488 DOM0和DOM2事件绑定的原理使用区别

Posted jianjie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了488 DOM0和DOM2事件绑定的原理使用区别相关的知识,希望对你有一定的参考价值。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="css/reset.min.css">
    <style>
        html,
        body {
            height: 100%;
            background: lightcyan;
        }

        #box {
            box-sizing: border-box;
            position: absolute;
            top: 50%;
            left: 50%;
            margin: -100px 0 0 -100px;
            width: 200px;
            height: 200px;
            background: lightcoral;
        }
    </style>
</head>

<body>
    <div id="box"></div>

    <script>
		/* 
		 * DOM0事件绑定 VS DOM2事件绑定
		 *   [DOM0]
		 *     元素.on事件行为 = function(){}

		 *   [DOM2]
		 *     元素.addEventListener(事件行为, function(){}, true/false)
		 *     IE6~8中:元素.attachEvent(‘on事件行为‘, function(){}),要加on
		*/

        /* DOM0事件绑定的原理:给元素的私有属性赋值,当事件触发,浏览器会帮我们把赋的值执行,但是这样也导致 “只能给当前元素某一个事件行为绑定一个方法” */
        box.onclick = function () {
            console.log(‘哈哈哈~~‘);
        }

        box.onclick = function () {
            console.log(‘呵呵呵~~‘);
        }

        box.onclick = function () {
            console.log(‘哈哈哈~~‘);
            // => 移除事件绑定:DOM0直接赋值为null即可
            box.onclick = null;
        }


        /* ================================================ */


        // DOM2事件绑定的原理:
        // (1)基于原型链查找机制,找到EventTarget.prototype上的方法并且执行,此方法执行,会把给当前元素某个事件行为绑定的所有方法,存放到浏览器默认的事件池中(绑定几个方法,会向事件池存储几个);
        // (2)当事件行为触发,会把事件池中存储的对应方法,依次按照顺序执行 “给当前元素某一个事件行为绑定多个不同方法” 
        box.addEventListener(‘click‘, function () {
            console.log(‘哈哈哈~~‘);
        }, false);

        box.addEventListener(‘click‘, function () {
            console.log(‘呵呵呵~~‘);
        }, false);

        // => DOM2事件绑定的时候,我们一般都采用实名函数
        // => 目的:这样可以基于实名函数去移除事件绑定
        function fn() {
            console.log(‘哈哈哈~~‘);
            // => 移除事件绑定:从事件池中移除,所以需要指定好事件类型、方法等信息(要和绑定的时候一样才可以移除)
            box.removeEventListener(‘click‘, fn, false);
        }
        box.addEventListener(‘click‘, fn, false);

        function fn1() {
            console.log(1);
        }
        function fn2() {
            console.log(2);
        }
        function fn3() {
            console.log(3);
        }

        box.addEventListener(‘click‘, fn2, false);
        box.addEventListener(‘click‘, fn3, false);
        box.addEventListener(‘click‘, fn1, false);

        // => 基于addEventListener向事件池增加方法,存在去重的机制: “同一个元素,同一个事件类型,在事件池中只能存储一遍这个方法,不能重复存储”
        box.addEventListener(‘click‘, fn1, false);
        box.addEventListener(‘mouseover‘, fn1, false);

        window.oncontextmenu = function (ev) {
            alert("哇咔咔~~");
        }

        /* DOM0和DOM2可以混在一起用:执行的顺序以绑定的顺序为主 */
        box.addEventListener(‘click‘, function () {
            console.log(‘哔咔哔咔~~‘);
        });
        box.onclick = function () {
            console.log(‘哇咔咔~~‘);
        }
        box.addEventListener(‘click‘, function () {
            console.log(‘call~~‘);
        });


        // --------------------------


        /* DOM0中能做事件绑定的事件行为,DOM2都支持;DOM2里面一些事件,DOM0不一定能处理绑定,例如:transitionend、DOMContentLoaded... */
        // box.style.transition = ‘opacity 1s‘;
        box.ontransitionend = function () {
            console.log(‘哇咔咔~~‘);
        }

        box.addEventListener(‘transitionend‘, function () {
            console.log(‘哇咔咔~~‘);
        });

        window.addEventListener(‘load‘, function () {
            // => 所有资源都加载完成触发
            console.log(‘LOAD‘);
        });

        window.addEventListener(‘DOMContentLoaded‘, function () {
            // => 只要DOM结构加载完就会触发
            console.log(‘DOMContentLoaded‘);
        });

        // => $(document).ready(function(){})
        $(function () {
            // => JQ中的这个处理(DOM结构加载完触发)采用的就是DOMContentLoaded事件,并且依托DOM2事件绑定来处理,所以同一个页面中,此操作可以被使用多次
        });
        $(function () {

        });
		/* JQ中的事件绑定采用的都是DOM2事件绑定,例如:on/off/one */
    </script>

    <script src="js/jquery.min.js"></script>

    <script>
        let $box = $(‘#box‘);
		/* $box.one(‘click‘, function () {
			console.log(‘哇咔咔~~‘);
		}); */
        $box.on(‘click‘, function () {
            console.log(‘哇咔咔~~‘);
        });
        $box.on(‘click‘, function () {
            console.log(‘哔咔哔咔,丘~~‘);
        });

		// window.onload VS $(document).ready()
		// 1.$(document).ready() 采用的是DOM2事件绑定,监听的是DOMContentLoaded这个事件,所以只要DOM结构加载完成就会被触发执行,而且同一个页面中可以使用多次(绑定不同的方法,因为基于DOM2事件池绑定机制完成的)
		// 2.window.onload必须等待所有资源都加载完成才会被触发执行,采用DOM0事件绑定,同一个页面只能绑定一次(一个方法),想绑定多个也需要改为window.addEventListener(‘load‘, function () {})DOM2绑定方式
    </script>
</body>

</html>

以上是关于488 DOM0和DOM2事件绑定的原理使用区别的主要内容,如果未能解决你的问题,请参考以下文章

js DOM0级事件和DOM2级事件

JavaScript 学习-30.HTML DOM0级事件和 DOM2级事件

DOM0DOM2级事件

JS中dom0级事件和dom2级事件的区别介绍

DOM0和DOM2事件的应用和区别详细对比

理解:javascript中DOM0,DOM2,DOM3级事件模型