使用未选中的复选框,如何过滤掉始终隐藏的 NSFW 标记的 div,但选中打开时,以遵循可见性规则?

2024-03-08

这个问题基于这个问题/答案:同时使用复选框和下拉菜单进行准确过滤 https://stackoverflow.com/q/68317206/4383420

Hi!

(注意,简化的问题和代码位于代码笔或下面的代码片段中,这里我只是解释上下文。)

Image of the simplified question, for which I actually need the answer: enter image description here

我的参考图像 PHP 画廊进展顺利:https://manu.mymaterial.org https://manu.mymaterial.org(请注意,它包括 NSFW 材料、安德鲁·卢米斯 (Andrew Loomis) 的美术绘画,位于 ATM 头版。)

这让我想到了这个问题。

当“显示 NSFW 材料”复选框未选中时,无论我执行什么其他过滤选项,如何让“显示 NSFW 材料”不显示任何带有 NSFW 标签的图像?

我有一种感觉,这是 Javascript 中的一个简单的 if 语句,但我不确定它到底应该放在哪里,以及它是否会破坏其他东西。

目前,NSFW 复选框仅显示 NSFW 材料(黄色框),不显示其他内容。这是不希望的。

所以,换句话说,我有用于以各种方式显示所有材料的标签 - 但现在 NSFW 标签在包含到 div 中时应该隐藏内容。或者就我而言,它只是一个由 PHP 处理并放入 div 中的图像文件:Andrew_Loomis;传统_字符_真实_颜色_NSFW.jpg

代码笔项目:https://codepen.io/manujarvinen/pen/wvdzeQv https://codepen.io/manujarvinen/pen/wvdzeQv

谢谢大家,这是个好地方。

Image of my project thing: enter image description here

var $filterCheckboxes = $('input[type="checkbox"]');
       var $filtermenues = $('.grid1');


       var filterFunc = function () {

           var selectedFilters = [];
           $filtermenues.find(":selected").each(function () {
               
               var v = this.value;
               if (selectedFilters.indexOf(v) === -1 && v)
                   selectedFilters.push(v);
           });

           $('.animal' && '.filterDiv')
               .hide()
               .filter(
                   function (_, a) {
                       var itemCat = $(a).data('category').split(' ');
                       if (itemCat.indexOf("showAll") > -1)
                           return;
                       return selectedFilters.every(
                           function (c) {
                               return itemCat.indexOf(c) > -1;
                           })
                   })
               .show();
           $filterCheckboxes.filter(':checked').each(function () {
               var v = this.value;
               if (selectedFilters.indexOf(v) === -1)
                   selectedFilters.push(v);
           });

           $('.animal' && '.filterDiv')
               .hide()
               .filter(
                   function (_, a) {
                       var itemCat = $(a).data('category').split(' ');
                       return selectedFilters.every(
                           function (c) {
                               return itemCat.indexOf(c) > -1;
                           })
                   })
               .show();

       }

       $filterCheckboxes.on('change', filterFunc);

       $('select').on('change', filterFunc);
body {
width: 100%;
text-align: center;
background-color: black;
color: white;
font-family: sans-serif;
}
.grid {
width: 300px;
margin: 50px auto;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.grid1 {
width: 300px;
margin: 50px auto;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.filterDiv {
width: 100px;
height: 100px;
padding-top: 20px;
color: black;
font-weight: bold;
}
<!-- Help needed in this URL: https://stackoverflow.com/q/68334085/4383420 -->

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

   <div class=grid1>
          <select>
              <option value="">--</option>
              <option value="violet">violet</option>
          </select>
          <select>
              <option value="">--</option>
              <option value="blue">blue</option>
          </select>
          <select>
              <option value="">--</option>
              <option value="yellow">yellow</option>
          </select>
      </div>

  <div class=grid>
      <label>VIOLET
      <input type="checkbox" value="violet" />
      <span class="checkmark"></span>
      </label>
      <label>BLUE
      <input type="checkbox" value="blue" />
      <span class="checkmark"></span>
      </label>
      <label>YELLOW
      <input type="checkbox" value="yellow" />
      <span class="checkmark"></span>
      </label>
  </div>

  <div class=grid>
      <div class="filterDiv" data-category="violet blue" style="background-color: blue">Tags: <br />violet <br />blue</div>
      <div class="filterDiv" data-category="violet red MVP" style="background-color: red">Tags: <br />violet <br />red <br />MVP</div>
      <div class="filterDiv" data-category="yellow NSFW MVP" style="background-color: yellow">Tags: <br />yellow <br />NSFW<br />MVP</div>
  </div>


  <div>
  <label>Most Valuable Players (MVP)
  <input type="checkbox" value="MVP" />
  <span class="checkmark"></span>
  </label>
  </div>

  <div>
  <label>Display NSFW material also
  <input type="checkbox" value="NSFW" />
  <span class="checkmark"></span>
  </label>
  </div>

    <div style="width:400px; text-align: left; margin: 60px auto;">
    What I need:
    
    <p>By default, NSFW material checkbox is OFF and YELLOW shouldn't be seen at all in ANY situation.</p>
      <p>When NSFW material checkbox is checked, ALSO YELLOW should be seen, but follow rest of the rules.</p>
      
      
    </div>

代码过于复杂,难以理解。其一,这一点

        var v = this.value;
        if (selectedFilters.indexOf(v) === -1 && v)
            selectedFilters.push(v);

只是为了避免数组中出现重复。这意味着它更像是一个set https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set,这是一种本身避免重复的数据结构。如果你这样做selectedFilters = new Set(),那么整个块可以替换为selectedFilters.add(this.value);

查询“该类别是否包含在所选过滤器中”也可以从selectedFilters.indexOf(cat) === -1 to selectedFilters.has(cat)。这样,代码就已经开始更加匹配所需的行为。

此外,单字母变量也应该被废除,并由解释性名称代替。代码还应该有更多注释来解释发生了什么。

然后,能够从菜单和复选框中选择过滤器会造成混乱。我不确定这应该如何工作,所以我只是更改了代码,以便将它们全部分组在一起:当通过复选框或菜单选择过滤器时,过滤器处于活动状态。

最后还有一个问题,即“允许的 NSFW”与其他类别的过滤并不完全相同。因此,我只是为它创建了一个单独的变量,并将其从过滤器中删除。最后我添加了一个额外的调用filterFunc()这样事情就开始被过滤(而不是等待过滤器复选框/菜单的第一次更改)。这就是最终结果。

EDIT:更新了“仅限 MVP”复选框。

EDIT 2:不要让“MVP”复选框显示带有 MVP 标签的所有内容。

EDIT 3:翻转条件以显示项目;他们现在需要所有标签。旧代码被注释掉,以便任何人都可以根据需要自行恢复此开关。

var $filterCheckboxes = $('input[type="checkbox"]');
var $filtermenus = $('.grid1');


// Return the intersection of setA and setB.
// Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
function intersection(setA, setB) {
    let _intersection = new Set()
    for (let elem of setB) {
        if (setA.has(elem)) {
            _intersection.add(elem)
        }
    }
    return _intersection
}
function isSuperset(set, subset) {
    for (let elem of subset) {
        if (!set.has(elem)) {
            return false
        }
    }
    return true
}


function filterFunc() {
    var selectedFilters = new Set();

    // Gather tags from the menus.
    $filtermenus.find(":selected").each(function () {
        if (this.value)
            selectedFilters.add(this.value);
    });
    // Gather tags from the checkboxes.
    $filterCheckboxes.filter(':checked').each(function () {
        if (this.value)
            selectedFilters.add(this.value);
    });
    console.log("selected filters:", [...selectedFilters]);
 
    let mayShowNSFW = selectedFilters.has("NSFW");
    selectedFilters.delete("NSFW");
  
    let mustShowMVPOnly = selectedFilters.has("MVP");
    selectedFilters.delete("MVP");

    $('.filterDiv')
        .hide()
        .filter(
            // Returns 'true' to show items, 'false' to hide them.
            function (_, element) {
                let itemCats = new Set($(element).data('category').split(' '));

                // If the item has tag 'showAll', always show it.
                if (itemCats.has("showAll"))
                    return true;
                
                // If item is NSFW but that's not in the filters, hide the item
                // regardless of other tags.
                if (itemCats.has("NSFW") && !mayShowNSFW)
                    return false;
                
                if (mustShowMVPOnly && !itemCats.has("MVP"))
                    return false;
                
                // If there are no filters at all, just show everything.
                if (selectedFilters.size == 0)
                    return true;

                // If this item has all the tags, show it:
                return isSuperset(itemCats, selectedFilters);
              
                // If this item has any of the tags, show it:
                // return intersection(selectedFilters, itemCats).size > 0;
            })
        .show();
}

$filterCheckboxes.on('change', filterFunc);
$('select').on('change', filterFunc);
filterFunc();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用未选中的复选框,如何过滤掉始终隐藏的 NSFW 标记的 div,但选中打开时,以遵循可见性规则? 的相关文章

随机推荐