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 阻止javascript事件冒泡,获取控件ID值
Jun 27 Javascript
用jquery实现的一个超级简单的下拉菜单
May 18 Javascript
基于javascript如何传递特殊字符
Nov 30 Javascript
基于JavaScript操作DOM常用的API小结
Dec 01 Javascript
JS之获取样式的简单实现方法(推荐)
Sep 13 Javascript
ES6入门教程之let和const命令详解
May 17 Javascript
JS实现图片居中悬浮效果
Dec 25 Javascript
前后端如何实现登录token拦截校验详解
Sep 03 Javascript
Node.js中读取TXT文件内容fs.readFile()用法
Oct 10 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
Oct 12 Javascript
基于jquery实现九宫格拼图小游戏
Nov 30 jQuery
在Angular中实现一个级联效果的下拉框的示例代码
May 20 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的内置函数,通过DES算法对数据加密和解密
2012/06/21 PHP
PHP读取大文件的多种方法介绍
2016/04/04 PHP
tp5框架使用composer实现日志记录功能示例
2019/01/10 PHP
php curl简单采集图片生成base64编码(并附curl函数参数说明)
2019/02/15 PHP
FCK调用方法..
2006/12/21 Javascript
js制作的鼠标悬浮时产生的下拉框效果
2012/10/27 Javascript
jQuery中的$.ajax()方法应用
2014/05/06 Javascript
谷歌地图打不开的解决办法
2014/08/07 Javascript
JS控制层作圆周运动的方法
2016/06/20 Javascript
JavaScript中windows.open()、windows.close()方法详解
2016/07/28 Javascript
Bootstrap基本插件学习笔记之模态对话框(16)
2016/12/08 Javascript
jQuery选择器之属性筛选选择器用法详解
2017/09/19 jQuery
JS实现碰撞检测的方法分析
2018/01/19 Javascript
webpack将js打包后的map文件详解
2018/02/22 Javascript
Node.js 实现远程桌面监控的方法步骤
2019/07/02 Javascript
原生javascript自定义input[type=radio]效果示例
2019/08/27 Javascript
JS+CSS实现随机点名(实例代码)
2019/11/04 Javascript
[28:07]完美世界DOTA2联赛PWL S3 Phoenix vs INK ICE 第二场 12.13
2020/12/17 DOTA
决策树的python实现方法
2014/11/18 Python
利用Python实现在同一网络中的本地文件共享方法
2018/06/04 Python
Python面向对象之反射/自省机制实例分析
2018/08/24 Python
Pytorch实现LSTM和GRU示例
2020/01/14 Python
Python sqlalchemy时间戳及密码管理实现代码详解
2020/08/01 Python
如何用用Python将地址标记在地图上
2021/02/07 Python
详解css3中 text-fill-color属性
2019/07/08 HTML / CSS
HTML5新特性之语义化标签
2017/10/31 HTML / CSS
雅诗兰黛澳大利亚官网:Estée Lauder澳大利亚
2019/05/31 全球购物
CSS代码检查工具stylelint的使用方法详解
2021/03/27 HTML / CSS
公务员个人自我评价分享
2013/11/06 职场文书
新员工试用期自我鉴定
2014/04/17 职场文书
医院我们的节日活动实施方案
2014/08/22 职场文书
党的群众路线专项整治方案
2014/11/03 职场文书
销售区域经理岗位职责
2015/04/10 职场文书
图解上海144收音机
2021/04/22 无线电
windows11怎么查看wifi密码? win11查看wifi密码的技巧
2021/11/21 数码科技
在NumPy中深拷贝和浅拷贝相关操作的定义和背后的原理
2022/04/14 Python