从零玩转jQuery-事件处理

事件绑定

  • jQuery中事件绑定有两种方式

    • eventName(function(){})
      • 绑定对应事件名的监听, 例如:$('#div').click(function(){});
    • on(eventName, funcion(){})
      • 通用的绑定事件监听, 例如:$('#div').on('click', function(){});
  • 优缺点:

    • eventName: 编码方便, 但有的事件监听不支持
    • on: 编码不方便, 但更通用
  • 企业开发中如何选择?

    • 能用eventName就用eventName, 不能用eventName就用on
  • 示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>13-jQuery事件绑定和解绑</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .father{
            width: 200px;
            height: 200px;
            background: red;
            overflow: hidden;
        }
        .son{
            width: 100px;
            height: 100px;
            background: blue;
            margin-top: 50px;
            margin-left: 50px;
        }
    </style>
    <script src="../day01/代码/js/jquery-1.12.4.js"></script>
    <script>
        $(function () {
            /*
            // 1.通过eventName绑定事件
            $(".son").click(function () {
                alert("son");
            });
            // 2.通过on绑定事件
           $(".son").on("click", function () {
               alert("son");
           });
             */

            // 2.可以多次添加相同类型的监听,后面添加不会覆盖前面添加
            function test1() {
                alert("son1");
            }
            function test2() {
                alert("son2");
            }
            function test3() {
                alert("son3");
            }
            $(".son").click(test1);
            $(".son").click(test2);
            $(".son").on("mouseleave", test3);
        });
    </script>
</head>
<body>
<div class="father">
    <div class="son"></div>
</div>
</body>
</html>

事件解绑

  • jQuery中可以通过off(eventName,function);解绑事件

  • 示例:

<script>
        $(function () {
            function test1() {
                alert("son1");
            }
            function test2() {
                alert("son2");
            }
            function test3() {
                alert("son3");
            }
            $(".son").click(test1);
            $(".son").click(test2);
            $(".son").on("mouseleave", test3);

            // 1.1不传入任何参数,移除所有事件
//            $(".son").off();
            // 1.2传入一个参数,移除指定事件
//            $(".son").off("click");
            // 1.3传入两个参数,移除指定事件中的指定回调
            $(".son").off("click", test1);
        });
</script>

获取事件的坐标

  • 当事件被触发时,系统会将事件对象(event)传递给回调函数,通过event对象我们就能获取时间的坐标

  • 获取事件坐标有三种方式

    • event.offsetX, event.offsetY 相对于事件元素左上角
    • event.pageX, event.pageY 相对于页面的左上角
    • event.clientX, event.clientY 相对于视口的左上角
  • event.page和event.client区别

    • 网页是可以滚动的,而视口是固定的
    • 所以想获取距离可视区域坐标通过event.client
    • 想获取距离网页左上角的坐标通过event.client
  • 示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>13-jQuery事件绑定和解绑</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .father{
            width: 200px;
            height: 200px;
            background: red;
            overflow: hidden;
        }
        .son{
            width: 100px;
            height: 100px;
            background: blue;
            margin-top: 50px;
            margin-left: 50px;
        }
    </style>
    <script src="../day01/代码/js/jquery-1.12.4.js"></script>
    <script>
        $(function () {
            // 获取事件的坐标
            $(".son").click(function (event) {
                // 获取相对于事件元素左上角坐标
                console.log(event.offsetX, event.offsetY);
                // 获取相对于视口左上角坐标
                console.log(event.clientX, event.clientY);
                // 获取相对于页面左上角坐标
                console.log(event.pageX, event.pageY);
            });
        });
    </script>
</head>
<body>
<div class="father">
    <div class="son"></div>
</div>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</body>
</html>

阻止事件冒泡

  • 什么是事件冒泡?

    • 事件冒泡是从目标元素逐级向上传播到根节点的过程
    • 小明告诉爸爸他有一个女票,爸爸告诉爷爷孙子有一个女票,一级级向上传递就是事件冒泡
  • 如何阻止事件冒泡?

    • 多数情况下,我们希望在触发一个元素的事件处理程序时,不影响它的父元素, 此时便可以使用停止事件冒泡
<script>
        $(function () {
            $(".son").click(function (event) {
                console.log(".son");
                // 在子元素中停止事件冒泡,时间不会继续向上传播,所以父元素click方法不会被触发
                event.stopPropagation();
            });
            $(".father").click(function () {
                console.log(".father");
            });
        });
</script>

阻止事件默认行为

  • 什么是默认行为?

    • 网页中的元素有自己的默认行为,例如单击超链接后会跳转,点击提交表单按钮会提交
  • 如何阻止事件默认行为?

    • 可以使用event.preventDefault();方法阻止事件默认行为方法
<script>
        $(function () {
            $("a").click(function (event) {
                var str = $("a").attr("href");
                // 如果超链接是百度就不跳转
                if(str.indexOf("baidu") > 0){
                    // 阻止默认行为
                    event.preventDefault();
                }
            });
        });
</script>
<script>
        $(function () {
            $("form").submit(function () {
                var userName = $("input[type='text']").val().length > 0;
                var password =  $("input[type='password']").val().length > 0;
                if(!userName && !password){
                    event.preventDefault();
                }
            });
        });
</script>

自动触发事件

  • 什么是自动触发事件?

    • 通过代码控制事件, 不用人为点击/移入/移除等事件就能被触发
  • 自动触发事件方式

    • $("selector").trigger("eventName");
      • 触发事件的同时会触发事件冒泡
      • 触发事件的同时会触发事件默认行为
    • $("selector").triggerHandler("eventName");
      • 触发事件的同时不会触发事件冒泡
      • 触发事件的同时不会触发事件默认行为
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>13-自动触发事件</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .father{
            width: 200px;
            height: 200px;
            background: red;
        }
        .son{
            width: 100px;
            height: 100px;
            background: blue;
        }
    </style>
    <script src="../day01/代码/js/jquery-1.12.4.js"></script>
    <script>
        $(function () {
            /*
            $(".son").click(function () {
                alert("son");
            });
            $(".father").click(function () {
                alert("father");
            });

            // trigger会触发事件冒泡
//            $(".father").trigger("click");
//            $(".son").trigger("click");

            // triggerHandler不会触发事件冒泡
//            $(".father").triggerHandler("click");
//            $(".son").triggerHandler("click");
            */

            $("input[type='submit']").click(function () {
                alert("点击了A标签");
            });
            // trigger会触发系统默认事件
//            $("input[type='submit']").trigger("click");
            // triggerHandler不会触发系统默认事件
            $("input[type='submit']").triggerHandler("click");

        });
    </script>
</head>
<body>
<div class="father">
    <div class="son"></div>
</div>

<form action="http://www.baidu.com">
    <input type="text">
    <input type="password">
    <input type="submit" name="sub" value="提交">
</form>
</body>
</html>

事件命名空间和自定义事件

  • 什么是自定义事件?

    • 自定义事件就是自己虾XX起一个不存在的事件名称来注册事件, 然后通过这个名称还能触发对应的方法执行, 这就是传说中的自定义事件
  • 自定义事件的前提条件

    • 1.事件必须是通过on绑定的
    • 2.事件必须通过trigger来触发
    • 因为trigger方法可以自动触发对应名称的事件,所以只要事件的名称和传递给trigger的名称一致就能执行对应的事件方法
<script>
       $(function () {
           $(".father").on("njClick", function () {
               alert("njClick");
           });
           $(".father").trigger("njClick");
       });
   </script>

  • 什么是事件命名空间?

  • 众所周知一个元素可以绑定多个相同类型的事件.企业多人协同开发中,如果多人同时给某一个元素绑定了相同类型的事件,但是事件处理的方式不同,就可能引发事件混乱

  • 为了解决这个问题jQuery提出了事件命名空间的概念

    • 事件命名空间主要用于区分相同类型的事件,区分不同前提条件下到底应该触发哪个人编写的事件
    • 格式: "eventName.命名空间"
  • 添加事件命名空间的前提条件

    • 1.事件是通过on来绑定的
    • 2.通过trigger触发事件
  • 注意点(面试题!!!面试题!!!面试题!!!):

    • 不带命名空间事件被trigger调用,会触发带命名空间事件
    • 带命名空间事件被trigger调用,只会触发带命名空间事件
    • 下级不带命名空间事件被trigger调用,会冒泡触发上级不带命名空间和带命名空间事件
    • 下级带命名空间事件被trigger调用,不会触发上级不带命名空间事件
    • 下级带命名空间事件被trigger调用,会触发上级带命名空间事件
  • 示例:

<script>
        $(function () {
            // 给父元素添加不带命名空间事件
            $(".father").on("click", function () {
                alert("father");
            });
            // 给父元素添加带命名空间事件
            $(".father").on("click.66", function () {
                alert("66 - father");
            });

            $(".son").on("click.nj", function () {
                alert("nj - 向左走");
            });
            $(".son").on("click.66", function () {
                alert("66 - 向右走");
            });
            // 会同时触发NJ和66编写的click事件
            // 事件会冒泡到不带命名空间上级元素和带相同命名空间的上级元素
//            $(".son").trigger("click");
            // 只会触发NJ编写的click事件
            // 事件不会冒泡到不带命名空间上级元素
//            $(".son").trigger("click.nj");
            // 只会触发66编写的click事件
            // 事件只会冒泡到带相同命名空间的上级元素
            $(".son").trigger("click.66");
        });
</script>

事件委托

  • 什么是事件委托?

    • 例如: 张三在寝室不想去食堂吃饭,那么张三可以"委托"李四帮忙带一份饭
    • 例如: 张三先找房,但是对要找房的地点又不熟悉,那么张三可以"委托"中介帮忙找房
    • 所以得出结论:
      • 事件委托就是请其他人帮忙做我们想做的事
      • 做完之后最终的结果还是会反馈到我们这里
  • js中事件委托的好处

    • 减少监听数量
      • 添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间
      • 每个监听的函数都是一个对象,是对象就会占用内存,对象越多,内存占用率就越大,自然性能就越差
      • ... ...
    • 新增元素自动有事件响应处理
      • 默认情况下新增的元素无法响应新增前添加的事件
  • jQuery中如何添加事件委托

  • 添加前

    • $("li").click隐式迭代给界面上所有li都添加了click事件(监听数量众多)
    • 通过$("ul").append新添加的li无法影响click事件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>18-jQuery事件委托</title>
    <script src="../day01/代码/js/jquery-1.12.4.js"></script>
    <script>
        $(function () {
            // 1.监听li点击事件
            $("li").click(function () {
                // 弹出当前点击行内容
                alert($(this).html());
            });

            // 2.监听新增按钮点击
            var count = 0;
            $("button").eq(0).click(function () {
                count++;
                // 新增一行内容
                $("ul").append("<li>我是新增内容"+count+"</li>")
            });
        });
    </script>
</head>
<body>
<ul>
    <li>我是第1行</li>
    <li>我是第2行</li>
    <li>我是第3行</li>
</ul>
<button>新增一行</button>
<button>移除事件委托</button>
</body>
</html>
  • 添加后
    • 格式:$(parentSelector).delegate(childrenSelector, eventName, callback)
    • $("ul").delegate隐式迭代所有ul添加事件(相比开始迭代li,必然ul的个数会少很多)
    • 当事件被触发时,系统会自动动态查找当前是哪个li触发了事件,所以新增的li也能响应到事件
<script>
        $(function () {
            // 1.委托ul监听li的点击事件
            $("ul").delegate("li","click",function () {
                // 前面我们说过事件委托就是让别人帮忙做事,但最终的结果还是会返回到我们手里,所以这里的this是触发事件的li
                // 这里的this之所以是触发事件的li,本质是因为"事件冒泡", 触发事件的li向上传递到ul,触发了click事件.
//                console.log(this);
                // 弹出当前点击行内容
                alert($(this).html());
            });

            // 2.监听新增按钮点击
            var count = 0;
            $("button").eq(0).click(function () {
                count++;
                // 新增一行内容
                $("ul").append("<li>我是新增内容"+count+"</li>")
            });
        });
</script>

移入移出事件

  • mouseenter和mouseleave
    • 移动到子元素不会触发事件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>14-jQuery移入移除事件</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .father{
            width: 200px;
            height: 200px;
            background-color: red;
        }
        .son{
            width: 100px;
            height: 100px;
            background-color: blue;
        }
    </style>
    <script src="../code/js/jquery-1.12.4.js"></script>
    <script>
        $(function () {
            // 移动到子元素不会触发事件
             // 2.1移入事件
             $('.father').mouseenter(function () {
               console.log('mouseenter');
             });
             // 2.2移除事件
             $('.father').mouseleave(function () {
               console.log('mouseleave');
             });
        });
    </script>
</head>
<body>
<div class="father">
    <div class="son"></div>
</div>
</body>
</html>
  • mouseover和mouseout
    • 移动到子元素触发事件
<script>
        $(function () {
             // 2.1移入事件
             $('.father').mouseover(function () {
               console.log('mouseover') ;
             });
             // 2.2移除事件
             $('.father').mouseout(function () {
               console.log('mouseout') ;
             });
        });
</script>
  • hover
    • 内容监听移入和移出
    • 内部实现就是调用mouseenter和mouseleave
<script>
        $(function () {
            /*
           // 传入两个回调函数,一个监听移入,一个监听移出
            $(".father").hover(function () {
                console.log("mouseenter");
            }, function () {
                console.log("mouseleave");
            });
            */
            // 如果只传入一个方式,那么这个方式既监听移入也监听移出
            $(".father").hover(function () {
                console.log("移入移除");
            });
        });
</script>

移入移出练习

  • 鼠标移动到哪一行,哪一行展开效果


<script>
        $(function () {
            // 1.监听li标签移入事件
            $("li").mouseenter(function () {
                console.log("mouseenter");
                // 当移入时候给当天li标签加上current类
                $(this).addClass("current");
            });
            // 2.监听li标签移出事件
            $("li").mouseleave(function () {
                console.log("mouseleave");
                // 当移入时候移除原有li标签的current类
                $(this).removeClass("current");
            });
        });
</script>
  • 鼠标移动到哪个选项卡就显示哪个选项卡对应的图片


<script>
        $(function () {
            // 1.监听tab的移入事件
            $("li").mouseenter(function () {
                // 2.修改当前移入tab背景
                $(this).addClass("cur");
                // 3.移除其它tab背景
                $(this).siblings().removeClass("cur");
                // 4.获取当前移入tab索引
                var $idx = $(this).index();
                // 5.找到对应索引的img
                var $img = $("img").eq($idx);
                // 6.让对应索引的图片显示
                $img.addClass("show");
                // 7.让其它所有图片隐藏
                $img.siblings().removeClass("show");

            });
        });
</script>
  • 鼠标移入到哪个序号就显示哪个序号对应图片


<script>
        $(function () {
            // 1.监听索引移入事件
            $(".index>li").mouseenter(function () {
                // 2.给移入的索引添加背景,其它索引删除背景
                $(this).addClass("cur").siblings().removeClass("cur");
                // 3.找到当前移入索引的序号
                var $idx = $(this).index();
                // 4.找到序号对应的图片
                var $li = $(".content>li").eq($idx);
                // 5.显示对应图片,并且让其它图片小事
                $li.addClass("show").siblings().removeClass("show");
            });
        });
</script>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 总结: 鼠标事件 1.click与dbclick事件$ele.click()$ele.click(handler(...
    阿r阿r阅读 1,595评论 2 10
  • 第1章 鼠标事件 1-1 jQuery鼠标事件之click与dbclick事件 用交互操作中,最简单直接的操作就是...
    mo默22阅读 1,260评论 0 6
  • (续jQuery基础(1)) 第5章 DOM节点的复制与替换 (1)DOM拷贝clone() 克隆节点是DOM的常...
    凛0_0阅读 1,318评论 0 8
  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 3,473评论 1 11
  • 凌晨3点 我肆意宣泄着我自己 漫长等待的时光里 我仍记得你一贯的模样 折纸,念经,细数过往 傍晚5点 我努力找寻从...
    稻草人_Z阅读 159评论 0 0