【前端】事件代理(事件委托)

事件代理(事件委托)

在面试时遇到了事件代理的问题,当时有点懵没有反应过来事件代理是什么东西,幸好面试官小姐姐提示我事件代理其实就是事件委托,我才恍然大悟。

首先我们在JS高级程序设计这本书中找一下事件委托的概念:

事件委托利用了事件冒泡,只指定一个事 件处理程序,就可以管理某一类型的所有事件。

简单来说,事件委托即事件代理,就是把多个节点的事件根据事件冒泡的原理绑定到其父节点上,以减少不必要的性能损耗。

代码举例,假如我们需要实现单击单元格并使其变色的功能,
方法一:

// 通过循环为每一个td都绑定一个onclick事件

<html>
<head>
    <title>testtitle>
head>
<body>
    <table id="tableTest" style="border: 1px solid #000">
        <tr id="trTest">
            <td>itemtd>
            <td>itemtd>
            <td>itemtd>
            <td>itemtd>
            <td>itemtd>
        tr>
        

    table>
    <script type="text/javascript">
        window.onload = function () {
            var oTr = document.getElementById("trTest");
            var oTd = oTr.getElementsByTagName("td");
            //alert(oTd.length);
            for(let i = 0; i < oTd.length; i++){
                
                oTd[i].onclick = function () {
                    //alert(i);
                    this.style.backgroundColor = 'yellow';
                }
            }
        }

    script>
body>
html>

通过循环为每一个td都绑定一个onclick事件固然可以,担当td数量很多的时候不免会造成一些性能问题,所以我们可以通过事件委托,将td的onclick事件通过事件冒泡的原理绑定到tr上,以减少不必要的性能浪费,所以我们来下面这个fang。
方法二:

// 将td事件绑定到tr

<html>
<head>
    <title>testtitle>
head>
<body>
    <table id="tableTest" style="border: 1px solid #000">
        <tr id="trTest">
            <td>itemtd>
            <td>itemtd>
            <td>itemtd>
            <td>itemtd>
            <td>itemtd>
        tr>
        

    table>
    <script type="text/javascript">

        window.onload = function () {
     
            var oTr = document.getElementById("trTest");
            oTr.onclick = function () {
                // 获取事件源
                var ev = window.event.srcElement;
                ev.style.backgroundColor = 'yellow';
            }

        }
    script>
body>
html>


昨天在字节跳动笔试时遇到一个这样的问题:

简述浏览器中事件代理的原理,并实现一个代理方法eventProxy,调用方法:eventProxy(el, className, callback),参数解释:

  • el:绑定事件的节点
  • className: 拥有该类名的子元素会触发事件
  • callback: 事件回调

事件代理的原理上文已讲到,即通过事件冒泡,将多个元素的事件绑定到一个元素上。
至于eventProxy的实现有点没搞懂,感觉可能是想要考察获取事件源吧?
以下是我理解的代码(不正确的可能性极大),求指正。

function eventProxy(el, className, callback) {
	// el:绑定事件的节点
	// className: 拥有该类名的子元素会触发事件
	// callback: 事件回调
	var oObj = window.event.srcElement; // 获取事件源

	if(oObj == el){

		// 获取oObj下的所有子元素 
		oClass = oObj.getElementByTagName('*');

		for(let i = 0; i < oClass.length; i++){

			// 如果子元素的类名为 className
			if(oClass[i].className == className)
				callback(oClass[i]);
		}
	}
}

你可能感兴趣的:(前端,事件委托,事件代理,事件源,冒泡)