18

我会在纯 Javascript 中模拟 jQuery.on( events , selector , data) 方法的主要功能。

例如

$(document).on('click','.button',function() {
   console.log("jquery onclick"); 
});

我认为制作这样的东西就足够了

document.addEventListener('click',function(e) {
    if(e.target.className == 'button2') {
         console.log("It works");   
    }
});

但是,当我有这个 html 结构时:

<button class="button2">Hello <span>World</span></button>

span当元素e.target上触发 click 事件时,我的脚本不起作用,因为span. (对于这个问题,我忽略了具有多个类的元素的复杂性以及跨浏览器兼容性)

jQuery的源代码读起来并不简单,我也不明白它是如何工作的(因为 jQuery 中的第一段代码适用于我的 html 结构)。

我需要这个方法,因为我的 html 是动态的,并且这个类的按钮被创建、删除和重新创建了很多次。我不想每次都添加听众。

如果可能的话,我会避免包含 jquery 库。

那么,我能做到吗?

这里是用于测试的jsFiddle

4

4 回答 4

16

2017 年更新当前的 DOM 标准,例如closest意味着现在要容易得多。

const addEventForChild = function(parent, eventName, childSelector, cb){      
  parent.addEventListener(eventName, function(event){
    const clickedElement = event.target,
    matchingChild = clickedElement.closest(childSelector)
    if (matchingChild) cb(matchingChild)
  })
};

要使用它:

addEventForChild(parent, 'click', '.child', function(childElement){
  console.log('Woo click!', childElement)
})

这是一个jsfiddle

于 2017-04-28T14:04:16.980 回答
11

这实际上非常简单。你在正确的轨道上,但它并不完全在那里。

这是我使用的功能:

window.addEvent = function(elem,type,callback) {
    var evt = function(e) {
        e = e || window.event;
        return callback.call(elem,e);
    }, cb = function(e) {return evt(e);};
    if( elem.addEventListener) {
        elem.addEventListener(type,cb,false);
    }
    else if( elem.attachEvent) {
        elem.attachEvent("on"+type,cb);
    }
    return elem;
};
window.findParent = function(child,filter,root) {
    do {
        if( filter(child)) return child;
        if( root && child == root) return false;
    } while(child = child.parentNode);
    return false;
};
window.hasClass = function(elem,cls) {
    if( !('className' in elem)) return;
    return !!elem.className.match(new RegExp("\\b"+cls+"\\b"));
};

window.findParent是整个事情的核心,当我向您展示如何附加所需的on侦听器时,您可以看到:

window.addEvent(document.body,"click",function(e) {
    var s = window.findParent(e.srcElement || e.target,function(elm) {
        return window.hasClass(elm,"button");
    },this);
    if( s) {
        console.log("It works!");
    }
});
于 2013-02-03T20:43:52.477 回答
0

简单而简短的代码:

function onEvt(type, callback) {
    if (document.attachEvent) {
        document.attachEvent("on" + type, function (e) {
            callback(e.target);
        });
    } else {
        document.addEventListener(type, function (e) {
            callback(e.target);
        }, false);
    }
}

像这样调用函数:

onEvt('click', function(elem){ // click, mouseover etc...
    // for class
    if(elem.classList.contains('classname')){
        // do stuff
    }
    // for attribute
    if(elem.hasAttribute('target')){
        // do stuff
    }
});
于 2016-12-08T18:24:36.280 回答
-1

您可以通过链接在 github 上使用函数 Marchy8或通过执行以下操作来扩展它。

首先创建 $() 选择器函数:

function $(selector) {
    return selector;
}

HTMLElement = typeof (HTMLElement) != "undefined" ? HTMLElement : Element;
String.prototype.on = function(type, callback){
    var selector = this;
    document.body.addEventListener(type, function (event) {
        if (event.target.matches(selector)) {
            callback.call(event.target);
        }
    });
}

$(".test").on("click", function(e) {
    console.log(this.innerHTML);
    this.style.color = "red";
});
<div class="test">Click Here</div>
<div class="test">Click Here-1</div>

于 2021-06-09T11:39:26.257 回答