代码之家  ›  专栏  ›  技术社区  ›  Max

使用jquery保持上一个突出显示

  •  0
  • Max  · 技术社区  · 6 年前

    我创建了一个简单的表来显示我遇到的问题。当一个值用复选框突出显示时,如果第二个复选框中存在该值,它仍然突出显示。没关系。但当我取消选中第一个或第二个复选框时,突出显示将消失,尽管它仍在第一个复选框中并且仍被单击。 当取消选中第二个复选框时,是否有方法保持突出显示? 我希望我说清楚。如果您愿意,这是我的J小提琴: https://jsfiddle.net/6k5caw8h/19/

    谢谢您。

    Html:

    $(document).ready(function() {
      $('.selector').each(function() {
        $(this).on('click', function(e) {
          check($(this).prop("checked") ? $("#nextColor").val() : '#fff', $(this).attr("name"));
        });
      });
      $('.all').each(function() {
        $(this).on('click', all);
      });
    
      function all(event) {
        if ($(this).is(':checked')) {
          let checked = $("input:checkbox:not(:checked)", $(this).parents('form')).not(this);
          checked.prop("checked", true);
          check($("#nextColor").val(), ...checked.map((i, e) => e.name).get());
        } else {
          let checked = $("input:checkbox(:checked)", $(this).parents('form')).not(this);
          checked.prop("checked", false);
          check('#fff', ...checked.map((i, e) => e.name).get());
        }
      }
    
      function check(color, ...elements) {
        $('td').each((i, td) => {
          if (elements.includes($(td).text())) $(td).css('background', color);
        });
      }
    });
    table.tb {
      border: 1px solid #CCC;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 12px;
      border-collapse: collapse;
      table-layout: fixed;
      margin-left: 200px;
    }
    
    .tb td {
      padding: 5px;
      margin: 5px;
      border: 1px solid #ccc;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <input id="nextColor" type="color" value="#9ac99d">
    <form id="form1" name="form1" method="post" action="">
      <label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
      <label><input type="checkbox" name="x" class="selector" />x</label>
      <label><input type="checkbox" name="y" class="selector" />y</label>
    </form>
    
    <form id="form1" name="form1" method="post" action="">
      <label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
      <label><input type="checkbox" name="x" class="selector" />x</label>
      <label><input type="checkbox" name="z" class="selector" />z</label>
    </form>
    <table class="tb">
      <tbody>
        <tr>
          <td>x</td>
          <td>y</td>
        </tr>
        <tr>
          <td>z</td>
          <td>x</td>
        </tr>
        <tr>
          <td>q</td>
          <td>a</td>
        </tr>
      </tbody>
    </table>
    3 回复  |  直到 6 年前
        1
  •  2
  •   Terry    6 年前

    您的问题是,取消选中针对同一字母表的复选框似乎忽略了其他字母表的状态,这来自于此问题行:

    check($(this).prop("checked") ? $("#nextColor").val() : '#fff', $(this).attr("name"));
    

    在这一行中,您只需检查正在单击的特定复选框是否被选中,而实际上您应该使用相同的复选框来检查所有的复选框。 name 属性并查看 任何 它们中的一个被检查过。

    所以你能做的就是简单地循环 .selectors 并通过(1)它们的 名称 与当前复选框匹配的属性,如果选中,则为(2)。如果选中其中任何一个,则第一个参数传递到 check() 应该是 true :

    const $sameNameSelector = $('.selector[name="'+$(this).attr('name')+'"]');
    const isAnySameNameSelectorChecked = $sameNameSelector.filter(function() { return this.checked }).length;
    check(isAnySameNameSelectorChecked ? $("#nextColor").val() : '#fff', $(this).attr("name"));
    

    更新:这似乎不能解决您的问题,因为 all() 也在调用一些复杂的逻辑。你只需要:

    1. 检查 click 事件侦听器打开 .selector .change
    2. 简单地使用 .all 复选框触发对 选择器 复选框并手动启动 change 事件。这将导致所有单个复选框上的单个逻辑触发,而不需要复制任何逻辑:
    function all(event) {
        $(this).closest('form').find('.selector').prop('checked', this.checked).trigger('change');
    }
    

    专业提示:你不需要这么做 $('.selector').each({ $(this).on('...'); }) 然后绑定事件处理程序。jquery可以智能地处理这一点,因此您只需在(…);'上执行“$('.selector').

    $(document).ready(function() {
    
      $('.selector').on('change', function(e) {
        const $sameNameSelector = $('.selector[name="' + $(this).attr('name') + '"]');
        const isAnySameNameSelectorChecked = $sameNameSelector.filter(function() {
          return this.checked
        }).length;
        check(isAnySameNameSelectorChecked ? $("#nextColor").val() : '#fff', $(this).attr("name"));
      });
      $('.all').each(function() {
        $(this).on('click', all);
      });
    
      function all(event) {
        $(this).closest('form').find('.selector').prop('checked', this.checked).trigger('change');
      }
    
      function check(color, ...elements) {
        $('td').each((i, td) => {
          if (elements.includes($(td).text())) $(td).css('background', color);
        });
      }
    
    
    });
    table.tb {
      border: 1px solid #CCC;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 12px;
      border-collapse: collapse;
      table-layout: fixed;
      margin-left: 200px;
    }
    
    .tb td {
      padding: 5px;
      margin: 5px;
      border: 1px solid #ccc;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <input id="nextColor" type="color" value="#9ac99d">
    
    <form id="form1" name="form1" method="post" action="">
    
      <label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
      <label><input type="checkbox" name="x" class="selector" />x</label>
      <label><input type="checkbox" name="y" class="selector" />y</label>
    
    </form>
    
    <form id="form1" name="form1" method="post" action="">
    
      <label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
      <label><input type="checkbox" name="x" class="selector" />x</label>
      <label><input type="checkbox" name="z" class="selector" />z</label>
    
    </form>
    
    
    <table class="tb">
      <tbody>
        <tr>
          <td>x</td>
          <td>y</td>
        </tr>
        <tr>
          <td>z</td>
          <td>x</td>
        </tr>
        <tr>
          <td>q</td>
          <td>a</td>
        </tr>
      </tbody>
    </table>
        2
  •  1
  •   Ralph Ritoch    6 年前

    要保持上一个突出显示,您需要在某个位置保存检查的历史记录以及检查时选择的颜色。一个简单的方法是将颜色数据和时间戳直接分配给复选框。下面的javascript解决了维护历史记录的实际问题,以便在删除检查时恢复以前检查的颜色。

    我重构代码以执行呈现循环 ReNeRebug检查() 这是一种更易于维护的设计模式。

    见: https://jsfiddle.net/c6pt0eb5/1/

    $(document).ready(function() {
    
      $('.selector').each(function() {
        $(this).on('click', function(e) {
          if ($(this).is(':checked')) {
          	$(this).data("color",[$("#nextColor").val(),Date.now()]);
          }
          renderChecks();
        });
      });
      $('.all').each(function() {
        $(this).on('click', all);
      });
    
      function all(event) {
        if ($(this).is(':checked')) {
          let checked = $("input:checkbox", $(this).parents('form')).not(this);
          checked.prop("checked", true);
          checked.data("color",[$("#nextColor").val(),Date.now()]);
        } else {
          let checked = $("input:checkbox(:checked)", $(this).parents('form')).not(this);
          checked.prop("checked", false);      
        }
        renderChecks();
      }
    
      function renderChecks() {
        const checks = {};
        const names = [];
      	$(".selector:checked").each((i,val) => {
           
           if (checks[$(val).attr('name')]) {
              checks[$(val).attr('name')].push($(val).data('color'));           
              checks[$(val).attr('name')].sort((a,b) => a - b);
           } else {
              checks[$(val).attr('name')] = [$(val).data('color')];
              names.push($(val).attr('name'));
           }});
           
           $('td').each((i, td) => {
               $(td).css('background','#fff');
               const text = $(td).text();
               let t = null;
               names.forEach((name) => {               
                   if (text.includes(name)) {
                       if (t == null || t < checks[name][0][1]) {
                          t = checks[name][0][1];
                          $(td).css('background', checks[name][0][0]);
                       }
                   }
               });                      
           });       
           
      }
    
    });
    
    
      
    table.tb {
      border: 1px solid #CCC;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 12px;
      border-collapse: collapse;
      table-layout: fixed;
      margin-left: 200px;
    }
    
    .tb td {
      padding: 5px;
      margin: 5px;
      border: 1px solid #ccc;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <input id="nextColor" type="color" value="#9ac99d">
    <form id="form1" name="form1" method="post" action="">
      <label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
      <label><input type="checkbox" name="x" class="selector" />x</label>
      <label><input type="checkbox" name="y" class="selector" />y</label>
    </form>
    
    <form id="form1" name="form1" method="post" action="">
      <label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
      <label><input type="checkbox" name="x" class="selector" />x</label>
      <label><input type="checkbox" name="z" class="selector" />z</label>
    </form>
    <table class="tb">
      <tbody>
        <tr>
          <td>x</td>
          <td>y</td>
        </tr>
        <tr>
          <td>z</td>
          <td>x</td>
        </tr>
        <tr>
          <td>q</td>
          <td>a</td>
        </tr>
      </tbody>
    </table>

    注意:接受的答案不保留以前的突出显示,它只保留当前的突出显示。

        3
  •  1
  •   Mark Schultheiss    6 年前

    我注意到,当选中所有子项时,“selectall”不会被选中-我假设您希望在选中所有子项时“选中”(一个常见要求),以便取消选中所有子项,而不必选中和取消选中“selectall”。

    另一件事是,您是否希望保持相关检查的检查,即当您选中“X”时,您是否希望另一个“X”被选中?如果执行此操作,请在我在此处提供的代码中取消对此行的注释,这样命名的代码将在同步时选中并取消选中:

      //  allChecksNotMe.prop("checked", isChecked);
    

    好了,现在我们已经超过了复选框管理,让我们来看看保持突出显示。现在这个要求有点不清楚了——你把它们变白了。 #fff 当您取消选中时。您希望这样做还是只在取消选中所有选项时才这样做?或者永远不要变白,也就是说,一旦有了颜色,即使没有选中,他们也会保留它?我的第二个示例提供了在取消选中时保持颜色突出显示以及重置为当前颜色选择的方法。

    $(function() {
      let cbx = "[type='checkbox']";
      let cbxSel = ".selector" + cbx;
      $(cbxSel) //.add('.all[type="checkbox"]')
        .on('change', function(e) {
          let me = $(this);
          let myname = $(this).attr("name");
          let namesel = "[name='" + myname + "']";
          let allpeer = $(".all" + cbx);
          let allChecksNotMe = $(cbxSel + namesel).not(me);
          let isChecked = this.checked;
          // uncomment to keep like checks in sync
          //  allChecksNotMe.prop("checked", isChecked);
          allpeer.trigger('checkcolor');
          let color = $("#nextColor").val();
          let newColor = isChecked ? color : '#fff';
          check(newColor, myname);
        });
      $('form').on('checkcolor', '.all', function(event) {
        let myForm = $(event.delegateTarget);
        // checks on form
        let formChecks = myForm.find(cbxSel);
        let formChecksChecked = formChecks.filter(':checked');
        let areAllChecked = (formChecks.length == formChecksChecked.length);
        $(this).prop("checked", areAllChecked);
      })
      $('.all' + cbx).on('change', function() {
        let isChecked = this.checked;
        let myForm = $(this).closest('form');
        // checks on form
        myForm.find(cbxSel)
          .prop('checked', isChecked).trigger("change");
      });
    
      function check(color, ...elements) {
        let newColor = {
          'background-color': color
        };
        $('.tb tbody').find('td').filter(function(index) {
          return elements.includes($(this).text());
        }).css(newColor);
      }
    });
    table.tb {
      border: 1px solid #CCC;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 12px;
      border-collapse: collapse;
      table-layout: fixed;
      margin-left: 200px;
    }
    
    .tb td {
      padding: 5px;
      margin: 5px;
      border: 1px solid #ccc;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <input id="nextColor" type="color" value="#9ac99d">
    <form id="form1" name="form1" method="post" action="">
      <label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
      <label><input type="checkbox" name="x" class="selector" />x</label>
      <label><input type="checkbox" name="y" class="selector" />y</label>
    </form>
    
    <form id="form2" name="form2" method="post" action="">
      <label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
      <label><input type="checkbox" name="x" class="selector" />x</label>
      <label><input type="checkbox" name="z" class="selector" />z</label>
    </form>
    <table class="tb">
      <tbody>
        <tr>
          <td>x</td>
          <td>y</td>
        </tr>
        <tr>
          <td>z</td>
          <td>x</td>
        </tr>
        <tr>
          <td>q</td>
          <td>a</td>
        </tr>
      </tbody>
    </table>

    替换为突出显示差异:

    $(function() {
      let cbx = "[type='checkbox']";
      let cbxSel = ".selector" + cbx;
      $(cbxSel) //.add('.all[type="checkbox"]')
        .on('change', function(e) {
          let me = $(this);
          let myname = $(this).attr("name");
          let namesel = "[name='" + myname + "']";
          let allpeer = $(".all" + cbx);
          let namedPeers = $(cbxSel + namesel);
          let allChecksNotMe = namedPeers.not(me);
          let isChecked = this.checked;
          // uncomment to keep like checks in sync
          //  allChecksNotMe.prop("checked", isChecked);
          allpeer.trigger('allchecked');
          let anyNamedChecked = !!namedPeers.filter(":checked").length;
          let keep = $('#keepcolor')[0].checked;
          let reset = $('#resetcolor')[0].checked;
          check(anyNamedChecked, myname, keep, reset);
        });
      $('form').on('allchecked', '.all', function(event) {
        let myForm = $(event.delegateTarget);
        // checks on form
        let formChecks = myForm.find(cbxSel);
        let formChecksChecked = formChecks.filter(':checked');
        let areAllChecked = (formChecks.length == formChecksChecked.length);
        $(this).prop("checked", areAllChecked);
      })
      $('.all' + cbx).on('change', function() {
        let isChecked = this.checked;
        let myForm = $(this).closest('form');
        // checks on form
        myForm.find(cbxSel)
          .prop('checked', isChecked).trigger("change");
      });
    
      function check(anyNamedChecked, myname, keepColor = false, reset = true) {
        let color = $("#nextColor").val();
        let newColor = anyNamedChecked ? color : '#fff';
        let colorCSS = {
          'background-color': newColor
        };
        $('.tb tbody').find('td').filter(function(index) {
          return myname.includes($(this).text());
        }).each(function(index, element) {
          let me = $(element);
          if (keepColor) {
            let scolor = reset ? color : me.data("savecolor");
            if (!!scolor) {
              colorCSS = {
                'background-color': scolor
              };
            }
            me.data("savecolor", !!scolor ? scolor : color);
          }
          $(element).css(colorCSS);
        });
      }
    });
    TB.TB{
    边框:1个实心CCC;
    字体系列:Arial,Helvetica,sans-serif;
    字体大小:12px;
    边框折叠:折叠;
    台面布置:固定;
    左边距:200px;
    }
    
    TB TD {
    填料:5px;
    利润率:5PX;
    边框:1个实心CCC;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    
    <input id="nextColor" type="color" value="#9ac99d">
    <label><input id="keepcolor" type="checkbox" name="keepcolor" />Keep Color</label>
    <label><input id="resetcolor" type="checkbox" name="resetcolor" />Reset Color</label>
    <form id="form1" name="form1" method="post" action="">
      <label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
      <label><input type="checkbox" name="x" class="selector" />x</label>
      <label><input type="checkbox" name="y" class="selector" />y</label>
    </form>
    
    <form id="form2" name="form2" method="post" action="">
      <label><input type="checkbox" name="SelectAll" class="all" />SelectAll</label>
      <label><input type="checkbox" name="x" class="selector" />x</label>
      <label><input type="checkbox" name="z" class="selector" />z</label>
    </form>
    <table class="tb">
      <tbody>
        <tr>
          <td>x</td>
          <td>y</td>
        </tr>
        <tr>
          <td>z</td>
          <td>x</td>
        </tr>
        <tr>
          <td>q</td>
          <td>a</td>
        </tr>
      </tbody>
    </table>