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 相关文章推荐
LazyLoad 延迟加载(按需加载)
May 31 Javascript
加载远程图片时,经常因为缓存而得不到更新的解决方法(分享)
Jun 26 Javascript
javaScript中的this示例学习详解及工作原理
Jan 13 Javascript
javascript中hasOwnProperty() 方法使用指南
Mar 09 Javascript
简易的投票系统以及js刷票思路和方法
Apr 07 Javascript
基于PHP和Mysql相结合使用jqGrid读取数据并显示
Dec 02 Javascript
javascript实现任务栏消息提示的简单实例
May 31 Javascript
js与jquery正则验证电子邮箱、手机号、邮政编码的方法
Jul 04 Javascript
VUE动态生成word的实现
Jul 26 Javascript
vue-列表下详情的展开与折叠案例
Jul 28 Javascript
vue离开当前页面触发的函数代码
Sep 01 Javascript
vue中的计算属性和侦听属性
Nov 06 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
大师制作的中短波矿石收音机
2020/04/02 无线电
php preg_match_all结合str_replace替换内容中所有img
2008/10/11 PHP
php操作csv文件代码实例汇总
2014/09/22 PHP
php实现中文转数字
2016/02/18 PHP
CentOS下搭建PHP环境与WordPress博客程序的全流程总结
2016/05/07 PHP
Yii2选项卡的简单使用
2017/05/26 PHP
jQuery在IE下使用未闭合的xml代码创建元素时的Bug介绍
2012/01/10 Javascript
jQuery语法总结和注意事项小结
2012/11/11 Javascript
jQery使网页在显示器上居中显示适用于任何分辨率
2014/06/09 Javascript
jQuery修改CSS伪元素属性的方法
2014/07/30 Javascript
整理Javascript函数学习笔记
2015/12/01 Javascript
jQuery事件绑定用法详解(附bind和live的区别)
2016/01/19 Javascript
JS组件Bootstrap ContextMenu右键菜单使用方法
2016/04/17 Javascript
深入剖析javascript中的exec与match方法
2016/05/18 Javascript
使用nodejs爬取前程无忧前端技能排行
2017/05/06 NodeJs
elemetUi 组件--el-upload实现上传Excel文件的实例
2017/10/27 Javascript
JS伪继承prototype实现方法示例
2018/06/20 Javascript
javascript实现电商放大镜效果
2020/11/23 Javascript
如何使用python爬取csdn博客访问量
2016/02/14 Python
Python序列操作之进阶篇
2016/12/08 Python
Python实现通讯录功能
2018/02/22 Python
Python开发网站目录扫描器的实现
2019/02/21 Python
Django model update的多种用法介绍
2020/03/28 Python
python SVM 线性分类模型的实现
2019/07/19 Python
使用python动态生成波形曲线的实现
2019/12/04 Python
基于Python测试程序是否有错误
2020/05/16 Python
Python爬虫入门教程01之爬取豆瓣Top电影
2021/01/24 Python
CSS3 Backgrounds属性相关介绍
2011/05/11 HTML / CSS
八年级生物教学反思
2014/01/22 职场文书
2015年六一儿童节演讲稿
2015/03/19 职场文书
电影圆明园观后感
2015/06/03 职场文书
CSS实现漂亮的时钟动画效果的实例代码
2021/03/30 HTML / CSS
MySQL sql_mode修改不生效的原因及解决
2021/05/07 MySQL
springboot @ConfigurationProperties和@PropertySource的区别
2021/06/11 Java/Android
Python学习之os包使用教程详解
2022/03/21 Python
吉利入股戴姆勒后smart“长大了”
2022/04/21 数码科技