有学有练才叫学习:学而不思则罔,思而不学则殆:学而不习,纸上谈兵,习而不进,画地为牢!

js dom事件汇总

javascript cat 10个月前 (11-30) 36次浏览 已收录 0个评论 扫描二维码

1、事件基础

1、事件函数

当事件被触发时调用的函数就是事件函数

function fn() {
    console.log('我执行了');
}

div.onclick = fn; // fn是一个事件函数

fn(); // fn不是事件函数

2、事件对象

事件对象:当一个事件发生的时候,和这个事件有关的一些详细信息保留在一个对象中,这个对象就是事件对象

IE和谷歌:全局的event对象

标准浏览器:事件函数的第一个参数

兼容:IE9及以上,用事件函数的第一个参数,而IE8及以下,用全局的event

var ev = ev || event;

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

box.onclick = function (ev) {
    // console.log(ev); // 标准浏览器支持的(IE8及以下不支持)
    // console.log(event); // IE和谷歌(IE8及以下支持)
    var ev = ev || event; // 兼容处理
    // console.log(ev);

    console.log(ev.type); // 事件类型   click

    // 事件源
    // console.log(ev.target); // IE8及以下不支持
    // console.log(ev.srcElement); // IE8及以下支持
    var target = ev.target || ev.srcElement; // 事件源的兼容
    target.style.background = 'pink';

    console.log(ev.clientX, ev.clientY); // 鼠标相对于可视区的距离
    console.log(ev.pageX, ev.pageY); // 鼠标相对于文档的距离(IE8及以下不支持)

    console.log(ev.altKey); // 事件发生的时候,alt键是否按下
    console.log(ev.ctrlKey); // 事件发生的时候,ctrl键是否按下
    console.log(ev.shiftKey); // 事件发生的时候,shift键是否按下
}

2、事件绑定与取消

1、事件绑定

格式:元素.addEventListener(不要on的事件名, 函数, 是否捕获);

格式:元素.attachEvent(要on的事件名, 函数);

<div id="box"></div>
<script>
    // 需求:给同一个元素的同一个事件绑定不同的处理函数
    var box = document.getElementById('box');
    function fn1() {
        console.log(1);
        console.log(this === window);
    }
    function fn2() {
        console.log(2);
    }

    // ----------------------------------------
    // 之前方法:会覆盖(是一种赋值的写法)
    box.onclick = fn1;
    box.onclick = fn2;

    // ----------------------------------------
    // add 添加  Event 事件   Listener监听
    // 添加事件监听。第三个参数默认为false(true为捕获,false为冒泡)
    // 元素.addEventListener(不要on的事件, 函数, 是否捕获);
    // IE8及以下不支持
    box.addEventListener('click', fn1, false);
    box.addEventListener('click', fn2, false);

    // ----------------------------------------
    // attach 贴上
    // 元素.attachEvent(要on的事件, 函数);   只有冒泡
    // IE8及以下支持
    box.attachEvent('onclick', fn1);
    box.attachEvent('onclick', fn2);

    // ----------------------------------------
    // 标准浏览器的事件绑定和 ie 浏览器的事件绑定的区别:
    // ● ie 没有捕获,标准有捕获
    // ● ie 的事件名称前面有 on,标准没有
    // ● IE8及以下倒序执行,标准浏览器正序执行
    // ● ie 的 this 是 window,标准的是触发这个事件的对象

    // ----------------------------------------
    // 兼容原理。IE8及以下返回undefined,标准浏览器返回函数
    // console.log(box.addEventListener);

    if (box.addEventListener) {
        // 标准浏览器
        box.addEventListener('click', fn1, false);
        box.addEventListener('click', fn2, false);
    } else {
        // IE8及以下
        box.attachEvent('onclick', fn1);
        box.attachEvent('onclick', fn2);
    }

    // ----------------------------------------
    // 封装一个函数,实现事件绑定的兼容
    // 参数:元素 事件 函数
    function bind(ele, event, callback) {
        if (ele.addEventListener) {
            // 标准浏览器
            ele.addEventListener(event, callback, false);
        } else {
            // IE8及以下
            ele.attachEvent('on' + event, callback);
        }
    }

    bind(box, 'click', fn1);
    bind(box, 'click', fn2);

</script>

2、取消事件绑定

标准浏览器

格式:元素.addEventListener(不要on的事件名, 函数, 是否捕获);

解绑:元素.removeEventListener(不要on的事件名, 函数, 是否捕获);

IE8及以下

格式:元素.attachEvent(要on的事件名, 函数);

解绑:元素.detachEvent(要on的事件名, 函数);

<div id="box"></div>
<script>
    // 需求:给同一个元素的同一个事件绑定不同的处理函数
    var box = document.getElementById('box');
    function fn1() {
        console.log(1);
    }
    function fn2() {
        console.log(2);
    }

    // ----------------------------------------
    // 之前方法:会覆盖(是一种赋值的写法)
    box.onclick = fn1;
    box.onclick = null; // 解绑

    // ----------------------------------------
    // add 添加  Event 事件   Listener监听
    // 添加事件监听。第三个参数默认为false(true为捕获,false为冒泡)
    // 元素.addEventListener(不要on的事件, 函数, 是否捕获);
    // 元素.removeEventListener(不要on的事件, 函数, 是否捕获);
    // IE8及以下不支持
    box.addEventListener('click', fn1, false);
    box.addEventListener('click', fn2, false);
    box.removeEventListener('click', fn2, false); // 解绑

    // ----------------------------------------
    // attach 贴上   detach 分离
    // 元素.attachEvent(要on的事件, 函数);   只有冒泡
    // 元素.detachEvent(要on的事件, 函数);
    // IE8及以下支持
    box.attachEvent('onclick', fn1);
    box.attachEvent('onclick', fn2);
    box.detachEvent('onclick', fn2); // 解绑

    // ----------------------------------------
    // 封装一个函数,实现事件绑定的兼容
    // 参数:元素 事件 函数
    function bind(ele, event, callback) {
        if (ele.addEventListener) {
            // 标准浏览器
            ele.addEventListener(event, callback, false);
        } else {
            // IE8及以下
            ele.attachEvent('on' + event, callback);
        }
    }
    // 解绑兼容
    function unbind(ele, event, callback) {
        if (ele.removeEventListener) {
            // 标准浏览器
            ele.removeEventListener(event, callback, false);
        } else {
            // IE8及以下
            ele.detachEvent('on' + event, callback);
        }
    }

    bind(box, 'click', fn1);
    bind(box, 'click', fn2);
    unbind(box, 'click', fn2);

</script>

3、DOM事件流

1、事件流

事件流:当事件发生的时候,事件会按一定的顺序在根节点和各元素节点之间传播,所经过的节点,都会触发对应的事件。

事件流分为三个阶段:

1、捕获阶段:从最外层不具体的元素到具体的元素。document-html-body-box1-box2-box3

2、处于目标阶段:事件到达box3

3、冒泡阶段:从具体的元素到不具体的元素。box3-box2-box1-body-html-document

当事件经过某个元素时,这个元素上恰好绑定着事件,则这个事件就会被触发

html代码:

<div id="box1">
    <div id="box2">
        <div id="box3"></div>
    </div>
</div>

js代码:

var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
var box3 = document.getElementById('box3');

function fn() {
    console.log(this.id);
}

box1.onclick = fn; // 这种形式的绑定,是在冒泡阶段触发
box2.onclick = fn;
box3.onclick = fn;

2、捕获与冒泡

冒泡,事件在子元素发生,子元素先处理,然后子元素传递到父元素

捕获,事件在子元素发生,先经过父元素,父元素先处理,在分发到子元素

var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
var box3 = document.getElementById('box3');

function fn() {
    console.log(this.id);
}

// 第三个参数:是否捕获
// false冒泡   true捕获
box1.addEventListener('click', fn, true);
box2.addEventListener('click', fn, true);
box3.addEventListener('click', fn, true);

// 捕获触发可以设置,而冒泡触发是默认的

3、阻止冒泡

标准浏览器:event.stopPropagation();

IE 浏览器:event.cancelBubble = true;

案例:二级菜单

<button>按钮</button>
<div></div>

<script>
    // 需求:点击按钮,div显示,点击页面的任何地方,div隐藏

    // Propagationw传播  cancel取消   Bubble泡泡
    // 标准浏览器:ev.stopPropagation();
    // IE 浏览器:ev.cancelBubble = true;

    var btn = document.querySelector('button');
    var div = document.querySelector('div');

    // 点击按钮,div显示
    btn.onclick = function (ev) {
        var e = ev || event;
        // e.stopPropagation(); // 标准浏览器
        // e.cancelBubble = true; // IE8及以下

        stopPropagation(e); // 阻止冒泡的兼容,传入的参数是兼容以后的事件对象
        div.style.display = 'block';
    }

    // 点页面的任何地方,div隐藏
    document.onclick = function () {
        // setTimeout(function () {
        div.style.display = 'none';
        // }, 2000);
    }

    // 阻止冒泡的兼容
    function stopPropagation(ev) {
        if (ev.stopPropagation) {
            ev.stopPropagation(); // 标准浏览器
        } else {
            ev.cancelBubble = true; // IE8及以下
        }
    }
</script>

4、事件默认行为

某些事件,即赋予了元素特殊的操作

标准浏览器:ev.preventDefault();

IE8及以下:ev.returnValue = false;

通用(要放在函数的最后):return false;

<a href="http://paozha.net">山猫博客</a>

<script>
    var a = document.querySelector('a');

    a.onclick = function (ev) {
        var e = ev || window.event;
        // e.preventDefault(); // 标准浏览器支持
        // e.returnValue = false; // IE8及以下支持
        // preventDefault(e)

        return false; // 通用,局限性(必须放在函数的最后)
    }

    function preventDefault(ev) {
        if (ev.preventDefault) {
            // 标准浏览器支持
            ev.preventDefault();
        } else {
            // IE8及以下支持
            ev.returnValue = false;
        }
    }
</script>

案例:自定义右键菜单

5、事件委托

事件委托:也叫事件代理,利用事件冒泡原理,只指定一个事件处理程序,就可以管理某一类型的所有事件。

实现:将事件添加到父元素上,当事件发生时,父元素会找到对应触发事件的子元素去处理。好处:后期添加的子元素,依然有这个事件。

好处:

1、新添加的元素也有之前的事件

2、提高性能

html代码:

<ul>
    <li>吃饭</li>
    <li>睡觉</li>
    <li>拉粑粑</li>
</ul>

js代码:

<script>
    // 需求:点击li,给它添加背景色
    var ul = document.querySelector('ul');

    // 之前的做法:循环
    // 1、后添加的元素没有之前的事件
    // 2、如果元素过多,会耗性能
    // var li = ul.querySelectorAll('li');
    // for (var i = 0; i < li.length; i++) {
    //     li[i].onclick = function () {
    //         this.style.backgroundColor = 'red';
    //     }
    // }

    // --------------------------------
    // 利用事件代理(事件委托)
    // 优点:
    // 1、后添加的元素也有之前的事件
    // 2、不论子元素多不少个,都只绑定一次事件,节省性能
    ul.onclick = function (ev) {
        var e = ev || event; // 事件对象的兼容
        var target = e.target || e.srcElement; // 事件源的兼容

        // console.log(target.nodeName);
        // 对事件源进行判断
        if (target.nodeName === 'LI') {
            target.style.backgroundColor = 'pink';
        }
    }

    // --------------------------------
    // 创建一项,添加给ul
    var newLi = document.createElement('li');
    newLi.innerText = '我是新来的';
    ul.appendChild(newLi);
</script>

6、键盘事件

1、键盘事件

元素.onkeydown 键盘按下

元素.onkeyup 键盘抬起

在能响应用户输入的元素上触发(表单元素、document都可以响应键盘事件)

var input = document.querySelector('input');

// 按下
input.onkeydown = function () {
    console.log(this.value);
}

// 抬起
input.onkeyup = function () {
    console.log(this.value);
}

2、键盘事件的事件对象

var input = document.querySelector('input');

input.onkeydown = function (ev) {
    var ev = ev || event;

    console.log(ev); // 键盘的事件对象

    console.log(ev.key); // 键盘键值(IE8及以下不支持)
    console.log(ev.keyCode); // 键码
    // a65  z90  空格32  回车13  esc27

    console.log(ev.altKey); // 是否按下alt键
    console.log(ev.ctrlKey);
    console.log(ev.shiftKey);

}

7、滚轮事件

标准和IE:

事件:onmousewheel

方向:ev.wheelDelta 上:120 下:-120

火狐:

事件:DOMMouseScroll 必须用addEventListener绑定

方向:ev.detail 上:-3 下:3

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

<script>
    // 在box上滚动滚轮,向下滚高度增加,向上滚高度减小

    var box = document.getElementById('box');
    var h = box.clientHeight; // 获取元素的高
    // console.log(h);

    bind(box, 'mousewheel', fn); // IE和标准
    bind(box, 'DOMMouseScroll', fn); // 火狐

    function fn(ev) {
        var ev = ev || event;
        if (wheelDelta(ev) > 0) {
            // 向上
            h--;
        } else {
            // 向下
            h++;
        }

        box.style.height = h + 'px';
    }

    // 滚轮方向的兼容:向上120   向下-120
    function wheelDelta(ev) {
        if (ev.wheelDelta) {
            // 标准和 IE
            return ev.wheelDelta;
        } else {
            // 火狐
            return -40 * ev.detail;
        }
    }

    // 事件绑定
    function bind(ele, event, callback) {
        if (ele.addEventListener) {
            // 标准浏览器
            ele.addEventListener(event, callback, false);
        } else {
            // IE8及以下
            ele.attachEvent('on' + event, callback);
        }
    }

</script>
喜欢 (0)
cat
关于作者:
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址