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类属性的访问方式详解
Feb 11 Javascript
JavaScript仿静态分页实现方法
Aug 04 Javascript
AngularJS中如何使用echart插件示例详解
Oct 26 Javascript
Javascript中字符串相关常用的使用方法总结
Mar 13 Javascript
基于vue2的table分页组件实现方法
Mar 20 Javascript
CodeMirror js代码加亮使用总结
Mar 25 Javascript
Node.js引入UIBootstrap的方法示例
May 11 Javascript
详解ECMAScript typeof用法
Jul 25 Javascript
JavaScript canvas基于数组生成柱状图代码实例
Mar 06 Javascript
微信小程序仿抖音视频之整屏上下切换功能的实现代码
May 24 Javascript
js操作两个json数组合并、去重,以及删除某一项元素
Sep 22 Javascript
Vue实现下拉加载更多
May 09 Vue.js
使用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使用curl获取https请求的方法
2015/02/11 PHP
PHP框架自动加载类文件原理详解
2017/06/06 PHP
PhpStorm的使用教程(本地运行PHP+远程开发+快捷键)
2020/03/26 PHP
laravel与thinkphp之间的区别与优缺点
2021/03/02 PHP
Javascript公共脚本库系列(一): 弹出层脚本
2011/02/24 Javascript
table insertRow、deleteRow定义和用法总结
2014/05/14 Javascript
多个checkbox被选中时如何判断是否有自己想要的
2014/09/22 Javascript
jQuery判断当前点击的是第几个li的代码
2014/09/26 Javascript
JavaScript对数字的判断与处理实例分析
2015/02/02 Javascript
jQuery搜索子元素的方法
2015/02/10 Javascript
javascript使用Promise对象实现异步编程
2016/03/01 Javascript
Jq通过td获取同行其它列td的方法
2016/10/05 Javascript
animate.css在vue项目中的使用教程
2018/08/05 Javascript
解决vue中使用Axios调用接口时出现的ie数据处理问题
2018/08/13 Javascript
vue 监听屏幕高度的实例
2018/09/05 Javascript
electron实现qq快捷登录的方法示例
2018/10/22 Javascript
详解无限滚动插件vue-infinite-scroll源码解析
2019/05/12 Javascript
npm的lock机制解析
2019/06/20 Javascript
分析Python读取文件时的路径问题
2018/02/11 Python
Python 实现引用其他.py文件中的类和类的方法
2018/04/29 Python
python如何制作英文字典
2019/06/25 Python
python 3.7.4 安装 opencv的教程
2019/10/10 Python
python GUI库图形界面开发之PyQt5信号与槽机制、自定义信号基础介绍
2020/02/25 Python
css3模拟jq点击事件的实例代码
2017/07/06 HTML / CSS
CSS3实现彩色进度条动画的示例
2020/10/29 HTML / CSS
瑞典灯具和照明网上商店:Lamp24.se
2018/03/17 全球购物
如何防止同一个帐户被多人同时登录
2013/08/01 面试题
商务专员岗位职责
2013/11/23 职场文书
大学生的网络创业计划书
2013/12/26 职场文书
大学军训感言300字
2014/03/09 职场文书
淘宝客服专员岗位职责
2014/04/11 职场文书
甲乙双方合作协议书
2014/10/13 职场文书
自我检讨报告
2015/01/28 职场文书
财务部岗位职责范本
2015/04/14 职场文书
python中subplot大小的设置步骤
2021/06/28 Python
Java使用HttpClient实现文件下载
2022/08/14 Java/Android