事件基础

目录

1.什么是事件
2.事件对象及兼容处理
3.事件的传播机制
4.案例-鼠标跟随jQuery
5.案例-鼠标跟随JS版
6.鼠标跟随、深入理解事件的传播机制
7.事件委托/事件代理
8.案例-京东商城放大镜
9.案例-百度搜索框
10.案例-多级菜单JS版
11.案例-多级菜单jQuery版
12.拖拽demo实现基本的效果
13.拖拽demo解决鼠标丢失

1.什么是事件

事件分为两部分:

1.行为本身:浏览器天生就赋予其的行为。onclick、onmouseover(onmouserenter)、onmouseout(onmouseleave)、onmousemove、ommousemove、onmousedown、onmouseup、onmousewheel(鼠标滚轮滚动行为)、onscroll(滚动条滚动行为)、onresize(window.onresize 浏览器窗口大小改变事件)、onload、onunload、onfouse文本框获取焦点行为)、onblur(浏览器失去焦点)、onkeydown(键盘按下行为)、onkeyup……

哪怕没有给上述行为绑定方法,事件也存在。当点击这个盒子的时候,同样会触发它的onclick行为,只是什么事情都没做而已。

2.事件绑定:给元素的某一个行为绑定一个方法

//DOM0级事件绑定
var oDiv = document.getElementById("div1");
oDiv.onclick = function () {
   
    //当触发oDiv的onclick行为的时候,会把绑定的这个函数执行
};
//DOM2级事件绑定
oDiv.addEventListener("click", function () {
   
    console.log("ok");
}, false);

onclick这个行为定义在当前元素的私有属性上;
addEventListener这个属性是定义在当前元素所属EventTarget这个类的原型上的

2.事件对象及兼容处理

oDiv.onclick = function () {
   
};

把匿名函数定义的部分当做一个值赋值给oDiv的点击行为(函数表达式)
当触发div的点击行为的时候,会执行对应绑定上的方法
不仅仅把绑定的方法执行了,而且浏览器还默认的给这个方法传递了一个参数值:MouseEvent:鼠标事件对象。

  • MouseEvent是一个对象数据类型值,里面包含了很多的属性名和属性值,这些都是用来记录当前鼠标的相关信息的
  • MouseEvent -> UIEvent -> Event -> Object
  • MouseEvent记录的是页面中唯一一个鼠标每一次触发时候的相关信息,和到底是在哪个元素上触发的没有关系

关于事件对象(MouseEvent)的兼容性问题:

1、事件对象本身的获取存在兼容问题:标准浏览器中是浏览器给方法传递的参数,只需要定义形参e就可以获取到

oDiv.onclick = function (e) {
   
    console.log(e);
};

2、在IE6-8中,浏览器不会给方法传递参数,如果需要的话,需要到window.event中获取查找。
解决方法:

oDiv.onclick = function (e) {
   
    e = e || window.event;
    console.log(e);
};

常用信息:

  • e.clientX/e.clientY:鼠标触发点距离当前屏幕左上角的坐标值
  • e.type:存储的是当前鼠标触发的行为类型,如“click”
  • e.target:事件源,当前鼠标触发的是哪个元素,那么它存储的就是哪个元素。存在兼容性问题,在IE6-8中不存在这个属性,即为undefined,可以使用e.srcElement来获取事件源。解决方法:e.target = e.target || e.srcElement;
  • e.preventDefault:阻止浏览器的默认行为。如a标签的默认行为就是跳转页面,但是有时候使用a标签,只是想应用它的特殊性,并不想点击的时候跳转。存在兼容性问题,在IE6-8中不存在这个属性,需要使用e.returnValue = false;来代替。
a.onclick = function (e) {
   
    e = e || window.event;
    e.preventDefault ? e.preventDefault() : e.returnValue = false;
    //或者:return false;
    //或者:见下
};
<li><a href="javascript:;"></a></li>
/*
直接在HTML结构上阻止
或者:href="javascript:void 0;"
href="javascript:void 1;"
*/
  • e.pageX/e.pageY:当前鼠标触发点距离body左上角(页面第一屏幕最左上角)的x/y轴的坐标。存在兼容性问题,在IE6-8中不存在这个属性,即为undefined,解决方法:
e.pageX = e.pageX || (e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));
e.pageY = e.pageY || (e.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
  • e.stopPropagation:阻止事件的冒泡传播,在IE6-8中不存在这个属性,解决方法如下:
e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
  • e.keycode:当前键盘上每一个键对应的值,如:空格:32;回退键:8;回车键:13;delete:46;左:37;上:38;右:39;下:40
3.事件的传播机制

有以下代码:

<body>
<div id="outer">
    <div id="inner">
        <div id="center"></div>
    </div>
</div>
<script type="text/javascript">
    var outer = document.getElementById("outer"),
        inner = document.getElementById("inner"),
        center = document.getElementById("center");
    document.body.onclick = function () {
    
        console.log("body");
    };
    outer.onclick = function () {
    
        console.log("outer");
    };
    inner.onclick = function () {
    
        console.log("inner");
    };
    center.onclick = function () {
    
        console.log("center");
    };
</script>
</body>

点击时,控制台会输出:center、inner、outer、body,这就涉及到了事件的默认传播机制。

事件的默认传播机制分为三个阶段:

  • 捕获阶段:从外向里依次查找元素
  • 目标阶段:当前事件源本身的操作
  • 冒泡阶段:从内到外依次触发相关的行为

最常用的就是冒泡阶段。

用DOM0级事件绑定给元素的某一个行为绑定的方法,都是在行为触发后的冒泡阶段把方法执行的。如图:

冒泡阶段:

  • 当前center的click行为被触发,如果给其绑定了方法,首先把center对应的方法执行(目标阶段)
  • 不仅仅center的click行为被触发了,它所有的父级元素的click行为也会被触发。inner的click行为触发->如果给inner也绑定了方法,inner对应的方法也会执行
  • 同理依次查找outer、body、html、document

注意:每个浏览器传播到的最顶层是不一样的。谷歌中可以到document,IE中只能传播到HTML。

document.body.addEventListener("click", function () {
    console.log("body");
}, false); //第一个参数是行为的类型,第二个参数是给当前的行为绑定的方法,第三个参数是控制在哪个阶段发生,true是捕获阶段发生,false是冒泡阶段发生
outer.addEventListener("click", function () {
    console.log("outer");
}, true);
inner.addEventListener("click", function () {
    console.log("inner");
}, false);

点击center的div,输出:outer、inner、body

4.案例-鼠标跟随jQuery

效果图:

HTML代码:

<div id="box" class="box">
    <img src="img/1.jpg" bigImg="img/11.jpg"/>
    <img src="img/2.jpg" bigImg="img/22.jpg"/>
    <img src="img/3.jpg" bigImg="img/33.jpg"/>
    <img src="img/4.jpg" bigImg="img/44.jpg"/>
    <div id="mark">
        <img src="img/11.jpg"/>
    </div>
</div>

CSS代码:

body, div, ing {
    margin: 0;
    padding: 0;
}

img {
    display: block;
    border: none;
}

.box {
    width: 450px;
    margin: 20px auto;
    position: relative;
}

.box img {
    width: 100px;
    border: 1px solid #777777;
    float: left;
    margin-left: 10px;
}

#mark {
    position: absolute;
    top: 0px;
    left: 0;
    width: 384px;
    height: 216px;
    border: 1px solid #5bc0de;
    z-index: 10;
    display: none;
}

#mark img {
    border: none;
    float: none;
    margin-left: 0px;
    width: 100%;
    height: 100%;
}

JavaScript代码(jQuery):

$(function () {
    var $box = $("#box"),
        $mark = $("#mark"),
        $boxOffset = $box.offset(); //获取当前元素距离body的偏移
    $box.children("img").mouseover(function (e) {
        e = e || window.event;
        e.target = e.target || e.srcElement;
        var left = e.clientX - $boxOffset.left + 10;
        var top = e.clientY - $boxOffset.top + 10;
        $mark.stop().show(100).css({left: left, top: top}).find("img").attr("src", e.target.getAttribute("bigImg"));
    }).bind("mousemove", function (e) {
        e = e || window.event;
        e.target = e.target || e.srcElement;
        var left = e.clientX - $boxOffset.left + 10;
        var top = e.clientY - $boxOffset.top + 10;
        $mark.css({left: left, top: top});
    }).bind("mouseout", function (e) {
        $mark.stop().hide(100);
    });
});
5.案例-鼠标跟随JS版

效果图:

HTML代码:

<div id="box">
    <!--<div id="mark"></div>-->
</div>

CSS代码:

body, div {
    margin: 0;
    padding: 0</
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值