在浏览器中 js 是一门基于事件机制的语言, 是发布订阅模式的天然使用场合.
此案例来自本网站的网友(@qingyang117), 这里用发布订阅模式来重新实现了一遍.
就算新增模块, 也容易改代码. 各模块之间交互职责也分得比较清楚, 不该发生交互的绝不会通信.
全选按钮只负责与其他选择按钮联动. 通信使用自定义事件 (这里是发布和订阅) 以及 jquery 默认事件通信(trigger).
选择按钮只与种类总数和数量 input 那边逻辑进行通信.
数量 input 变化时, 才更新总数统计数据.
可以看出, 发布订阅模式可以细化到任何颗粒度.
当然没人无聊, 把每一行都写到一个单独订阅, 然后发布一下.
总体优化了一下. 还有其他细节也可以具体优化(比如委托).
最后说一下, 这里主体逻辑清晰了即可, 怎么写都可以,
当然了按照这种思路去写东西, 很容易行云流水的, 不是新加一点功能, 就左改改右改改, 去订阅相应主题即可.
html 代码
- <!doctype html>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <style>
- .cfs { width: 30%; }
- .cfs a { cursor: pointer; }
- #cxsdd{ width:800px; text-align:center;}
- #cxsdd td{ height:35px;}
- #xianss{ height:40px; line-height:40px;}
- #in_num, #sp_num{ color:red; font-weight:bold;font-size:20px; padding:0 5px;}
- .lskdo{ width:40px; text-align:center; }
- </style>
- <div id="xianss">您选择了 < span id="in_num">0</span > 种商品, 共有 < span id="sp_num">0</span > 个商品</div>
- <table id="cxsdd" width="200" border="1" cellpadding="0" cellspacing="0" onselectstart="return false">
- <tr>
- <td > 店铺序列</td>
- <td > 店铺名称</td>
- <td > 商品</td>
- <td><input id="checkAll" type="checkbox"/>全选</td>
- <td class="cfs">数量</td>
- </tr>
- <tr>
- <td rowspan="5">201604192587</td>
- <td rowspan="5">陈先生的店</td>
- <td > 产品 1</td>
- <td><input class="choo" type="checkbox" value="choose"/>选择</td>
- <td class="cfs">
- <a class="jian">-</a>
- <input class="lskdo" disabled="disabled" type="text" value="0"/>
- <a class="jia">+</a>
- </td>
- </tr>
- <tr>
- <td > 产品 2</td>
- <td><input class="choo" type="checkbox" value="choose"/>选择</td>
- <td class="cfs">
- <a class="jian">-</a>
- <input class="lskdo" disabled="disabled" type="text" value="0"/>
- <a class="jia">+</a>
- </td>
- </tr>
- <tr>
- <td > 产品 3</td>
- <td><input class="choo" type="checkbox" value="choose"/>选择</td>
- <td class="cfs">
- <a class="jian">-</a>
- <input class="lskdo" disabled="disabled" type="text" value="0" />
- <a class="jia">+</a>
- </td>
- </tr>
- <tr>
- <td > 产品 4</td>
- <td><input class="choo" type="checkbox" value="choose"/>选择</td>
- <td class="cfs">
- <a class="jian">-</a>
- <input class="lskdo" disabled="disabled" type="text" value="0" />
- <a class="jia">+</a>
- </td>
- </tr>
- <tr>
- <td > 产品 5</td>
- <td><input class="choo" type="checkbox" value="choose"/>选择</td>
- <td class="cfs">
- <a class="jian">-</a>
- <input class="lskdo" disabled="disabled" type="text" value="0" />
- <a class="jia">+</a>
- </td>
- </tr>
- </table>
- <script src="http://apps.bdimg.com/libs/jquery/2.0.0/jquery.min.js"></script>
- <script>
- // 发布订阅实现
- (function($) {
- var o = $({});
- $.subscribe = function() {
- o.on.apply(o, arguments);
- };
- $.publish = function() {
- o.trigger.apply(o, arguments);
- };
- $.unSubscribe = function() {
- o.off.apply(o, arguments);
- };
- })(jQuery);
- </script>
- <script>
/************* 客户端 **************$/ 全选与其他选择按钮之间的联动
- $.subscribe('selectAll:true',
- function() {
- $(".choo").not(':checked').prop("checked", true).trigger('change');
- });
- $.subscribe('selectAll:false',
- function() {
- $(".choo").prop("checked", false).trigger('change');
- });
- // 选择按钮与数量框之间的联动
- $.subscribe('selectItem:true',
- function(e, $checkbox) {
- $checkbox.parent().siblings('.cfs').find('.lskdo').prop("disabled", false).val(1).trigger('propertychange');
- $.publish('typeNumberChange');
- });
- $.subscribe('selectItem:false',
- function(e, $checkbox) {
- $checkbox.parent().siblings('.cfs').find('.lskdo').prop("disabled", true).val(0).trigger('propertychange');
- $.publish('typeNumberChange');
- });
- // 种类个数变化事件
- $.subscribe('typeNumberChange',
- function(e, $checkbox) {
- $("#in_num").text($('.choo:checked').length);
- });
- // 商品总数变化事件
- $.subscribe('totalNumberChange',
- function(e, $checkbox) {
- var total = 0;
- $('.lskdo').each(function() {
- total += +this.value; //+ 表示转化为数字
- });
- $("#sp_num").text(total);
- });
- // 全选按钮 change 事件
- $("#checkAll").change(function() {
- var topic = 'selectAll:' + $(this).is(':checked');
- $.publish(topic);
- });
- // 选择按钮 chang 事件
- $('.choo').change(function() {
- var $this = $(this);
- var topic = 'selectItem:' + $this.is(':checked');
- $.publish(topic, [$this]);
- });
- // 加减按钮事件
- $(".jian").click(function() {
- var active = $(this).parent().parent().find(".choo").is(":checked");
- var input = $(this).parent().find(".lskdo");
- var value = +input.val();
- if (active && value > 1) {
- input.val(value - 1).trigger('propertychange');
- }
- });
- $(".jia").click(function() {
- var active = $(this).parent().parent().find(".choo").is(":checked");
- var input = $(this).siblings(".lskdo");
- var value = +input.val();
- if (active) {
- input.val(value + 1).trigger('propertychange');
- }
- });
- // input 框 change 事件
- $(".lskdo").on('input propertychange',
- function() {
- var value = $(this).val();
- if (isNaN(value)) {
- alert("您好, 请输入您想购买的数量!");
- $(this).val(1);
- }
- $.publish('totalNumberChange');
- }).focus(function() {
- $(this).select();
- }); < /script>/
来源: http://www.qdfuns.com/article/17398/cc37303c131f23a05fb36ab477d6563c.html