案例 - 动态添加 li 元素添加事件
<button>添加</button>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
<script>
var oList = document.getElementsByTagName('ul')[0],
oLi = oList.getElementsByTagName('li'),
oBtn = document.getElementsByTagName("button")[0];
len = oLi.length;
oList.onclick = function(e) {
var e = e || window.event,
tar = e.target || e.srcElement;
console.log(tar.innerText);
}
oBtn.onclick = function() {
const li = document.createElement("li");
li.innerText = oLi.length + 1;
oList.appendChild(li);
}
</script>
- 在父级绑定事件,子级触发后冒泡到父级,在通过事件源对象即可操作子级
<button>添加</button>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
<script>
var oList = document.getElementsByTagName('ul')[0],
oLi = oList.getElementsByTagName('li'),
oBtn = document.getElementsByTagName("button")[0];
len = oLi.length;
oList.onclick = function(e) {
var e = e || window.event,
tar = e.target || e.srcElement;
console.log(tar);
}
</script>
- 通过 事件冒泡 获取 target
oUl.onclick = function(e){
var e = e || window.event,
tar = e.target || e.srcElement;
console.log(tar);
}
- 点击 li 打印对应下标,绑定事件到 li 元素上
for (var i = 0; i < len; i++) {
item = oLi[i];
(function (i) {
item.onclick = function () {
console.log(i);
};
})(i);
}
- 通过事件代理获取下标
oList.onclick = function(e) {
var e = e || window.event,
tar = e.target || e.srcElement; // target 才是真正点击的 li 元素
for (var i = 0; i < len; i++) {
item = oLi[i];
if (tar === item) {
console.log(i);
}
}
}
- 通过 indexOf 获取,比上面方式好
oList.onclick = function(e) {
var e = e || window.event,
tar = e.target || e.srcElement
var index = Array.prototype.indexOf.call(oLi, tar);
console.log(index);
}
🌈 手写事件委托
// 原生JS
var ul = document.querySelector('ul');
function listen(element, eventType, targetElement, fn) {
element.addEventListener(eventType, function(e) {
// 先拿到当前事件的直接触发对象
var curTarget = e.target;
// 看它是不是使用者监听的目标对象类型
// 一旦发现不是,就执行循环
while(!curTarget.matches(targetElement)) {
// 先看看当前对象是不是和父元素相同
// 相同则把当前对象置为空,且不执行回调
if (curTarget === element) {
curTarget = null;
break;
}
// 不相同则把当前对象设置成自己的父对象
curTarget = curTarget.parentNode;
}
// 是,则先看当前对象有没有值,有值则执行回调函数
curTarget && fn(e, curTarget);
});
};
listen(ul, 'click', 'li', function(event, el) {
console.log(event, el);
});
// jquery
$("ul").on("click", "li", function(e) {
console.log($(e.target).html());
});
// 这个on事件是绑定在ul上面的,li是目标元素,
// on事件内部是通过e.target来判断点击元素是不是li的