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 相关文章推荐
jQuery EasyUI API 中文文档 - NumberSpinner数值微调器使用介绍
Oct 21 Javascript
js实现获取div坐标的方法
Nov 16 Javascript
jQuery ajax提交Form表单实例(附demo源码)
Apr 06 Javascript
项目实践一图片上传之form表单还是base64前端图片压缩(前端图片压缩)
Jul 28 Javascript
AngularJS入门教程之双向绑定详解
Aug 18 Javascript
js控制文本框禁止输入特殊字符详解
Apr 07 Javascript
详解AngularJS脏检查机制及$timeout的妙用
Jun 19 Javascript
jQuery选择器之属性筛选选择器用法详解
Sep 19 jQuery
JavaScript实现QQ列表展开收缩扩展功能
Oct 30 Javascript
微信小程序实现顶部下拉菜单栏
Nov 04 Javascript
vue 集成 vis-network 实现网络拓扑图的方法
Aug 07 Javascript
layui框架与SSM前后台交互的方法
Sep 12 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 转义使用详解
2013/07/15 PHP
php调整gif动画图片尺寸示例代码分享
2013/12/05 PHP
PHP统计nginx访问日志中的搜索引擎抓取404链接页面路径
2014/06/30 PHP
php过滤表单提交的html等危险代码
2014/11/03 PHP
thinkPHP5.0框架整体架构总览【应用,模块,MVC,驱动,行为,命名空间等】
2017/03/25 PHP
php检查函数必传参数是否存在的实例详解
2017/08/28 PHP
php PDO属性设置与操作方法分析
2018/12/27 PHP
可缩放Reloaded-一个针对可缩放元素的复用组件
2007/03/10 Javascript
国外Lightbox v2.03.3 最新版 下载
2007/10/17 Javascript
Javascript hasOwnProperty 方法 &amp; in 关键字
2008/11/26 Javascript
一个用javascript写的select支持上下键、首字母筛选以及回车取值的功能
2009/09/09 Javascript
基于jquery实现一张图片点击鼠标放大再点缩小
2013/09/29 Javascript
JS判断移动端访问设备并加载对应CSS样式
2014/06/13 Javascript
2014 年最热门的21款JavaScript框架推荐
2014/12/25 Javascript
仅一个form表单 js实现注册信息依次填写提交功能
2016/06/12 Javascript
jQuery Easyui datagrid editor为combobox时指定数据源实例
2016/12/19 Javascript
微信小程序使用image组件显示图片的方法【附源码下载】
2017/12/08 Javascript
浅谈Webpack打包优化技巧
2018/06/12 Javascript
关于vue状态过渡transition不起作用的原因解决
2019/04/09 Javascript
vue操作dom元素的3种方法示例
2020/09/20 Javascript
Python常用库推荐
2016/12/04 Python
Python利用itchat对微信中好友数据实现简单分析的方法
2017/11/21 Python
Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容
2018/02/23 Python
Python openpyxl 遍历所有sheet 查找特定字符串的方法
2018/12/10 Python
在python中pandas读文件,有中文字符的方法
2018/12/12 Python
python实现对输入的密文加密
2019/03/20 Python
使用Python将字符串转换为格式化的日期时间字符串
2019/09/01 Python
python能自学吗
2020/06/18 Python
利用CSS3的transition属性实现滑动效果
2015/08/05 HTML / CSS
澳大利亚领先的皮肤诊所:Skin Matrix(抗衰老、痤疮专家、药妆护肤)
2018/05/20 全球购物
英国领先的野生鸟类食品供应商:GardenBird
2018/08/09 全球购物
编写strcpy函数
2014/06/24 面试题
下列程序在32位linux或unix中的结果是什么
2015/01/26 面试题
中科软测试工程师面试题
2012/06/16 面试题
客服服务心得体会
2013/12/30 职场文书
学习十八大标语
2014/10/09 职场文书