5.jQuery的事件的介绍及使用

浏览器的事件模型

在js中有两种事件模型:
DOM 0级事件模型 基本所有浏览器都支持
DOM 2级事件模型 绝大部分现代浏览器支持

还是上代码举例说明8
在这里插入图片描述

	<p id="example" onclick="console.log('Click');">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Officiis praesentium, sapiente? Earum, molestiae rem. Enim, perspiciatis quisquam! A consequatur culpa error et, natus nobis placeat qui rem, suscipit tempora tenetur.
    </p>
    <script>
    document.getElementById('example').onclick = function(event) {
     
     
        console.log('click me');
    };
    document.getElementById('example').onclick = function(event) {
     
     
    event = event || window.event;//浏览器兼容问题
    console.log('click me2');
    };
    </script>

事件只能绑定一次,后面绑定的会覆盖前面的。

除此之外,事件执行时还会检测父元素有没有事件,要是有,依次触发,例如:

	<div id="p1">
        <div id="p1-1">
            <div id="p1-1-1">
                <div id="p1-1-1-1">
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet architecto beatae delectus enim ipsum iusto laborum, libero minus perspiciatis quae quidem rem sed soluta velit veniam voluptatem voluptates voluptatibus. Repudiandae.
                    </p>
                </div>
            </div>
        </div>
    </div>
document.getElementById('p1').onclick = function() {
    
    
        console.log('p1');
    };
    document.getElementById('p1-1').onclick = function() {
    
    
        console.log('p1-1');
    };
    document.getElementById('p1-1-1').onclick = function() {
    
    
        console.log('p1-1-1');
    };
    document.getElementById('p1-1-1-1').onclick = function(e) {
    
    
        console.log('p1-1-1-1');
        //        e.cancelBubble = true;
        //			e.stopPropagation();
    };

这就是事件冒泡。当然如果我加上上面任意一行代码就可以取消冒泡了

最大的缺点就是只支持一个DOM事件处理函数,所以有了DOM2级事件模型。

在这里插入图片描述
attachEvent()是针对IE浏览器支持的

	var element = document.getElementById('example');
    element.addEventListener('click', function(event) {
    
    
        console.log('Click1');
    }, false);
    element.addEventListener('click', function(event) {
    
    
        console.log('Click2');
    }, false);
    element.addEventListener('click', function(event) {
    
    
        console.log('Click3');
    }, false);

此时点击一次,多个事件都会依次执行,不会覆盖。

DOM 2级事件除了有冒泡机制还加入了捕获机制,上面设置为false就是指只冒泡不捕获,如果为true则相反。
在这里插入图片描述

var useCapture = true;

    document.getElementById('p1').addEventListener('click', function() {
    
    
        console.log('p1');
    }, useCapture);

    document.getElementById('p1-1').addEventListener('click', function() {
    
    
        console.log('p1-1');
    }, useCapture);

    document.getElementById('p1-1-1').addEventListener('click', function() {
    
    
        console.log('p1-1-1');
    }, useCapture);

    document.getElementById('p1-1-1-1').addEventListener('click', function() {
    
    
        console.log('p1-1-1-1');
    }, useCapture);

此时就是捕获,从上往下执行。(为了兼容性,很少使用,基本用冒泡)
那如何实现既捕获又冒泡呢?
其实就是执行两遍就行,先捕获,然后冒泡。

为了处理兼容性问题,对于事件的处理,通常会使用下面的代码:

var EventsUtility = {
    
    
    addEvent: function (element, type, callback) {
    
    
        if (typeof addEventListener !== 'undefined') {
    
    
            element.addEventListener(type, callback, false);
        } else if (typeof attachEvent !== 'undefined') {
    
    
            element.attachEvent('on' + type, callback); // IE, legacy browser
        } else {
    
    
            element['on' + type] = callback; //DOM 0级
        }
    },

    removeEvent: function (element, type, callback) {
    
    
        if (typeof removeEventListener !== 'undefined') {
    
    
            element.removeEventListener(type, callback, false);
        } else if (typeof detachEvent !== 'undefined') {
    
    
            element.detachEvent('on' + type, callback); // IE, legacy browser
        } else {
    
    
            element['on' + type] = null;
        }
    },

    getTarget: function (event) {
    
    
        if (typeof event.target !== 'undefined') {
    
    
            return event.target;
        } else {
    
    
            return event.srcElement; // IE, legacy browser
        }
    },

    preventDefault: function (event) {
    
    
        if (typeof event.preventDefault !== 'undefined') {
    
    
            event.preventDefault();
        } else {
    
    
            event.returnValue = false;
        }
    },

    getCharCode: function (event) {
    
    
        if (typeof event.charCode === 'number') {
    
    
            return event.charCode;
        } else {
    
    
            return event.keyCode; // IE, legacy browser
        }
    }
};

接下来进入主题:jQuery事件

在这里插入图片描述
在这里插入图片描述

<div class="item">
        <p>Lorem ipsum dolor sit amet.</p>
    </div>
    <ul>
        <li class="item1">新闻标题-1</li>
        <li class="item2">新闻标题-2</li>
        <li class="item3">新闻标题-3</li>
        <li class="item4">新闻标题-4</li>
        <li class="item5">新闻标题-5</li>
        <li class="item6">新闻标题-6</li>
        <li class="item7">新闻标题-7</li>
        <li class="item8">新闻标题-8</li>
        <li class="item9">新闻标题-9</li>
    </ul>
    <div id="p1">
        <div id="p1-1">
            <div id="p1-1-1">
                <div id="p1-1-1-1">
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet architecto beatae delectus enim ipsum iusto laborum, libero minus perspiciatis quae quidem rem sed soluta velit veniam voluptatem voluptates voluptatibus. Repudiandae.
                    </p>
                </div>
            </div>
        </div>
    </div>
$(function() {
    
    
	$('p')
	.on('click', null, null, function (e) {
    
    
	       console.log('p clicked');
	})//这里获取的是p的一个集合,不管点哪个p都会触发
	.on('click', function (e) {
    
    
           console.log('p clicked2');
     })//不加null也一样
     .on('click',function (e) {
    
    
          console.log('p clicked3';
     })//触发链式
	.on('click', {
    
     foo: 'bar' }, function (e) {
    
    
          console.log('p clicked3 %o', e.data);
     })//给它加数据,%o为占位符
     .on('mouseover', function (e) {
    
    
     		console.log('p mouseover');
      })
      .on('mouseover', function (e) {
    
    
          console.log('p mouseover2');
      })
                   
	$('div').on('click','#p1-1', function () {
    
    
          console.log(pp);
      })//过滤,只选择id为对应的才触发
      
//事件委托
	 $('ul').on('click', 'li.item2', function () {
    
    
     		console.log('li clicked');
      })
      $('li').on('click', function (e) {
    
    
          	console.log('Clicked: %o', $(this));
      })
      //给父节点添加,根据target不同,效果一样
      $('ul').on('click', 'li', function (e) {
    
    
      if(event.target)//如果是li元素就执行
            console.log('Clicked: %o', $(e.target));
      })//根据冒泡,点击li,会冒泡到ul,然后触发,这样建少了绑定事件数目
      //这就是事件的委托,委托在父元素上,提升性能
})

在这里插入图片描述

$('p').on('click', function (e) {
    
    
     e.stopPropagation()
     console.log('clicked p');
      })

在这里插入图片描述
在这里插入图片描述
一次性的事件处理:
one(eventType[, selector][, data],handler)
执行完一次就自动销毁了

$('p').one('click', function(e) {
    
    
            console.log('clicked p');
        });

移除事件

 <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur assumenda debitis fugiat laboriosam magni modi sequi, sint ullam! Ad consequatur cum excepturi modi nam quos. Dolor est laudantium minima ratione.</p>
var clicked2 = function(e) {
    
    
            console.log('clicked2');
        };

        $('p').on('click', function(e) {
    
    
            console.log('clicked');
        }).on('click', clicked2).on('mouseover', function(e) {
    
    
            console.log('mouseover');
        });

                $('p').off('click')//如果换成下面的,则会移除指定的
                $('p').off('click', clicked2)
    });

off事件不管你绑定了多少click事件,都会移除所有的click事件。

当然也可以移除指定的事件。

如果想移除多个不同事件,可以用下面的方法,加空格或者啥也不传

$('p').off('click mouseover')
$('p').off()

事件实例对象

在这里插入图片描述
在这里插入图片描述
这些红色的属性是有浏览器兼容问题的,而且jQuery对这些属性做了兼容性处理

在这里插入图片描述
stopPropagation()只阻止了本身及后续事件的冒泡,而stopImmediatePropagation()除了阻止冒泡以外,还阻止了后续的事件执行。
后3个就是检测前面的方法有没有调用,调用了返回true。

$(function() {
    
    
        $('div').on('click', function(e) {
    
    
            console.log('clicked: %o', $(this));
        });
        $('p').on('click', function(e) {
    
    
            e.stopPropagation();
            console.log('clicked1: p');
            console.log(e.isPropagationStopped());
        });
        $('p').on('click', function(e) {
    
    
            console.log('clicked2: p');
        });
    });

触发事件

trigger(eventType[, data])
triggerHandler(eventType[, data])
在这里插入图片描述

<body>
    <ul>
        <li class="item1">新闻标题-1</li>
        <li class="item2">新闻标题-2</li>
        <li class="item3">新闻标题-3</li>
        <li class="item4">新闻标题-4</li>
        <li class="item5">新闻标题-5</li>
        <li class="item6">新闻标题-6</li>
        <li class="item7">新闻标题-7</li>
        <li class="item8">新闻标题-8</li>
        <li class="item9">新闻标题-9</li>
    </ul>
    <button id="all">全部标记为已读</button>
    <script src="../../../vendor/jquery-1.12.4.js"></script>
    <script>
    $(function() {
     
     
        $('li').on('click', function(e, arg1, arg2) {
     
     
            console.log('%o 已读', $(this));
            console.log(arg1);
            console.log(arg2);
            return $(this);
        });

        $('#all').on('click', function() {
     
     
            console.log($('li').trigger('click', [1, 2]));//如果没有后面的数组,则都会触发,加上数组[1,2],其实这是传入的数据。
            console.log($('li').triggerHandler('click'));//只会触发第一个
        });
    });
    </script>
</body>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上面的就修改为:

$(function() {
    
    
        $('li').click(function(e) {
    
    
            console.log('%o 已读', $(this));
        });
        $('#all').on('click', function() {
    
    
            console.log($('li').click());
        });
    });

hover方法

弥补onmouseover()和onmouseout()的不足
例如下面的代码,当移入outer1时触发mouseover,但当移入outer1里面的inner1时却触发了outer1的mouseout,然后触发inner1的mouseover。这就不符合我们的认识了。

<head>
    <meta charset="UTF-8">
    <title>demo</title>
    <style>
    .outer {
     
     
        width: 200px;
        height: 200px;
        padding: 20px;
        color: #fff;
        background-color: green;
    }
    
    .inner {
     
     
        width: 100px;
        height: 100px;
        margin: 30px auto;
        padding: 20px;
        color: #fff;
        background-color: orange;
    }
    
    #outer2 {
     
     
        margin-top: 50px;
    }
    </style>
</head>

<body>
    <div class="outer" id="outer1">
        Outer 1
        <div class="inner" id="inner1">Inner 1</div>
    </div>
    <div class="outer" id="outer2">
        Outer 2
        <div class="inner" id="inner2">Inner 2</div>
    </div>
    <script src="../../../vendor/jquery-1.12.4.js"></script>
    <script>
    $(function() {
     
     
        function report(event) {
     
     
            event.stopPropagation();
            console.log(event.type + ' on ' + event.target.id);
        }

        $('#outer1').on('mouseover mouseout', report);
        $('#inner1').on('mouseover mouseout', report);
        //下面的就不会触发了
        $('#outer2').hover(report);
        $('#inner2').hover(report);
    });
    </script>
</body>

jQuery就是提供这两种来解决:
hover(enterHandler,leaveHandler)
hover(handler)

自定义事件

监听器模式和观察者模式
在这里插入图片描述

$(function() {
    
    

        $('li').on('markAsRead', function(e) {
    
    
            console.log('%o 已读', $(this));
        });

        $('li').on('click', function(e) {
    
    
            $(this).trigger('markAsRead');
        });

        $('#all').on('click', function() {
    
    
            $('li').trigger('markAsRead');
        });
    });

事件命名空间

eventName.namespace

<body>
    <ul>
        <li class="item1">新闻标题-1</li>
        <li class="item2">新闻标题-2</li>
        <li class="item3">新闻标题-3</li>
        <li class="item4">新闻标题-4</li>
        <li class="item5">新闻标题-5</li>
        <li class="item6">新闻标题-6</li>
        <li class="item7">新闻标题-7</li>
        <li class="item8">新闻标题-8</li>
        <li class="item9">新闻标题-9</li>
    </ul>
    <button id="even">点击偶数</button>
    <button id="odd">点击奇数</button>
    <button id="all">全部点击</button>
    <script src="../../../vendor/jquery-1.12.4.js"></script>
    <script>
    $(function() {
     
     

        $('li:odd').on('click.even', function(e) {
     
     
            console.log('%o 偶数', $(this));
        });//奇数为什么写偶数呢,因为从0开始计数

        $('li').eq(0).on('click.even.0', function(e) {
     
     
            console.log('%o 0', $(this));
        });

        $('li:even').on('click.odd', function(e) {
     
     
            console.log('%o 奇数', $(this));
        });

        $('#even').on('click', function() {
     
     
            $('li').trigger('click.even');
        });

        $('#odd').on('click', function() {
     
     
            $('li').trigger('click.odd');
        });

        $('#all').on('click', function() {
     
     
            //            $('li').trigger('click');
            $('li').trigger('click.even.0');
        });

        //        $('li').off('.even')
    });
    </script>
</body>

命名空间作用:除了触发even,还会触发带有even的子的命名空间触发

//去除even事件:
$('li').off('.even')
//去除所有事件:
$('li').off()

在这里插入图片描述
一词:puppet 傀儡,木偶
NEXT:
jQuery插件的使用和编写,交互效果来吧!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44682019/article/details/109012301
今日推荐