JavaScript 入门(05)事件处理

一、event对象

  • 用来获取事件的详细信息:鼠标位置,键盘键位
  • 事件对象的兼容性写法:var oEvent = ev || event
  • document的本质:可以看作一个最高级节点,全局事件加在 document 上
var handleClick = function (event) {
    console.log('offsetX:'+event.offsetX);
    console.log('offsetY:'+event.offsetY);
    console.log('pageX:'+event.pageX);
    console.log('pageY:'+event.pageY);
    console.log('screenX:'+event.screenX);
    console.log('screenY:'+event.screenY);
    console.log('X:'+event.x);
    console.log('Y:'+event.y);
    console.log('target:'+event.target);
    console.log('timestamp:'+event.timeStamp);
    console.log('type:'+event.type);
    console.log(event);
};
var but1 = document.querySelector('#but1');
but1.addEventListener('click',handleClick);
  • 一些相关坐标位置的示意图
    在这里插入图片描述

二、事件处理

1、默认行为

  • 事件的默认行为就是浏览器帮我们实现的对一些事件的默认的响应,比如鼠标右键单击的菜单弹出、a标签和form表单的默认跳转
  • 默认行为可以用事件对象的 preventDefault()来阻止,也可以直接在事件对应的响应方法里直接return false,后面的方法更加常用

2、事件传播

  • 事件的冒泡和捕获都是属于事件的传播行为

冒泡

  • 冒泡的行为是子元素发生某个事件,父元素的相同事件也会被触发,这种行为是从内往外的,就和冒泡一样
  • 基本上大部分的浏览器默认的事件的传播行为都是冒泡,阻止事件的冒泡:event.cancelBubble = true

捕获

  • 事件捕获和冒泡相反,事件传播的方向是从外向内的,注册了相同事件并且使用了捕获的父元素依照从外往内的顺序会被依次激发
  • 事件捕获的实现要用到 addEventListener('click',func,true)这里的第三个参数设置为true就是使用捕获了,不设置的话默认还是冒泡
  • 事件捕获只会针对设置了捕获的父元素,没有设置的父元素还是冒泡行为
  • 捕获行为和冒泡行为同时存在的话实测先响应捕获再响应冒泡
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        div {
            font-size: 50px;
        }

        #d1 {
            width: 500px;
            height: 500px;
            background: red;
        }

        #d2 {
            width: 400px;
            height: 400px;
            background: blue;
        }

        #d3 {
            width: 300px;
            height: 300px;
            background: yellow;
        }

        #d4 {
            width: 200px;
            height: 200px;
            background: grey;
        }

    </style>
</head>
<body>

<div id="d1">1
    <div id="d2">2
        <div id="d3">3
            <div id="d4">4</div>
        </div>
    </div>
</div>

<script>
    window.onload = function () {
        var d1 = document.getElementById('d1');
        var d2 = document.getElementById('d2');
        var d3 = document.getElementById('d3');
        var d4 = document.getElementById('d4');
        // d1.onclick = function () {
        //     console.log('d1-click')
        // };
        d2.onclick = function () {
            console.log('d2-click')
        };
        // d3.onclick = function () {
        //     console.log('d3-click')
        // };
        d4.onclick = function () {
            console.log('d4-click')
        };

        d1.addEventListener('click', function () {
            console.log('d1-click');
        }, true);

        // d2.addEventListener('click',function () {
        //     console.log('d2-click');
        // },true);

        d3.addEventListener('click', function () {
            console.log('d3-click');
        }, true);

        // d4.addEventListener('click',function () {
        //     console.log('d4-click');
        // },true);
    }


</script>

</body>
</html>

3、事件绑定

  • 老方法(onclick等直接绑定)给元素绑定事件,会出现同一元素相同事件覆盖问题
  • 使用addEventListener进行事件的绑定就不会有这个问题, 甚至能给 window 对象绑定事件
function myAddEvent(obj, ev, fn)
{
    if(obj.attachEvent)
    {
        obj.attachEvent('on'+ev, fn);
    }
    else
    {
        obj.addEventListener(ev, fn, false);
    }
}

事件的解绑:IE(detachEvent);CHROME(removeEventListener);

4、事件委托

  • 问题:正常情况下,我们是没有办法给未来要动态添加的元素来注册事件的

事件委托的优点

  • 提高性能:每一个函数都会占用内存空间,只需添加一个事件处理程序代理所有事件,所占用的内存空间更少
  • 动态监听:使用事件委托可以自动绑定动态添加的元素,即新增的节点不需要主动添加也可以一样具有和其他元素一样的事件
<div>
   <ul id=ha>
      <li>默认</li>
   </ul>
</div>

<script>
var ha = document.getElementById("ha")
ha.onclick=function(ev){
var ev = ev || window.event;   
var target = ev.target||ev.srcElement;
   alert(target.innerHTML);
};
var li1 = document.createElement("li");
li1.innerText = "你好";
ha.appendChild(li1);
</script>

委托的原理

  • 委托的底层实际上是通过冒泡来实现的
  • 子元素发生事件(比如点击),子元素没有注册对应的处理行为的话,这个事件就会被传递到外层的元素,外层元素如果注册相应的事件处理行为的话,就会被触发,通过ev.target可以追踪到事件发生的源头,方便我们进一步处理
  • 这里更正以下前面关于冒泡和捕获的说法:无论元素有没有注册相应的事件处理行为,事件都是会一层一层传递的,只有注册了事件处理行为的元素会被触发而已

三、鼠标&键盘事件

1、鼠标事件

click:单击事件。
dblclick:双击事件。
mousedown:按下鼠标键时触发。
mouseup:释放按下的鼠标键时触发。
mousemove:鼠标移动事件。
mouseover:移入事件。
mouseout:移出事件。
mouseenter:移入事件。
mouseleave:移出事件。
contextmenu:右键事件。

鼠标位置 clientXclientY 实际是可视区域的坐标,如果要获取相对与 document 的绝对坐标,需要和 scrolltop 等配合使用,封装相应的方法;

鼠标的移入移出事件

  • 只要鼠标指针移入(或移出)事件所绑定的元素或其子元素,都会触发mouseover、mouseout事件
  • 只有鼠标指针移入(或移出)事件所绑定的元素时,才会触发mouseenter、mouseleave事件

2、键盘事件

  • keycode :可以用来判断键盘的按键
  • 特殊的按键:ctrlkey、altkey、shiftkey
  • event.ctrlKey的值是一个 bool 值
<p>Click anywhere to test the <code>ctrlKey</code> property.</p>
<p id="log"></p>
let log = document.querySelector('#log');
document.addEventListener('click', logKey);

function logKey(e) {
  log.textContent = `The ctrl key is pressed: ${e.ctrlKey}`;
}
发布了153 篇原创文章 · 获赞 51 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/stanwuc/article/details/103855178
今日推荐