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 相关文章推荐
js中Image对象以及对其预加载处理示例
Nov 20 Javascript
javascript面向对象特性代码实例
Jun 12 Javascript
jQuery实现带滚动线条导航效果的方法
Jan 30 Javascript
js代码实现点击按钮出现60秒倒计时
Jan 28 Javascript
用JS实现轮播图效果(二)
Jun 26 Javascript
详解基于webpack和vue.js搭建开发环境
Apr 05 Javascript
Node.JS更改Windows注册表Regedit的方法小结
Aug 18 Javascript
用JavaScript做简易的购物车的代码示例
Oct 20 Javascript
vue一个页面实现音乐播放器的示例
Feb 06 Javascript
jQuery实现模糊搜索功能的方法分析
Jun 29 jQuery
深入理解JavaScript 中的匿名函数((function() {})();)与变量的作用域
Aug 28 Javascript
小程序scroll-view安卓机隐藏横向滚动条的实现详解
May 16 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介绍篇
2010/10/26 PHP
定义php常量的详解
2013/06/09 PHP
php读取富文本的时p标签会出现红线是怎么回事
2014/05/13 PHP
php正则匹配html中带class的div并选取其中内容的方法
2015/01/13 PHP
PHP7.1实现的AES与RSA加密操作示例
2018/06/15 PHP
Jquery拖拽并简单保存的实现代码
2010/11/28 Javascript
javascript内存管理详细解析
2013/11/11 Javascript
简单选项卡 js和jquery制作方法分享
2014/02/26 Javascript
jQuery插件实现适用于移动端的地址选择器
2016/02/18 Javascript
基于JS如何实现给字符加千分符(65,541,694,158)
2016/08/03 Javascript
轻松实现js选项卡切换效果
2016/09/24 Javascript
vue数据双向绑定原理解析(get &amp; set)
2017/03/08 Javascript
javascript  删除select中的所有option的实例
2017/09/17 Javascript
jQuery 实现倒计时天,时,分,秒功能
2018/07/31 jQuery
深入探讨JavaScript的最基本部分之执行上下文
2019/02/12 Javascript
js实现弹出框的拖拽效果实例代码详解
2019/04/16 Javascript
基于JavaScript实现十五拼图代码实例
2020/04/26 Javascript
Flexible.js可伸缩布局实现方法详解
2020/11/13 Javascript
python利用OpenCV2实现人脸检测
2020/04/16 Python
Python实现多条件筛选目标数据功能【测试可用】
2018/06/13 Python
python3.6根据m3u8下载mp4视频
2019/06/17 Python
Python学习笔记之Break和Continue用法分析
2019/08/14 Python
Windows+Anaconda3+PyTorch+PyCharm的安装教程图文详解
2020/04/03 Python
Python接口测试结果集实现封装比较
2020/05/01 Python
PyCharm 2020.2下配置Anaconda环境的方法步骤
2020/09/23 Python
python日志通过不同的等级打印不同的颜色(示例代码)
2021/01/13 Python
致标枪运动员广播稿
2014/02/06 职场文书
安全承诺书格式
2014/05/21 职场文书
销售类求职信
2014/06/13 职场文书
幼儿园八一建军节活动方案
2014/08/27 职场文书
2014年民政局关于保密工作整改措施
2014/09/19 职场文书
中秋节随笔
2015/08/15 职场文书
《落花生》教学反思
2016/02/16 职场文书
SQL注入详解及防范方法
2021/12/06 MySQL
使用python求解迷宫问题的三种实现方法
2022/03/17 Python