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面向对象编程(一) 实例代码
Jun 25 Javascript
JQUERY对单选框(radio)操作的小例子
Apr 25 Javascript
浅谈javascript面向对象程序设计
Jan 21 Javascript
jquery实现的代替传统checkbox样式插件
Jun 19 Javascript
浅谈JavaScript的push(),pop(),concat()方法
Jun 03 Javascript
卸载安装Node.js与npm过程详解
Aug 15 Javascript
关于JavaScript和jQuery的类型判断详解
Oct 08 Javascript
JS版微信6.0分享接口用法分析
Oct 13 Javascript
原生js实现可爱糖果数字时间特效
Dec 30 Javascript
通过V8源码看一个关于JS数组排序的诡异问题
Aug 14 Javascript
vue使用v-if v-show页面闪烁,div闪现的解决方法
Oct 12 Javascript
JavaScript接口实现方法实例分析
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实现在限定区域里自动调整字体大小的类实例
2015/04/02 PHP
浅谈PHP接收POST数据方式
2015/06/05 PHP
编写PHP脚本使WordPress的主题支持Widget侧边栏
2015/12/14 PHP
PHP实现简单的模板引擎功能示例
2017/09/02 PHP
PHP INT类型在内存中占字节详解
2019/07/20 PHP
Laravel6.2中用于用户登录的新密码确认流程详解
2019/10/16 PHP
关于PHP中interface的用处详解
2020/07/26 PHP
用JavaScript修改CSS属性的代码
2013/05/06 Javascript
使用js实现按钮控制文本框加1减1应用于小时+分钟
2013/12/09 Javascript
上传文件返回的json数据会被提示下载问题解决方案
2014/12/03 Javascript
深入理解JavaScript单体内置对象
2016/06/06 Javascript
echarts3 使用总结(绘制各种图表,地图)
2017/01/05 Javascript
微信小程序开发之麦克风动画 帧动画 放大 淡出
2017/04/18 Javascript
配置nodejs环境的方法
2017/05/13 NodeJs
Vue-router 类似Vuex实现组件化开发的示例
2017/09/15 Javascript
浅析Vue.js 中的条件渲染指令
2018/11/19 Javascript
vue中引入第三方字体文件的方法示例
2018/12/17 Javascript
利用Electron简单撸一个Markdown编辑器的方法
2019/06/10 Javascript
[51:39]DOTA2-DPC中国联赛 正赛 Magma vs LBZS BO3 第二场 2月7日
2021/03/11 DOTA
python采用getopt解析命令行输入参数实例
2014/09/30 Python
Python实现Linux的find命令实例分享
2017/06/04 Python
Python实现ping指定IP的示例
2018/06/04 Python
Python爬取qq空间说说的实例代码
2018/08/17 Python
解决使用PyCharm时无法启动控制台的问题
2019/01/19 Python
python 通过SSHTunnelForwarder隧道连接redis的方法
2019/02/19 Python
实例详解Python模块decimal
2019/06/26 Python
如何定义TensorFlow输入节点
2020/01/23 Python
TensorFlow2.X结合OpenCV 实现手势识别功能
2020/04/08 Python
python opencv把一张图片嵌入(叠加)到另一张图片上的实现代码
2020/06/11 Python
html5组织文档结构_动力节点Java学院整理
2017/07/11 HTML / CSS
可爱的童装和鞋子:Fabkids
2019/08/16 全球购物
餐厅执行经理岗位职责范本
2014/02/26 职场文书
酒店节能降耗方案
2014/05/08 职场文书
师德承诺书
2015/01/20 职场文书
三峡大坝导游词
2015/01/31 职场文书
毕业生个人总结
2015/02/28 职场文书