jQuery的观察者模式详解


Posted in Javascript onDecember 22, 2014

在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>

jQuery的观察者模式详解 

如果用一个全局变量来接收异步获取的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>

jQuery的观察者模式详解

这次,我们得到的结果却是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>

jQuery的观察者模式详解

以上,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>

jQuery的观察者模式详解

以上,定义了全局的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

                );

            });

        });

jQuery的观察者模式详解

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

Javascript 相关文章推荐
JavaScript三元运算符的多种使用技巧
Apr 16 Javascript
js全选按钮的实现方法
Nov 17 Javascript
AngularJS表单和输入验证实例
Nov 02 Javascript
详解Angular路由之路由守卫
May 10 Javascript
node前端开发模板引擎Jade的入门
May 11 Javascript
解决vue点击控制单个样式的问题
Sep 05 Javascript
详解vue中localStorage的使用方法
Nov 22 Javascript
jquery.tagsinput.js实现记录checkbox勾选的顺序
Sep 21 jQuery
vue 路由懒加载中给 Webpack Chunks 命名的方法
Apr 24 Javascript
Element Popover 弹出框的使用示例
Jul 26 Javascript
js canvas实现俄罗斯方块
Oct 11 Javascript
解决vue props传Array/Object类型值,子组件报错的情况
Nov 07 Javascript
使用jQuery和Bootstrap实现多层、自适应模态窗口
Dec 22 #Javascript
sails框架的学习指南
Dec 22 #Javascript
了不起的node.js读书笔记之mongodb数据库交互
Dec 22 #Javascript
javascript动态创建及删除元素的方法
Dec 22 #Javascript
了不起的node.js读书笔记之例程分析
Dec 22 #Javascript
了不起的node.js读书笔记之node的学习总结
Dec 22 #Javascript
了不起的node.js读书笔记之node.js中的特性
Dec 22 #Javascript
You might like
php中记录用户访问过的产品,在cookie记录产品id,id取得产品信息
2011/05/04 PHP
php中常用的预定义变量小结
2012/05/09 PHP
PHP中基于ts与nts版本- vc6和vc9编译版本的区别详解
2013/04/26 PHP
浅谈PHP发送HTTP请求的几种方式
2017/07/25 PHP
PHP实现的防止跨站和xss攻击代码【来自阿里云】
2018/01/29 PHP
Javascript miscellanea -display data real time, using window.status
2007/01/09 Javascript
Extjs Ajax 乱码问题解决方案
2009/04/15 Javascript
js文本框输入点回车触发确定兼容IE、FF等
2013/11/19 Javascript
上传文件返回的json数据会被提示下载问题解决方案
2014/12/03 Javascript
Node.js中的流(Stream)介绍
2015/03/30 Javascript
JavaScript返回当前会话cookie全部键值对照的方法
2015/04/03 Javascript
jQuery的事件委托实例分析
2015/07/15 Javascript
js实现(全选)多选按钮的方法【附实例】
2016/03/30 Javascript
用最简单的方法判断JavaScript中this的指向(推荐)
2017/09/04 Javascript
js原生方法被覆盖,从新赋值原生的方法
2018/01/02 Javascript
jQuery 防止相同的事件快速重复触发方法
2018/02/08 jQuery
Vue2.X 通过AJAX动态更新数据
2018/07/17 Javascript
通过cordova将vue项目打包为webapp的方法
2019/02/02 Javascript
layer.prompt输入层的例子
2019/09/24 Javascript
如何正确理解vue中的key详解
2019/11/02 Javascript
vue中路由跳转不计入history的操作
2020/09/21 Javascript
解决vue项目打包上服务器显示404错误,本地没出错的问题
2020/11/03 Javascript
[02:12]DOTA2英雄基础教程 变体精灵
2013/12/16 DOTA
Python实现获取操作系统版本信息方法
2015/04/08 Python
python实现百万答题自动百度搜索答案
2018/01/16 Python
python中for循环变量作用域及用法详解
2019/11/05 Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
2020/02/10 Python
会计学财务管理专业个人的自我评价
2013/10/19 职场文书
2014年中班元旦活动方案
2014/02/14 职场文书
课前三分钟演讲稿
2014/04/24 职场文书
团日活动总结
2014/04/28 职场文书
社团活动总结书
2014/06/27 职场文书
小学语文继续教育研修日志
2015/11/13 职场文书
CSS3实现三角形不断放大效果
2021/04/13 HTML / CSS
html+css实现环绕倒影加载特效
2021/07/07 HTML / CSS
10大幻兽系恶魔果实 蝙蝠果实上榜,第一自愈能力强
2022/03/18 日漫