基于 jQuery 的发布订阅模式实战

imPony 发布于:2017-11-16 14:52:21

前言


很多人学习 Javascript 或者其它语言到了一定阶段的时候,会感到很苦恼,感觉提起什么自己都会,但是代码质量始终上不去,在做一些大项目的时候尤为明显,尽管可以完成功能,但是代码质量不堪一击,更不要提什么扩展性。

到了这个阶段,你可能需要学习一下设计模式了。



什么是设计模式


“设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。...为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化…”

https://baike.baidu.com/item/设计模式/1212549



发布订阅模式要点

image.png

(本图来源于互联网)


  1. 设计模式的一种

  2. 理解 Javascript 事件驱动机制(《Javascript高级程序设计(第三版)》第 616 页:自定义事件)

  3. 可以用“滴滴打车”场景来理解这个模式,“订阅者”就是乘客,“发布者”就是出租车司机,“调度中心”就是滴滴公司,“自定义事件”就是打车




实战


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
<title>基于 jQuery 的发布订阅模式实战</title>
<style>
html, body, h1, h3, h4 { margin: 0; padding: 0; }
body, button { font: 42px/1.5 sans-serif; outline: none; }
.wp { display: flex; padding: 30px; }
    .side { width: 350px; }
    .main { flex: 1; padding-right: 30px; }
    fieldset { margin: 30px 0; }
        button { margin: 0 30px; padding: 0 30px; background: #09c; color: #fff; }
            button[class="js_btn_followed"] { background: #eee; color: #000;  }
    li:nth-child(2n) { color: red; }
</style>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<script>
/*
 * jQuery Tiny Pub/Sub
 * https://github.com/cowboy/jquery-tiny-pubsub
 *
 * Copyright (c) 2013 "Cowboy" Ben Alman
 * Licensed under the MIT license.
 */

(function($) {

    var o = $({});

    $.subscribe = function() {
        o.on.apply(o, arguments);
    };

    $.unsubscribe = function() {
        o.off.apply(o, arguments);
    };

    $.publish = function() {
        o.trigger.apply(o, arguments);
    };

}(jQuery));
</script>
</head>
<body>

<div>
    <div>
        <h1>以微博场景来举例</h1>
        <fieldset>
            <legend>
                用户2
                <button data-uid="2" data-lang='{"followed": "已关注", "follow": "关注"}'>关注</button>
            </legend>
            <p>假设这是一条微博,注意观察点击关注按钮后,页面右侧数据的变化</p>
        </fieldset>
    </div>
    <div>








        <h3>我的</h3>
        <ul>
            <li>微博 <em>5000</em> 条</li>
            <li>关注 <em>120</em> 人</li>
            <li>粉丝 <em>1200</em> 人</li>
        </ul>
        <script>
            $.subscribe('user:followed user:unfollow', function (e) {
                var step = e.type == 'user:followed' ? 1 : -1;
                var $followed = $('.js_followed');
                $followed.text($followed.text() * 1 + step);
            });
        </script>












        <h3>达人排行榜</h3>
        <ol>
            <li>用户1,<em data-uid="1">7800</em> 粉</li>
            <li>用户2,<em data-uid="2">7600</em> 粉</li>
            <li>用户3,<em data-uid="3">5400</em> 粉</li>
        </ol>
        <script>
            $.subscribe('user:followed user:unfollow', function (e, uid) {
                var step = e.type == 'user:followed' ? 1 : -1;
                var $followed = $('.js_darenlist [data-uid=' + uid + ']');
                $followed.text($followed.text() * 1 + step);
            });
        </script>









    </div>
</div>


<script>
$(document).ready(function () {

    $('body').on('click', 'button', function (e) {
        var $this = $(this);
        var uid = $this.data('uid');
        var lang = $this.data('lang');
        var stateFollowed = 'js_btn_followed';

        if($this.hasClass(stateFollowed)) {
            $.publish('user:unfollow', uid);
            $this.html(lang.follow).removeClass(stateFollowed);
        } else {
            $.publish('user:followed', uid);
            $this.html(lang.followed).addClass(stateFollowed);
        }
    });

});
</script>

</body>
</html>


觉得有用请点个赞吧!
1 590