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中的五种基本数据类型
Aug 26 Javascript
javascript事件处理模型实例说明
May 31 Javascript
js 判断一组日期是否是连续的简单实例
Jul 11 Javascript
jQuery.datatables.js插件用法及api实例详解
Oct 28 Javascript
Node.js数据库操作之查询MySQL数据库(二)
Mar 04 Javascript
利用JavaScript实现栈的数据结构示例代码
Aug 02 Javascript
Three.js基础学习教程
Nov 16 Javascript
不使用 JS 匿名函数理由
Nov 17 Javascript
node中使用log4js4.x版本记录日志的方法
Aug 20 Javascript
jQuery操作选中select下拉框的值代码实例
Feb 07 jQuery
vue tab切换,解决echartst图表宽度只有100px的问题
Jul 19 Javascript
TS 类型兼容教程示例详解
Sep 23 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 高手之路(一)
2006/10/09 PHP
浅谈php和js中json的编码和解码
2016/10/24 PHP
Laravel 实现在Blade模版中使用全局变量代替路径的例子
2019/10/22 PHP
JavaScript this 深入理解
2009/07/30 Javascript
jquery.validate使用攻略 第五步 正则验证
2010/07/01 Javascript
js兼容火狐获取图片宽和高的方法
2015/05/21 Javascript
javascript数据结构之二叉搜索树实现方法
2015/11/25 Javascript
浅析JavaScript 箭头函数 generator Date JSON
2016/05/23 Javascript
javascript流程控制语句集合
2017/09/18 Javascript
js实现数组和对象的深浅拷贝
2017/09/30 Javascript
浅谈webpack编译vue项目生成的代码探索
2017/12/11 Javascript
Angular5.1新功能分享
2017/12/21 Javascript
Vue中父子组件通讯之todolist组件功能开发
2018/05/21 Javascript
还不懂递归?读完这篇文章保证你会懂
2018/07/29 Javascript
layui实现数据表格隐藏列的示例
2019/10/25 Javascript
Vue中的this.$options.data()和this.$data用法说明
2020/07/26 Javascript
jQuery实现计算器功能
2020/10/19 jQuery
js定时器出现第一次延迟的原因及解决方法
2021/01/04 Javascript
使用python搭建Django应用程序步骤及版本冲突问题解决
2013/11/19 Python
Python 40行代码实现人脸识别功能
2017/04/02 Python
Python随机生成均匀分布在单位圆内的点代码示例
2017/11/13 Python
基于Python List的赋值方法
2018/06/23 Python
Python3.7实现中控考勤机自动连接
2018/08/28 Python
Python通过cv2读取多个USB摄像头
2019/08/28 Python
解决Python安装cryptography报错问题
2020/09/03 Python
Python importlib模块重载使用方法详解
2020/10/13 Python
canvas 如何绘制线段的实现方法
2018/07/12 HTML / CSS
罗马尼亚在线杂货店:Pilulka.ro
2019/09/28 全球购物
牵手50香港:专为黄金岁月的单身人士而设的交友网站
2020/08/14 全球购物
如何启动时不需输入用户名与密码
2014/05/09 面试题
高三家长寄语
2014/04/03 职场文书
2014年营销工作总结
2014/11/22 职场文书
2015年世界环境日演讲稿
2015/03/18 职场文书
2015年纪委工作总结
2015/05/13 职场文书
离婚起诉书范文2015
2015/05/19 职场文书
2019年度开业庆典祝福语大全!
2019/07/05 职场文书