+ -
当前位置:首页 → 问答吧 → 关于event delegation的补充

关于event delegation的补充

时间:2010-05-07

来源:互联网

好久没小贴士了
今天聊聊,js中的event delegation
这个我以前讲过,是一种触发事件的机制。
我在这里先在说一下(今天不是想谈论这个,是在这个上的提高)
比如有如下html代码
<ul id="aa"  style="float:left">
       <li><a href=”#”  >我是 1</a>
       <ul>
       <li><a href=”#”>我是 2</a></li>
       <li><a href=”#”>我是 3 </a></li>
       </ul></li>
       <li><a href=”#”>我是 4</a>
       <ul>
       <li><a href=”#”>我是 5</a></li>
       <li><a href=”#”>我是 6</a></li>
       <li><a href=”#”>我是 7</a></li>
       </ul></li>
</ul>
想为他的每个a添加一个onmouseover
传统的模式是得到所有的a,在每个赋值mouseover
但这是老黄历了,不及罗嗦又容易出现内从泄露
新的方式就是通过event机制中的冒泡,来实现

代码如下
复制内容到剪贴板
代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
    <title>Untitled</title>
</head>
<body>
<ul id="aa"  style="float:left">
    <li><a href=”#”  >我是 1</a>
    <ul>
    <li><a href=”#”>我是 2</a></li>
    <li><a href=”#”>我是 3 </a></li>
    </ul></li>
    <li><a href=”#”>我是 4</a>
    <ul>
    <li><a href=”#”>我是 5</a></li>
    <li><a href=”#”>我是 6</a></li>
    <li><a href=”#”>我是 7</a></li>
    </ul></li>
</ul>
<div style="float:right"id="console"></div>
</body>
</html>
<script>
    var con = document.getElementById('console'),
        aa = document.getElementById('aa');
    function test1(e){
        e = e||event;
        var t = e.target||e.srcElement;
        if(t.tagName=='A'){
            con.innerHTML += t.innerHTML + '<br/>'
        }
    }
    aa.onmouseover = test1;
</script>
代码中只为最外边的ul添加了一次事件,通过对event中的target也就是谁触发了,来为每个a做mouseover

实验一切ok

但现在需求变了,我想为每个a的focus,也就是通过键盘的tab来触发他的focus,而不是通过鼠标了,这时event   delegation 不好用了
   aa.onmouseover = aa.onfocus = test1;     //不好用了
用键盘触发focus,大家可以先在页面上点一下空白处,然后用tab键可以在每个a中切换
这时如果你写了每个a的focus时他是可以触发的,但用          event   delegation 就不行了
为什么的,原因很简单,就是像focus,blur他们是不冒泡的,不想mouseover/mouseout/click等等,
那event   delegation肯定就不好用了

但幸运的是可以用别的方式来代替

先说ie,ie为focus/blur这两个事件添加了两个可以冒泡的事件他们是focusin/blurin所以我们添加代码

aa.onmouseover = aa.onfocusin = test1;
除了ie呢,我们可以用捕获机制,其实在dom中事件机制是分为两个时期的,一种是 capture捕获时期,一种是冒泡时期(很不幸ie只支持冒泡)
大家要是用过addEventListener会发现他有3个属性,最后一个一般都是false,这个就是表示这个事件触发是不是支持捕获
好了代码再次改动一下
加入
if(aa.addEventListener){
              aa.addEventListener('focus',test1,true)//为真,让其支持捕获
       }
至此我们的代码改成了
复制内容到剪贴板
代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
    <title>Untitled</title>
</head>
<body>
<ul id="aa"  style="float:left">
    <li><a href=”#”  >我是 1</a>
    <ul>
    <li><a href=”#”>我是 2</a></li>
    <li><a href=”#”>我是 3 </a></li>
    </ul></li>
    <li><a href=”#”>我是 4</a>
    <ul>
    <li><a href=”#”>我是 5</a></li>
    <li><a href=”#”>我是 6</a></li>
    <li><a href=”#”>我是 7</a></li>
    </ul></li>
</ul>
<div style="float:right"id="console"></div>
</body>
</html>
<script>
    var con = document.getElementById('console'),
        aa = document.getElementById('aa');
    function test1(e){
        e = e||event;
        var t = e.target||e.srcElement;
        if(t.tagName=='A'){
            con.innerHTML += t.innerHTML + '<br/>'
        }
    }
    aa.onmouseover = aa.onfocusin = test1;
    if(aa.addEventListener){
        aa.addEventListener('focus',test1,true)
    }
</script>
好了,再在浏览器里试试,over显示了,点击页面按tab,发现也显示了

作者: campaignZH   发布时间: 2010-05-07

学习了
lz还能发个以前讲event delegation的链接看看

作者: jiangliuhuo   发布时间: 2010-05-07