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 相关文章推荐
看了就知道什么是JSON
Dec 09 Javascript
学习ExtJS border布局
Oct 08 Javascript
Tips 带三角可关闭的文字提示
Oct 06 Javascript
分享9点个人认为比较重要的javascript 编程技巧
Apr 27 Javascript
JavaScript编写推箱子游戏
Jul 07 Javascript
搞定immutable.js详细说明
May 02 Javascript
js注入 黑客之路必备!
Sep 14 Javascript
vue实现动态数据绑定
Apr 28 Javascript
JavaScript实现各种排序的代码详解
Aug 28 Javascript
jQuery中将json数据显示到页面表格的方法
May 27 jQuery
Vue.js的动态组件模板的实现
Nov 26 Javascript
Javascript类型判断相关例题及解析
Aug 26 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开发需要注意的安全问题
2010/09/01 PHP
php发送post请求的三种方法
2014/02/11 PHP
ThinkPHP3.1数据CURD操作快速入门
2014/06/19 PHP
php实现专业获取网站SEO信息类实例
2015/04/02 PHP
Yii CDBCriteria常用方法实例小结
2017/01/19 PHP
php面向对象程序设计中self与static的区别分析
2019/05/21 PHP
Laravel框架自定义分页样式操作示例
2020/01/26 PHP
Mozilla中显示textarea中选择的文字
2006/09/07 Javascript
用Javascript实现锚点(Anchor)间平滑跳转
2009/09/08 Javascript
js页面跳转的常用方法整理
2013/10/18 Javascript
jquery放大镜效果超漂亮噢
2013/11/15 Javascript
javascript时间函数大全
2014/06/30 Javascript
jQuery插件zepto.js简单实现tab切换
2015/06/16 Javascript
jquery实现从数组移除指定的值
2015/06/24 Javascript
AngularJS中的表单简单入门
2016/07/28 Javascript
Jquery Easyui分割按钮组件SplitButton使用详解(17)
2016/12/18 Javascript
easyui-datagrid特殊字符不能显示的处理方法
2017/04/12 Javascript
浅谈Vuejs Prop基本用法
2017/08/17 Javascript
使用Vue.js和Element-UI做一个简单登录页面的实例
2018/02/23 Javascript
vue项目webpack中Npm传递参数配置不同域名接口
2018/06/15 Javascript
微信小程序文章详情页面实现代码
2018/09/10 Javascript
Node.js实现简单的爬取的示例代码
2019/06/25 Javascript
[05:35]DOTA2英雄梦之声_第13期_拉比克
2014/06/21 DOTA
Python中的ceil()方法使用教程
2015/05/14 Python
python实现自动登录人人网并采集信息的方法
2015/06/28 Python
pytorch打印网络结构的实例
2019/08/19 Python
如何基于python测量代码运行时间
2019/12/25 Python
Python中过滤字符串列表的方法
2020/12/22 Python
html5 postMessage前端跨域并前端监听的方法示例
2018/11/01 HTML / CSS
芬兰设计商店美国:Finnish Design Shop US
2019/03/25 全球购物
商务英语专业求职信
2014/06/26 职场文书
2014年党员整改措施
2014/10/24 职场文书
保姆聘用合同
2015/09/21 职场文书
html5 录制mp3音频支持采样率和比特率设置
2021/07/15 Javascript
详细介绍Java中的CyclicBarrier
2022/04/13 Java/Android
Golang日志包的使用
2022/04/20 Golang