欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

手写事件代理函数 (Delegated function)

程序员文章站 2022-05-08 08:14:07
‘手写 ’ 这个词 ,面试是不是听过无数遍呢 ! 今天我们来手写一个这样的事件委托函数 =》 function( parent, selector, type , handle) {} 你需要传递的参数分别是: parent: 事件绑定的父级 selector: 选择器, type: 事件类型 ha ......

‘手写 ’ 这个词 ,面试是不是听过无数遍呢 !

今天我们来手写一个这样的事件委托函数 =》

function( parent, selector, type ,  handle)  {}

你需要传递的参数分别是:

parent: 事件绑定的父级

selector: 选择器,

type:  事件类型

handle: 事件处理函数

 

写之前 先了解一下事件委托的概念:     

    它是通过事件冒泡机制,

       即子元素上触发的事件会冒泡到父级上, 即父级也会触发该类型的事件,

       通过父级触发的事件拿到事件源对象e.target  就可以 知道 真正触发事件的元素是什么。

 

举个例子, 一个ul 下面有 1000 个  li   , 我们 要给  li  绑定  点击事件 , 如果给每个li都绑定一个

点击事件  会  大量占用 内存   , 不利于性能优化, 这种情况下 我们 只需要在ul上绑定一个点击事件,

通过class 或者 id 来识别每个li ,  这样就大大减少了事件注册, 而且 再 有新增的li时 我们也无需再去注册点击事件

 

我们来写个小demo

html:

<ul id="parent">
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

css:

.active{
    background-color: green;
}

js:

const parent = document.getelementbyid('parent');
function changecolor() {
  if (this.classlist.contains('active')) {
  this.classlist.remove('active')
  } else {
  this.classlist.add('active');
  }
 } 

function delegate(parent, selector, type, handle) { }
delegate(parent, 'li', 'click',changecolor);

我们要实现点哪个li  , 哪个li就变成原谅色, 再次点击取消。并 做 浏览器的兼容

我们开始写 delegate函数:

function matchselector(target, selector) {
    if (selector.match(/^#/g)) { // 匹配以#开头的字符串
        return target.id === selector.slice(1); // 截取#后面的字符串
    }
    if (selector.match(/^\./g)) {  // . 要转义,匹配以点开头的字符转
        return target.classlist.contains(selector.slice(1))
    }
    return target.nodename.tolowercase() ===  selector; // 匹配标签
}
function delegate(parent, selector, type, handle) {
    if (parent.addeventlistener) {
        parent.addeventlistener(type, eventfn, false)
    } else {   // 兼容老ie
        parent.attachevent('on' + type, handle)
    }
    function eventfn(e) {
        const event = e || window.event;
        const target = event.target || event.srcelement;// 兼容老ie
        if (matchselector(target, selector)) {
            if (handle) {
                handle.call(target, e); // 让handle执行时的this指向target
            }
        }
    }
}

 

 效果:手写事件代理函数 (Delegated function)