菜单

jQuery的观看者形式详解,jquery观察者详解

2019年7月31日 - 2020欧洲杯冠军竞猜

// 在最后一个标签上触发 “假” 的事件
jQuery(‘.tabs a’).last().trigger(‘tabs-click’);

jQuery的观察者模式详解,jquery观察者详解

在jQuery中,on方法可以为元素绑定事件,trigger方法可以手动触发事件,围绕这2个方法,我们来体验jQuery中的观察者模式(Observer
Pattern)。

■ on方法绑定内置事件,自然触发

比如,我们给页面的body元素绑定一个click事件,这样写。

复制代码 代码如下:

 <head>
<meta http-equiv=”Content-Type” content=”text/html;
charset=utf-8″/>
    <title></title>
    <script src=”Scripts/jquery-2.1.1.min.js”></script>
    <script type=”text/javascript”>
        $(function() {
            $(‘body’).on(‘click’, function () {
                console.log(‘被点击了~~’);
            });
        });     
    </script>
</head>
<body>
    <h1>hello</h1>
</body>

以上,我们只有点击body,才能触发click事件。也就是说,当给页面元素绑定内置事件后,事件的触发是在内置事件发生的那刻。

■ on方法绑定内置事件,手动触发

使用trigger方法,也可以手动触发元素绑定的内置事件。

     <script src=”Scripts/jquery-2.1.1.min.js”></script>
    <script type=”text/javascript”>
        $(function() {
            $(‘body’).on(‘click’, function () {
                console.log(‘被点击了~~’);
            });
            $(‘body’).trigger(‘click’);
        });     
    </script>
以上,无需点击body,在页面加载完毕,body自动触发了click事件。

■ on方法绑定自定义事件,手动触发

我们知道,click是jquery内置的事件,那么,是否可以自定义事件,并手动触发呢?

复制代码 代码如下:

    <script src=”Scripts/jquery-2.1.1.min.js”></script>
    <script type=”text/javascript”>
        $(function() {
            $(‘body’).on(‘someclick’, function () {
                console.log(‘被点击了~~’);
            });
            $(‘body’).trigger(‘someclick’);
        });     
    </script>

以上,我们自定义了一个someclick事件,得到的结果和上面一样。

于是,我们发现:我们可以为元素绑定自定义事件,并且用trigger方法触发该事件。

当然,自定义事件的名称可以按照”命名空间.自定义事件名称”的形式来写,比如app.someclick,这在大型项目中尤其有用,这样可以有效避免自定义事件名称冲突。

如果从”发布订阅”这个角度来看,on方法相当于订阅者、观察者,trigger方法相当于发布者。

■ 从”异步获取json数据”来体验jQuery观察者模式

在根目录下,有一个data.json的文件。

{
    “one” : “Hello”,
    “two” : “World”
}
现在,通过异步的方式来获取json数据。

复制代码 代码如下:

    <script src=”Scripts/jquery-2.1.1.min.js”></script>
    <script type=”text/javascript”>
        $(function () {
            $.getJSON(‘data.json’, function(data) {
                console.log(data);
            });
        });     
    </script>

图片 1 

如果用一个全局变量来接收异步获取的json数据。

复制代码 代码如下:

    <script src=”Scripts/jquery-2.1.1.min.js”></script>
    <script type=”text/javascript”>
        $(function () {
            var data;
            $.getJSON(‘data.json’, function(results) {
                data = results;
            });
            console.log(data);
        });     
    </script>

图片 2

这次,我们得到的结果却是undefined,这是为什么?
–因为,当$.getJSON方法还在获取数据的时候,就已经执行console.log(data),而此时data还没有数据。

如何解决这个问题呢?
–如果在$.getJSON方法之外先定义好需要执行的方法,然后在$.getJSON方法的回调函数里真正触发这个方法,不就解决了吗?

复制代码 代码如下:

    <script src=”Scripts/jquery-2.1.1.min.js”></script>
    <script type=”text/javascript”>
        $(function () {
            $.getJSON(‘data.json’, function(results) {
                $(document).trigger(‘app.myevent’, results);
//相当于发布
            });
            $(document).on(‘app.myevent’, function(e, results) {
//相当于订阅
                console.log(results);
            });
        });     
    </script>

图片 3

以上,on方法就像一个订阅者,它订阅了自定义事件app.myevent;而trigger方法就像一个发布者,它发布事件和参数后,才真正让订阅者方法得以执行。

■ jQuery观察者模式的扩展方法

为此,我们还可以为jQuery观察者模式专门写一个扩展方法。

复制代码 代码如下:

    <script src=”Scripts/jquery-2.1.1.min.js”></script>
    <script type=”text/javascript”>
        $(function () {
            $.getJSON(‘data.json’, function (results) {
                $.publish(‘app.myevent’, results);
            });
            $.subscribe(‘app.myevent’, function(e, results) {
                console.log(results);
            });
        });
        (function($) {
            var o = $({});//自定义事件对象
            $.each({
                trigger: ‘publish’,
                on: ‘subscribe’,
                off: ‘unsubscribe’
            }, function(key, val) {
                jQuery[val] = function() {
                    o[key].apply(o, arguments);
                };
            });
        })(jQuery);
    </script>

图片 4

以上,定义了全局的publish和subscribe方法,我们在任何时候都可以调用。

复制代码 代码如下:

    <script src=”Scripts/jquery-2.1.1.min.js”></script>
    <script type=”text/javascript”>
        $(function () {
            $.getJSON(‘data.json’, function (results) {
                $.publish(‘app.myevent’, results);
            });
            $.subscribe(‘app.myevent’, function(e, results) {
                $(‘body’).html(
                    results.one
                );
            });
        });

图片 5

总结:jQuery的观察者模式,实际上是让on方法绑定的自定义事件先不执行,直到使用trigger方法来触发事件。使用jQuery的观察者模式的好处是:一次发布,多次订阅。

在jQuery中,on方法可以为元素绑定事件,trigger方法可以手动触发事件,围绕这2个方法,我们来体…

// 监听 click 事件
jQuery(‘.tabs a’).on(‘click’, function() {
// 执行某些操作,比如切换界面,加载内容等..
});

上面的代码将会打开给定index的tab标签。 我完全理解开发者使用 trigger
来处理这些事情的原因,通常是因为要触发的函数在全局范围内不可用,而触发事件是很容易的,也总是可用的。
问题是,使用原生的事件名称来触发可能 … 触发 …
一些无法言说的伤。让我们来看看在网站的其他地方添加的内容:

// 监听 body 内部的所有 click 事件
jQuery(‘body’).on(‘click’, ‘a’, function() {
// 此处可以进行一些业务逻辑处理 …

// 在最后一个 a 标签上触发 click 事件
jQuery(‘.tabs a’).last().trigger(‘click’);

复制代码 代码如下:

JavaScript 框架提供了如此多的功能,以至于一不小心就会掉进坑里去。
对工具库依赖得越多,在修改或维护时一个小小的改的很可能就会影响到其他的功能(俗称
处处是地雷,走路需谨慎),特别是维护多年前的遗留代码时。
我经常看到的一个错误是关于 jQuery的 trigger,
trigger允许开发者手动触发某些事件。
这个功能真的非常强大与好用,但是请遵守约定,不要触发JS中那些原生的事件名称!
注:我知道,其他JS框架也提供这种功能 ——
我只用jQuery作为一个例子,因为我看到了它的受欢迎程度,最近又刚好碰上这个问题。
而所有工具类库都有可能引发同样的问题。 比如 MooTools使用 的 fireEvent
等。
下面是使用 trigger 来完成任务的一个典型例子:

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图