10_js 事件

如何绑定事件
  1. ele.onxxx = function (event) {}
    兼容性很好,但是一个元素只能绑定一个处理程序
    基本等同于写在HTML行间上
  2. obj.addEventListener(type, fn, false);
    IE9以下不兼容,可以为一个事件绑定多个处理程序
  3. obj.attachEvent(‘on’ + type, fn);
    IE独有,一个事件同样可以绑定多个处理程序

addEventListener的用法

    <div style="width:100px;height:100px;background-color: red;position:absolute;left:0;top:0;"></div>
    <script>
        // 句柄
        var div = document.getElementsByTagName('div')[0];
        div.addEventListener('click', function () {
            console.log('a');
        }, false);
        div.addEventListener('click', function () {
            console.log('b');
        }, false);
        div.addEventListener('click', test, false);
        div.addEventListener('click', test, false);
        div.addEventListener('click', test, false);
        function test() {
            console.log('绑定过后只会执行一次test函数');
        	// 而attachEvent绑定相同的函数可以多次执行,但是只有IE才有attachEvent
        }
        // div.onclick = function () {
        //     console.log('兼容好');
        // }
    </script>

ul闭包问题

<!doctype html>
<html lang="en">
<head>
    <title>Document</title>
</head>
<body>
<ul>
    <li>a</li>
    <li>a</li>
    <li>a</li>
    <li>a</li>
</ul>
    <script>
        var liCol = document.getElementsByTagName('li'),
            len = liCol.length;
        for(var i = 0; i < len; i++) {
            (function(i){
                liCol[i].addEventListener('click', function () {console.log(i)}, false);
            }(i));
        }
    </script>
</body>
</html>
事件处理程序的运行环境
  1. ele.onxxx = function (event) {}
    程序this指向是dom元素本身
  2. obj.addEventListener(type, fn, false);
    程序this指向是dom元素本身
  3. obj.attachEvent(‘on’ + type, fn);
    程序this指向window
    IE独有的attachEvent中this指向window的解决办法
        <div style="width:100px;height:100px;background-color: red;"></div>
        <script>
            var div = document.getElementsByTagName('div')[0];
            // 因为IE独有的attachEvent它的this是指向window的,
            // 但是用起来的时候绝大部分都是想调用该元素,
            // 所以可以用下面这种形式来改变this指向
            div.attachEvent('onclick', function () {
                handle.call(div);
            });
            function handle() {
    
            }
        </script>
    

封装兼容性的 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;
            }
        }
解除事件处理程序
  • ele.onclick = false/‘’/null;
  • ele.removeEventListener(type, fn, false);
  • ele.detachEvent(‘on’ + type, fn);
  • 注:若绑定匿名函数,则无法解除

只会生效一次的点击方法

<div style="width:100px;height:100px;background-color: red;"></div>
    <script>
        var div = document.getElementsByTagName('div')[0];
        div.onclick = function () {
            console.log('a');
            this.onclick = null;
        }
    </script>
事件处理模型 — 事件冒泡、捕获
  • 事件冒泡

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

    • 结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自底向上)
    • IE没有捕获事件
  • 触发顺序,先捕获,后冒泡

  • focus, blur, change, submit, reset, select 等事件不冒泡
    在这里插入图片描述

事件冒泡demo(看控制台)
为什么说非视觉呢,你把注释的加上就明白了
如果想实现事件捕获的话,把addEventListener中的false都改成true即可

<!doctype html>
<html lang="en">
<head>
    <title>Document</title>
    <style>
        .wrapper{
            width: 300px;
            height: 300px;
            background-color: red;
        }
        .content{
            width: 200px;
            height: 200px;
            background-color: green;
            /*margin-left: 300px;*/
        }
        .box{
            width: 100px;
            height: 100px;
            background-color: orange;
            /*margin-left: 200px;*/
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <div class="content">
            <div class="box"></div>
        </div>
    </div>
    <script>
        var wrapper = document.getElementsByClassName('wrapper')[0];
        var content = document.getElementsByClassName('content')[0];
        var box = document.getElementsByClassName('box')[0];

        wrapper.addEventListener('click', function () {
            console.log('wrapper');
        }, false);
        content.addEventListener('click', function () {
            console.log('content');
        }, false);
        box.addEventListener('click', function () {
            console.log('box');
        }, false);
    </script>
</body>
</html>

取消冒泡和阻止默认事件
  • 取消冒泡:
    • W3C标准 event.stopPropagation();但不支持ie9以下版本
    • IE独有event.cancelBubble = true;(谷歌也实现了)
        <!doctype html>
        <html lang="en">
        <head>
            <title>Document</title>
            <style>
                .wrapper{
                    width: 300px;
                    height: 300px;
                    background-color: red;
                }
            </style>
        </head>
        <body>
            <div class="wrapper"></div>
            <script>
                document.onclick = function () {
                    console.log('this is document')
                }
                var div = document.getElementsByClassName('wrapper')[0];
        
                div.onclick = function (e) {
                    // 取消冒泡时间
                    // e.stopPropagation();
                    e.cancelBubble = true;
                    this.style.background = "green";
                }
            </script>
        </body>
        </html>
      
    • 封装取消冒泡的函数 stopBubble(event)
      function stopBubble(event) {
        if(event.stopPropagation) {
        	event.stopPropagation();
        } else {
        	event.cancelBubble = true;
        }
      
    }
    ```
  • 阻止默认事件:
    • 默认事件 — 表单提交,a标签跳转,右键菜单等
    • 1.return false; 以对象属性的方式注册的事件才生效
      例子:右键页面不会出现菜单
      document.oncontextmenu = function (){
       	return false;
       }
      
    • 2.event.preventDefault(); W3C标准,IE9以下不兼容
      document.oncontextmenu = function (e){
         e.preventDefault();
      }
      
    • 3.event.returnValue = false; 兼容IE 封装阻止默认事件的函数 cancelHandler(event);
      document.oncontextmenu = function (e){
         e.returnValue = false;
      }
      

封装阻止默认事件的函数 cancelHandler(event);

function cancelHander(event){
	if(event.preventDefault){
		event.preventDefault();
	} else {
		event.returnValue = false;
	}
}

取消a标签的默认事件
void()相当于函数中return false;

<a href="javascript:void(false)">demo</a>
事件对象
  • event || window.event 用于IE
  • 事件源对象:
    • event.target 火狐只有这个
    • event.srcElement le只有这个
    • 这两chrome都有
  • 兼容性写法
<!doctype html>
<html lang="en">
<head>
    <title>Document</title>
</head>
<body>
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
</ul>
    <script>
        var ul = document.getElementsByTagName('ul')[0];
        ul.onclick = function (e) {
            var event = e || window.event;//兼容event
            var target = event.target || event.srcElement;//兼容事件源对象
            console.log(target.innerText);
        }
    </script>
</body>
</html>
事件委托
  • 利用事件冒泡,和事件源对象进行处理
  • 有点:
    • 1.性能不需要循环所有的元素一个个绑定事件
    • 2.灵活当有新的子元素时不需要重新绑定事件
事件分类
鼠标事件
  • click、mousedown、mousemove、 mouseup、contextmenu、mouseover、mouseout、mouseenter、mouseleave
  • 用button来区分鼠标的按键,0/1/2 (按下左键为0,滚动轮为1,右键为2)
  • DOM3标准规定:click事件只能监听左键,只能通过mousedown和mouseup来判断鼠标键
  • 如何解决mousedown和click的冲突
          var firstTime = 0;
          var lastTime = 0;
          var key = false;
          // 鼠标按下时
          document.onmousedown = function () {
              firstTime = new Date().getTime();
          }
          // 鼠标抬起时
          document.onmouseup = function () {
              lastTime = new Date().getTime();
              // 时间小于300ms则触发点击事件
              if(lastTime - firstTime < 300) {
                  key = true;
              }
          }
          document.onclick = function () {
              if(key) {
                  console.log('click');
                  key = false;
              }
          }
    
键盘事件
  • keydown keyup keypress
  • keydown > keypress > keyup
  • keydown 和 keypress 的区别
    • keydown 可以响应任意键盘按键(返回大小写区分不了),keypress只可以响应字符类键盘按键
    • keypress返回ASCII码,可以转换成相应字符
事件分类
  • 文本操作事件
  • input, focus, blur, change
    <!doctype html>
    <html lang="en">
    <head>
        <title>Document</title>
        <style>
            input{
                border:1px solid #01f;
            }
        </style>
    </head>
    <body>
        <input type="text" value="请输入用户名" style="color:#999"
               onfocus="if(this.value=='请输入用户名'){this.value='';this.style.color='#424242'}"
               onblur="if(this.value==''){this.value='请输入用户名';this.style.color='#999'}">
        <script type="text/javascript">
            var input = document.getElementsByTagName('input')[0];
            input.oninput = function (e) {
                console.log(this.value);
            }
        </script>
    </body>
    </html>
    
  • 窗体操作类(window上的事件)
  • scroll load
发布了56 篇原创文章 · 获赞 20 · 访问量 7387

猜你喜欢

转载自blog.csdn.net/qq_36826618/article/details/103176693