视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
JavaScriptDOM事件初探的图文代码详细介绍
2020-11-27 20:24:29 责编:小采
文档

事件对象 event

在触发 DOM 上的某个事件时,会产生一个事件对象 event,这个对象中包含着所有与该事件有关的信息。

event 对象只存在于事件处理程序执行期间,一旦执行完毕,立即被销毁。

<p>
 <a id="test" href="http://baidu.com">点我点我,我是链接</a>
</p>
/* 下列 event 对象的属性和方法都是只读的 */
var link = document.getElementById("test");
link.onclick = function(event){
 // 判断当前事件是否会向 DOM 树上层元素冒泡
 console.log(event.bubbles);

 // 判断是否可以取消事件的默认行为
 console.log(event.cancelable);
 // 使用该方法可以取消事件的默认行为(使用前提是 cancelable 属性的值为 true)
 event.preventDefault();
 // 判断是否已经调用了 preventDefault() 方法(DOM3级事件新增)
 console.log(event.defaultPrevented);

 // 指向事件遍历 DOM 时,识别事件的当前目标对象
 console.log(event.currentTarget);
 // 指向触发事件的对象
 console.log(event.target);

 // 表示事件流当前处于哪一个阶段
 // 值为 1 表示在捕获阶段,值为 2 表示处于目标阶段,值为 3 表示在冒泡阶段
 console.log(event.eventPhase);

 // 返回一个字符串, 表示该事件对象的事件类型
 console.log(event.type);

 // 立即停止当前事件在 DOM 层次中的传播,即取消进一步的事件捕获或冒泡
 event.stopPropagation();
};

为了进一步说明 event.stopPropagation() 的运行效果,借用前面的代码,更改如下:

// 事件冒泡和事件捕获混合一下
var p = document.getElementById("test");
p.addEventListener("click",function(){
 console.log("i am p");
}, true);
document.body.addEventListener("click",function(){
 console.log("i am body");
}, false); // 改为在冒泡阶段调用事件处理程序
document.documentElement.addEventListener("click",function(){
 console.log("i am html");
 event.stopPropagation(); // 立即停止事件在 DOM 中的传播
}, true);
document.addEventListener("click",function(){
 console.log("i am document");
}, true);
window.addEventListener("click",function(){
 console.log("i am window");
}, false); // 改为在冒泡阶段调用事件处理程序
点击p,控制端会打印如下:
i am document
i am html

看到了吧,后面元素的事件就不会被激发了。

事件类型

UI 事件

UI 事件指的是简单的用户界面事件

load 事件:当页面所有资源(比如图像、css文件、js文件等资源)完全加载完毕后,就会触发 window 上面的 load 事件。

当然,我们也可以单独为某个元素设置 load 事件,比如为一个图片绑定这个事件,就可以检测这个图片是否加载完毕了。

<img id="myImg" src="1.jpg" />
var img = document.getElementById("myImg");
img.onload = function(){
 alert("Image loaded!");
};

scroll 事件:在文档被滚动期间,重复触发该事件。

window.onscroll = function(){
 console.log("Scroll!");
};

焦点事件

焦点事件会在页面元素获得或失去焦点时触发。

注意:默认情况下,只有部分 html 元素能获得鼠标焦点(如 input,a),很大一部分 html 元素是不能获得鼠标焦点的(如 p,img),这些能够获得鼠标焦点的元素就是 focusable 元素。

不过,可以通过为这些默认没有焦点事件的元素添加一个 tabindex 属性,从而使它可以支持焦点事件。

  • document.activeElement:返回当前页面中获得焦点的元素,如果没有某个元素获得焦点,则该属性的值为当前页面中的元素

  • document.hasFocus():判断当前文档或者当前文档的子节点是否获得了焦点

  • HTMLElement.focus():使得指定的元素获得焦点(前提是这个元素是一个可以获得焦点的元素)

  • HTMLElement.blur():移除当前元素获得的焦点

  • 上面是一些 HTML5 中添加的焦点管理 API。下面说焦点事件:

  • focus 事件:在元素获得焦点时触发,这个事件不会冒泡

  • blur 事件:在元素失去焦点时触发,这个事件不会冒泡

  • focusin 事件:在元素获得焦点时触发,与 focus 事件等价,但会冒泡

  • focusout 事件:在元素失去焦点时触发,与 blur 事件等价,但会冒泡

  • <img id="img" src="1.jpg" tabindex="1" />
    var img = document.getElementById("img");
    document.body.onscroll = function() {
     img.blur();
    };
    img.onfocus = function() {
     console.log("Img focused!");
    };
    img.onblur = function() {
     console.log("Img lose focus!");
    };
    img.onclick = function() {
     console.log(document.activeElement);
     console.log(document.hasFocus());
    };

    注意: focusin 和 focusout 事件,所有的 Firefox 版本都不支持,看这里。chrome 和 safari 中只有通过 addEventListener 方式绑定这两个事件才能正常使用,其他方式绑定都不行。

    说说focus /focusin /focusout /blur 事件(推荐)
    (WHATWG)Focus management APIs

    鼠标与滚轮事件

    DOM3 级事件中定义了9个鼠标事件。

    <body>
     <p id="test">
     <button>按钮</button>
     </p>
    </body>
    // css
    p {
     width: 300px;
     height: 300px;
     margin: 50px auto;
     border: 1px solid #aaa;
     }

    mouseover 事件:鼠标指针首次进入一个元素边界之内时触发,会冒泡

    mouseout 事件:鼠标指针移出这个元素边界时触发,会冒泡

    var test = document.getElementById("test");
    test.onmouseover = function(event){
     event.target.style.border = "3px solid #666";
    };
    test.onmouseout = function(event){
     event.target.style.border = "none";
    };

    mouseenter 事件:鼠标指针首次移动到元素范围之内时触发,不冒泡

    mouseleave 事件:鼠标指针移动到元素范围之外时触发,不冒泡

    var test = document.getElementById("test");
    test.onmouseenter = function(event){
     event.target.style.border = "10px solid #666";
    };
    test.onmouseleave = function(event){
     event.target.style.border = "none";
    };

    mousemove 事件:当鼠标在元素内部移动时重复触发,会冒泡

    // 这里写一个鼠标在 body 内移动时,背景颜色随机变化的脚本
    document.body.onmousemove = function(){
     var r = Math.floor(Math.random() * 256)
     g = Math.floor(Math.random() * 256)
     b = Math.floor(Math.random() * 256);
     document.body.style.background = "rgb("+r+","+g+","+b+")";
    };

    mousedown 事件:用户通过按下任意鼠标按钮时触发

    mouseup 事件:用户释放鼠标按钮时触发

    click 事件:用户单击鼠标左键时或按下回车键时触发

    dblclick 事件:用户双击鼠标左键时触发

    var body = document.body;
    body.onmousedown = function(){
     console.log("Mouse down!");
    };
    body.onmouseup = function(){
     console.log("Mouse up!");
    };
    body.onclick = function(){
     console.log("One click!");
    };
    body.ondblclick = function(){
     console.log("Double click!");
    };
    // 双击 body,控制端打印:
    Mouse down!
    Mouse up!
    One click!
    Mouse down!
    Mouse up!
    One click!
    Double click!

    只有在同一个元素上相继触发 mousedown 和 mouseup 事件,才会触发 click 事件,缺一不可。类似地,只有连续触发两次 click 事件,才会触发 dblclick 事件。

    获取点击坐标

  • clientX 和 clientY:鼠标指针在视口中的坐标

  • pageX 和 pageY:鼠标指针在页面中的坐标

  • screenX 和 screenY:鼠标指针在屏幕中的坐标

  • 在页面没有滚动的情况下,pageX 和 pageY 的值与 clientX 和 clientY 的值相等。

    document.body.onclick = function() {
     console.log("Client: " + "(" + event.clientX + "," + event.clientY + ")");
     console.log("Page: " + "(" + event.pageX + "," + event.pageY + ")");
     console.log("Screen: " + "(" + event.screenX + "," + event.screenY + ")");
    };

    键盘与文本事件

  • keydown 事件:当用户按下任意键时触发,而且如果按住不放的话,会重复触发此事件

  • keypress 事件:当用户按下任意字符键时触发,而且如果按住不放的话,会重复触发此事件

  • keyup 事件:当用户释放键盘上的按键时触发

  • 在用户按下一个字符键并且立马释放这个按键的过程中,先触发 keydown 事件,再触发 keypress 事件,最后触发 keyup 事件。

    window.onkeydown = function() {
     console.log("on key down");
    };
    window.onkeyup = function() {
     if (event.keyCode === 65) {
     console.log(event.key);
     }
     console.log("one key up");
    };
    window.onkeypress = function() {
     console.log("one key press");
    };

    为了知道自己按下的是哪个按键,可以使用 event.which 来获得你按下按键的键码(比如字母 A 的键码为 65)。也可以通过键码属性(event.keyCode)来对特定的按键来进行响应。键码参考表

    发生 keypress 事件时,会存在一个 charCode 属性,返回这个按键代表字符的 ASCII 编码。ASCII table

    event.which 返回一个 keyCode 或 charCode 值,详情看下面代码

    String.fromCharCode() 静态方法可以将 event.which 转化为相应的字符。

    // 请自行粘贴复制于浏览器控制端测试
    // 分别输入 a 和 A
    // A和a 的 ASCII码分别为65,97
    window.onkeydown = function(){
     if(event.keyCode === 65){
     console.log("(keydown keyCode)You press 'a' or 'A'!");
     }
     if(event.charCode === 65){
     console.log("(keydown charCode)You press 'A'!");
     }
     console.log("keydown event.which = " + event.which);
     console.log("(keydown:)" + String.fromCharCode(event.which));
    };
    window.onkeypress = function(){
     if(event.keyCode === 65){
     console.log("(keypress keyCode)You press 'A'!");
     }
     if(event.charCode === 65){
     console.log("(keypress charCode)You press 'A',not 'a'!");
     }
     console.log("keypress event.which = " + event.which);
     console.log("(keypress:)" + String.fromCharCode(event.which));
    };

    在 DOM3 级事件中,做了一些变化,不再推荐使用 keyCode、charCode、which 属性,而是出现了两个新属性:keychar,用来替代 keyCodecharCode 属性。

    但是不建议使用 key、char 属性,因为有一部分浏览器对他支持的不是很好。点这里

    参考:JavaScript 事件——“事件类型”中“键盘与文本事件”的注意要点

    变动事件

    变动事件是在 DOM 结构发生变化时触发

    在 DOM2 中定义了多个变动事件,但是在 DOM3 中又废除了一些,在这里先简单提一下有这个东西,以后用到再作补充。

    HTML5 事件

    contextmenu 事件:单击鼠标右键,会触发这个事件并调出页面的上下文菜单。这个事件是鼠标事件的一种,并且支持冒泡。

    在上面的例子中,我们演示了利用 contextmenu 事件来设置自定义右键菜单,以及屏蔽右键菜单。

    然而,屏蔽右键菜单却难不倒高手,Greasy Fork 上面有一个脚本(网页解除),专门来打破对右键菜单有的页面。

    beforeunload 事件:当浏览器窗口,文档或其资源将要卸载时或者刷新页面时,会触发这个事件【MDN】

    下面有几点需要注意一下:

    1. 如果处理函数为 Event 对象的 returnValue 属性赋值非空字符串,浏览器会弹出一个对话框,来询问用户是否确定要离开当前页面。没有赋值时,该事件不做任何响应。

    2. 从2011年5月25号开始,HTML5规范指出在此事件处理函数中,对于window.alert(), window.confirm(), 和 window.prompt() 的调用会被忽略。

    3. 旧版本的浏览器可能会在提示框里显示返回的信息,但是新版本浏览器都默认采用浏览器内设的提示信息。

    // 复制粘贴于浏览器控制端,然后关闭页面,会出现提示框
    window.addEventListener("beforeunload", function() {
     var message = "你真的要离开吗?";
     event.returnValue = message;
     return message;
    }, false);

    DOMContentLoaded 事件:在页面文档形成完整的 DOM 树时触发,不理会图像、js文件、css文件等资源是否加载完毕

    这个事件可以为 document 或 window 绑定,但实际目标是 document。这个事件会冒泡。

    注意:这个事件与 load 事件是不一样的,正常情况下,会早于 load 事件被触发。

    感觉篇幅太长了,事件委托、移动设备中的事件、事件对内存性能的影响等内容将在以后逐渐写出。

    下载本文
    显示全文
    专题