jQuery事件相关

一. jQuery事件绑定

  • jQuery中有两种绑定事件的方式
  • eventName(fn)方法: 直接通过事件名来绑定
$('button').click(function(){
	alert('点击第一次')
})

优点: 编码效率高

缺点: 部分事件不能添加,因为jQuery没有实现

  • on(eventName, fn)方法: 通过on()方法来绑定
$('button').on('click',function(){
    alert('点击第二次')
})

优点: 所有js事件都可以实现

缺点: 编码效率略低

  • 以上两种方法都可以添加多个相同或不同类型的事件,不会覆盖例如:
$('button').click(function () {
     console.log('鼠标点击了')
 })
 
 $('button').click(function () {
     console.log('你好')
 })
 
 $('button').mouseleave(function () {
     console.log('鼠标离开了')
 })
 
 $('button').mouseenter(function () {
     console.log('鼠标移入了')
 })

二. jQuery事件移除

  • off()方法: 移除事件
  • 不传参数,移除所有事件
$('button').off();
  • 传一个参数,会移除所有指定类型的事件
$('button').off('click');
  • 传两个参数,会移除指定类型的指定事件
$('button').off('click', text2);
  • 完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jQuery事件移除</title>
    <script src="../jquery-3.5.1.js"></script>
    <script>
        $(function () {
            function text(){
                alert('鼠标点击了')
            }

            function text2() {
                alert('你好')
            }

            // 点击事件
            $('button').click(text)
            $('button').click(text2)
            $('button').mouseleave(function () {
                alert('鼠标离开了')
            })
            $('button').mouseenter(function () {
                alert('鼠标移入了')
            })


            // $('button').off(); 
            // $('button').off('click'); 
            $('button').off('click', text2); 
        })
    </script>
</head>
<body>
    <button>点击</button>
</body>
</html>

三. jQuery事件冒泡和默认行为

  • 事件冒泡:给子元素和父元素都设置事件时,子元素相应事件父元素也会跟着相应,是一个从下级传向上级的过程
<head>
    <style>
        *{
            margin: 0;
            padding: 0;
        }

        .father{
            width: 100px;
            height: 100px;
            background: aquamarine;
        }

        .son{
            width: 50px;
            height: 50px;
            background: gray;
        }
    </style>
    <script>
        $(function(){
            // 给son和father添加点击事件
            $('.son').click(function(){
                alert('son')
            })

            $('.father').click(function () {
                alert('father')
            })
        })
    </script>
</head>
<body>
    <div class="father">
        <div class="son"></div>
    </div>
</body>

此时点击son不仅会弹出son,也会弹出father。这就是事件冒泡

  • 阻止事件冒泡:
  • 在子元素设置:return false
$('.son').click(function(){
    alert('son');
    return false;
})
  • 在子元素设置:event.stopPropagation();
$('.son').click(function(event){
    alert('son');
    event.stopPropagation();
})
  • 默认行为:标签默认会执行的行为,如a标签默认点击会跳转
<a href="https://www.baidu.com/">百度</a>
  • 阻止默认行为:
  • return false
$('a').click(function(){
    alert('跳转新页面')
    return false;
})

设置之后再点击时只会弹窗,不会跳转

  • event.preventDefault()
$('a').click(function(event){
    alert('跳转新页面')
    event.preventDefault();
})

效果同上

四. jQuery事件自动触发

  • trigger和triggerHandler
  • 页面布局
<body>
    <div class="father">
        <div class="son"></div>
    </div>
    
    <a href="https://www.baidu.com/">百度</a>
    <form action="https://www.qq.com/">
        <input type="text">
        <input type="submit">
    </form>
</body>
  • jQuery代码
$(function () {
    // 添加点击事件
    $('.son').click(function () {
        alert('son');
    })
    $('.father').click(function () {
        alert('father')
    })

    // 设置自动触发
    /*
        trigger: 如果利用trigger自动触发事件,会触发事件冒泡
        triggerHandler: 如果利用triggerHandler自动触发事件,不会触发事件冒泡
    */
    // $('.son').trigger('click')   // 设置点击事件自动触发
    // $('.son').triggerHandler('click')

    /*
        trigger:如果利用trigger自动触发事件,会触发默认行为
        triggerHandler:如果利用triggerHandler自动触发事件,不会触发默认行为
    */
    $('input[type="submit"]').click(function(){
        alert('submit')
    })

    // $('input[type="submit"]').trigger('click');
    // $('input[type="submit"]').triggerHandler('click');
})

trigger: 会触发事件冒泡和默认行为

triggerHandler: 不会触发事件冒泡和默认行为

  • 注意:a标签和其他标签有点不同
$('a').click(function(){
    alert('a')
})

// $('a').triggerHandler('click')    // 不会触发事件冒泡和默认行为
$('a').trigger('click')

如果这样写用trigger()方法a的默认行为也不会触发,也就是不会跳转

  • 如果要想a标签自动触发是也触发默认行为要改下页面结构
<body>
    <a href="https://www.baidu.com/"><span>百度</span></a>
</body>
  • 这样直接设置span就能触发默认行为了
$('a').click(function(){
    alert('a')
})

$('span').trigger('click')

五. jQuery自定义事件

  • 自定义事件必须满足的两个条件:
  1. 事件必须是通过on()绑定的
  2. 事件必须通过trigger()triggerHandler()来触发
$('div').on('myClick', function(){
    alert('自定义事件触发了')
})
$('div').trigger('myClick')

给div添加自定义事件,用trigger()来触发

六. jQuery事件命名空间

  • 事件命名空间
  1. 事件必须是通过on()绑定的
  2. 事件通过trigger()triggerHandler()来触发
$(function () {
    // 通过事件名.的方式来设置命名空间
    $('div').on('click.yellow', function () {
        alert('yellow的click')
    })

    $('div').on('click.green', function () {
        alert('green的click')
    })

    // $('div').triggerHandler('click') // 都触发
    $('div').triggerHandler('click.yellow') // 只触发yellow的
})
  • 注意:
  • 利用trigger触发子元素带命名空间的事件,父元素带相同命名空间的事件也会被触发.而父元素没有命名空间的事件不会被触发
  • 利用trigger触发子元素不带命名空间的事件,子元素所有相同类型的事件和父元素所有相同类型的事件都会被触发
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jQuery事件命名空间</title>
    <style>
        .father{
            width: 100px;
            height: 100px;
            background: green;
        }

        .son{
            width: 50px;
            height: 50px;
            background:yellow;
        }
    </style>
    <script src="../jquery-3.5.1.js"></script>
    <script>
        $(function () {
            $('.father').on('click.blue', function () {
                alert('father-blue的click')
            })

            $('.father').on('click', function () {
                alert('father的click')
            })

            $('.son').on('click.blue', function () {
                alert('son-blue的click')
            })

            // $('.son').trigger('click.blue') // son-blue的click | father-blue的click触发了
            $('.son').trigger('click') // 三个都触发了
        })
    </script>
</head>
<body>
    <div class="father">
        <div class="son"></div>
    </div>
</body>
</html>

七. jQuery事件委托

  • 可以找一个在入口函数执行前就存在的元素来监听动态添加元素的某些事件
  • 页面结构
<body>
    <ul>
        <li>第一个li的</li>
        <li>第二个li的</li>
        <li>第三个li的</li>
    </ul>
    <button>添加li</button>
</body>
  • jQuery代码
// 添加按钮点击事件
$('button').click(function(){
    $('ul').append('<li>新的li</li>')  // 再ul里追加li
})

// 添加li点击事件
$('ul>li').click(function(){
    console.log($(this).html())
})

这样设置的点击事件新增的li是没有的

$('ul').delegate('li','click',function(){
    console.log($(this).html())
})

把li的click事件委托给ul去监听,这样动态添加的li也有点击事件

点li时li没有click,此时向上传递到ul,ul有click事件所以相应了ul的click事件。所以这里的this是li

  • 小练习
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件委托练习</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        html,body{
            width: 100%;
            height: 100%;
        }

        #box{
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            position: fixed;
            top: 0;
            left: 0;
        }

        #cont{
            width: 500px;
            height: 300px;
            background: white;
            position: relative;
            left: 42%;
            top: 32%;
        }

        #exit{
            width: 30px;
            height: 30px;
            position: absolute;
            right: 0;
            top: 0;
            border: 1px solid black;
            font-size: 16px;
            text-align: center;
            line-height: 30px;
            font-weight: bold;
            cursor: pointer;
        }
    </style>
    <script src="../jquery-3.5.1.js"></script>
    <script>
        $(function(){
            var $mask = $(
                "<div id='box'>\n"+
                    "<div id='cont'>\n"+
                        "<div id='exit'>x</div>\n"+
                    "</div>\n"+
                "</div >"
            );

            $('a').click(function(){
                $('body').append($mask);
                return false;
            });

            $('body').delegate('#exit','click',function(){
                alert('退出')
                $mask.remove();
            })
        })
    </script>
</head>
<body>
    <a href="#">点击登录</a>
    <!-- <div id="box">
        <div id="cont">
            <div id="exit">x</div>
        </div>
    </div> -->
</body>
</html>

八. jQuery其他事件处理

  • bind()和on()一样
  • unbind()和off()一样
  • one()和on() 一样,不过one()添加的事件只执行一次

九. jQuery移入移出事件

  • mouseover/mouseout事件: 子元素被移入移出会触发父元素的事件
$('.father').mouseover(function(){
    console.log('mouseover方法鼠标移入了')
})

$('.father').mouseout(function () {
    console.log('mouseout方法鼠标移出了')
})
  • mouseenter/mouseleave事件: 子元素被移入移出不会触发父元素的事件
$('.father').mouseenter(function(){
    console.log('mouseenter方法鼠标移入了')
})

$('.father').mouseleave(function () {
    console.log('mouseleave方法鼠标移出了')
})

推荐使用mouseenter/mouseleave

  • 同时能监听移入移出的方法hover()
  • 传入两个参数: 第一个监听移入,第二个监听移出
$('.father').hover(function(){
    console.log('hover方法鼠标移入了')
},function(){
    console.log('hover方法鼠标移出了')
})
  • 传入一个参数:既监听移入也监听移出
$('.father').hover(function () {
    console.log('hover方法鼠标移入移出了')
})
  • hover是使用mouseenter/mouseleave做的所以移入移出不会触发父元素的事件