Oct1a

Javascript 事件

image

0x1 如何绑定事件

ele.onxxx = function(event){}

兼容性很好,但是一个元素的同一事件上只能绑定一个处理程序

基本等同于写在HTML行间上(

obj.addEventListener(type, fn, false);

IE9以下不兼容,可以为一个事件绑定多个处理程序

obj.attachEvent(on+type, fn)

IE独有,一个事件同样可以绑定多个处理程序

0x2 如何处理事件

ele.onxxx = function(event){}

程序this指向是Dom元素本身

obj.addEventListener(type, fn, false)

程序this指向是Dom元素本身

obj.attachEvent(on+type, fn)

程序this指向window

0x3 解除事件处理程序

若绑定匿名函数,则无法解除

  • ele.onclick = false/‘’/null;
  • ele.removeEventListener(type, fn false)
  • ele.detachEvent(on+type,fn)

0x4 事件冒泡、捕获

  • 事件冒泡

    结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素。(自底向上)

  • 事件捕获

    结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自顶向下)

    IE没有捕获事件

  • 触发顺序

    • 捕获
    • 冒泡
  • 不冒泡事件

    • focus
    • blur
    • change
    • submit
    • reset
    • select

0x5 取消冒泡和阻止默认事件

  • 取消冒泡:

    • event.stopPropagation();

      W3C标准,但不支持ie9以下版本

    • event.cancelBubble = true;

      IE独有

  • 阻止默认事件:

    • 默认事件—表单提交,a标签跳转,右键菜单等
    • return false; 以对象属性的方式注册的事件才生效
    • event.preventDefault; W3C标准,IE9以下不兼容
    • event.returnValue = false; 兼容IE

0x6 事件对象

  • event || window.event 用于IE

  • 事件源对象

    • event.target 火狐只有这个
    • event.srcElement IE只有这个
    • 这两个chrome都有
  • 兼容性写法

    event.target || event.srcElement

0x7 事件委托

利用事件冒泡,和事件源对象进行处理

  • 优点
    1. 性能 不需要循环所有的元素一个个绑定事件
    2. 灵活 当有新的子元素时不需要重新绑定事件

0x8 事件分类

  • 鼠标事件

    • click、mousedown、mousemove、mouseup、contextmenu、mouseover、mouseout、mouseenter、mouseleave

    DOM3标准规定:click事件只能监听左键,

    只能通过mousedownmoseup来判断鼠标键(button:0/1/2)

    • div.setCapture() 鼠标捕获 / div.releaseCapture() 释放

      这两个方法只有IE通用

  • 键盘事件

    • keydown > keypress > keyup
    • keydown和keypress的区别
      • keydown可以响应任意键盘按键
      • keypress只可响应字符类键盘按键
  • 文本操作事件

    • oninput 内容变换将触发
    • onfocus 获得焦点触发
    • onblur 失去焦点触发
    • onchange 内容变化并失去焦点触发
  • 窗体操作事件

    • scroll 滚动条滚动触发
    • load 网页全部载入后触发

0x0 面试题

  1. 使用原生js,addEventListener,给每个li元素绑定一个click事件,点击会输出他们的顺序
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
    <script>
        var li = document.getElementsByTagName('li');
        for(var i=0;i<li.length;i++){
            (function(i){
                li[i].addEventListener('click',function(){
                    console.log(i);
                },false)
            }(i))
        }
    </script>
  1. 封装兼容性的addEvent(elem, type, handle);方法
    function addEvent(elem, type, handle){
            if (elem.addEventListener) {
                elem.addEventListener(type,handle,false);
            }else if(elem.attachEvent){
                elem.attachEvent('on'+type,function(){
                    handle.call(elem)
                });
            }else{
                elem['on'+type] = handle
            }
        }
  1. 封装取消冒泡的函数 stopBubble(event)
    function stopBubble(event){
            if (event.stopPropagation){
                event.stopPropagation()
            }else{
                event.cancelBubble = true
            }
        }
  1. 封装阻止默认事件的函数cancelHandler(event)
    function cancelHandler(event){
            if (event.preventDefault){
                event.preventDefault()
            }else{
                event.returnValue = false
            }
        }
  1. 使用事件委托来绑定输出每个li文本
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
    <script>
        var ul = document.getElementsByTagName('ul')[0];
        ul.onclick = function(e){
            var event = e || window.event;
            var target = event.target || event.srcElement;
            console.log(target.innerText)
        }
    </script>

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。