js事件触发器fireEvent和dispatchEvent

1,537 阅读5分钟

click、mousedown、mouseup详解

onclick是在鼠标点击弹起之后触发的事件。

onmousedown 事件会在鼠标按键被按下时发生。

onMouseUp:在鼠标弹起的时候触发

注意:

<button onclick="showinfo()">肥肥</button>

点击目标区域,移动鼠标到除目标区域以外的位置松开鼠标,onclick事件不会触发。

<button onclick="showinfo()" onmousedown="mouseDown()">肥肥</button>

点击目标区域,移动鼠标到除目标区域以外的位置松开鼠标,onclick事件不会触发,只会触发onmousedown事件。

点击目标区域,在目标区域的位置松开鼠标,先触发onmousedown事件,再执行onclick事件。(当鼠标弹起的时候在目标区域上,才会触发onclick事件)

<button onclick="showinfo()" onmousedown="mouseDown()" onmouseup="mouseUp()">肥肥</button>

点击目标区域,移动鼠标到除目标区域以外的位置松开鼠标,触发onmousedown事件,onclick和onmouseup都不会触发

点击目标区域,在目标区域的位置松开鼠标,先执行onmousedown,然后执行onmouseup触发,最后执行onclick事件

<!DOCTYPE html>
<html lang="en">
<head>    
    <meta charset="UTF-8">    
    <title>click和mousedown、mouseup</title>
</head>
<body>
    <div id="data">    
        <button onclick="showinfo()" onmousedown="mouseDown()" onmouseup="mouseUp()">
            肥肥
        </button>
    </div><script type="text/javascript">
    function showinfo() {    
        console.log("这是一只肥肥");
    }
    function mouseDown() {    
        console.log("按下鼠标");
    }
    function mouseUp() {    
        console.log("松开鼠标");
    }
</script></body>
</html>

document.addEventListener的使用

document.addEventListener(event, function, useCapture)

event  事件名,注意不要使用“on”前缀,使用“click”代替“onclick”

useCapture  布尔值,

  • true - 事件句柄在捕获阶段执行,从外向里
  • false- 默认。事件句柄在冒泡阶段执行,从底向外

addEventListener里最后一个参数决定该事件的响应顺序;
如果为true事件执行顺序为 addEventListener ---- 标签的onclick事件 ---- document.onclick
如果为false事件的顺序为 标签的onclick事件 ---- document.onclick ---- addEventListener

使用案例:

1、可以在文档中添加许多事件,添加的事件不会覆盖已存在的事件。

该实例演示了如何在文档中添加两个点击事件:

document.addEventListener("click", myFunction);
document.addEventListener("click", someOtherFunction);

2、使用 removeEventListener() 方法移除通过 addEventListener() 方法添加的事件句柄:

// 向文档添加事件句柄
document.addEventListener("mousemove", myFunction);
// 移除文档的事件句柄
document.removeEventListener("mousemove", myFunction);

3、如果浏览器不支持 addEventListener() 方法, 你可以使用 attachEvent() 方法替代。

以下实例演示了跨浏览器的解决方法:

if (document.addEventListener) { //所有主流浏览器,除了 IE 8 及更早 IE版本
document.addEventListener("click", myFunction);
} else if (document.attachEvent) { // IE 8 及更早 IE 版本
document.attachEvent("onclick", myFunction);
}

<!DOCTYPE html>
<html lang="en">
<head>    
    <meta charset="UTF-8">    
    <title>dispatchEvent和fireEvent</title>
</head>
<body>
    <div id="test">肥肥</div>
<script type="text/javascript">    
    var test=document.getElementById('test');    
    document.addEventListener("click", function () {        
        alert("document");    
    }, true);    
    test.addEventListener('click', function () {        
        alert("test");    
    }, true)
</script>
</body>
</html>

设置事件句柄在捕获阶段执行,点击肥肥,先弹出document,再弹出test

<!DOCTYPE html>
<html lang="en">
<head>    
    <meta charset="UTF-8">    
    <title>dispatchEvent和fireEvent</title>
</head>
<body>
    <div id="test">肥肥</div>
<script type="text/javascript">    
    var test=document.getElementById('test');    
    document.addEventListener("click", function () {        
        alert("document");    
    }, false);    
    test.addEventListener('click', function () {        
        alert("test");    
    }, false)
</script>
</body>
</html>

设置事件句柄在捕获阶段执行,点击肥肥,先弹出test,再弹出document

createEvent,dispatchEvent,fireEvent详解

MDN解释如下:

与浏览器原生事件不同,原生事件是由DOM派发的,并通过event loop异步调用事件处理程序,而dispatchEvent()则是同步调用事件处理程序。在调用dispatchEvent()后,所有监听该事件的事件处理程序将在代码继续前执行并返回。

dispatchEvent()是create-init-dispatch过程的最后一步,用于将事件调度到实现的事件模型中。可以使用Event构造函数来创建事件。

使用方式如下:

// Create the event.
const event = document.createEvent('Event');

// Define that the event name is 'build'.
event.initEvent('build', true, true);

// Listen for the event.
elem.addEventListener('build', function (e) {
  // e.target matches elem
}, false);

// target can be any Element or other EventTarget.
elem.dispatchEvent(event);
// 调用document对象的 createEvent 方法得到一个event的对象实例。
var mouseEvent = document.createEvent("MouseEvents") 
// 事件类型,是否冒泡,是否阻止浏览器的默认行为
mouseEvent.initMouseEvent("mousedown", true, true) 
dom.addEventListener('mousedown', function(event) {
    console.log("00")
})
dom.dispatchEvent(mouseEvent)

createEvent()方法返回新创建的Event对象,支持一个参数,表示事件类型,具体见下表:

参数

事件接口

初始化方法

HTMLEvents

HTMLEvent

initEvent()

MouseEvents

MouseEvent

initMouseEvent()

UIEvents

UIEvent

initUIEvent()

发现一个现象,刷新浏览器会alert一个肥肥,并没有进行鼠标按下的操作

var kk = document.getElementById('kk');

// 调用document对象的 createEvent 方法得到一个event的对象实例。
var mouseEvent = document.createEvent("MouseEvents");
// 事件类型,是否冒泡,是否阻止浏览器的默认行为
mouseEvent.initMouseEvent("mousedown", true, true);
kk.addEventListener('mousedown', function(event) {    
    alert("肥肥")
})kk.dispatchEvent(mouseEvent);

参考MDN:

developer.mozilla.org/zh-CN/docs/…

从2011年5月25日起, HTML5 规范 声明:在该事件的处理函数中调用下列弹窗相关的方法时,可以忽略不执行,[window.showModalDialog()](https://developer.mozilla.org/zh-CN/docs/DOM/window.showModalDialog), [window.alert()](https://developer.mozilla.org/zh-CN/docs/DOM/window.alert), [window.confirm()](https://developer.mozilla.org/zh-CN/docs/DOM/window.confirm) [window.prompt()](https://developer.mozilla.org/zh-CN/docs/DOM/window.prompt).

需要指出的是,许多浏览器会忽略该事件并自动关闭页面无需用户的确认。火狐浏览器在配置页面about:config设有一个dom.disable_beforeunload的开关变量用于开启这个功能。

按F5报错,block alert 

window.addEventListener("beforeunload", function (e) {    
    alert("dddd");
    //不是所有浏览器都支持提示信息的修改    
var confirmationMessage = "请先保存您编辑的内容,否则您修改的信息会丢失。";    
e.returnValue = confirmationMessage;    
return confirmationMessage;
});

window.onload和document.ready 等页面加载时触发的事件及顺序

1、window.onload 

在文档装载完成后会触发 load 事件。此时,在文档中的所有对象都在DOM中,所有图片,脚本,链接以及子框都完成了装载。 

2、DOMContentLoadedDOMFrameContentLoaded (它们可以使用 EventTarget.addEventListener() 来处理 ) , 这些事件在页面DOM构建起来后就会触发,而不会等到其他的资源都装载完成。

3、document readystatechange

switch (document.readyState) {
  case "loading":
    // 表示文档还在加载中,即处于“正在加载”状态。
    break;
  case "interactive":
    // 文档已经结束了“正在加载”状态,DOM元素可以被访问。
    // 但是像图像,样式表和框架等资源依然还在加载。
    var span = document.createElement("span");
    span.textContent = "A <span> element.";
    document.body.appendChild(span);
    break;
  case "complete":
    // 页面所有内容都已被完全加载.
    let CSS_rule = document.styleSheets[0].cssRules[0].cssText;
    console.log(`The first CSS rule is: ${CSS_rule }`);
    break;
}

模拟 DOMContentLoaded 事件的 readystatechange// 模拟 DOMContentLoaded/ jquery ready
document.onreadystatechange = function () {
  if (document.readyState === "interactive") {
    initApplication();
  }
}模拟 load 事件的 readystatechange// 模拟 load 事件
document.onreadystatechange = function () {
  if (document.readyState === "complete") {
    initApplication();
  }
}
在 DOMContentLoaded 之前使用 readystatechange 作为事件处理程序以插入或修改DOMdocument.addEventListener('readystatechange', event => {
  if (event.target.readyState === 'interactive') {
    initLoader();
  }
  else if (event.target.readyState === 'complete') {
    initApp();
  }
});

4、DOMContentLoaded

DOM树渲染完成时触发DOMContentLoaded事件,此时可能外部资源还在加载