【问题标题】:Show/Hide Elements with multiple attributes by attribute selection (Javascript)通过属性选择显示/隐藏具有多个属性的元素(Javascript)
【发布时间】:2015-07-17 14:45:35
【问题描述】:

我尝试为以下问题找到一个简单的解决方案(我完全是编码初学者,只需在“开箱即用”页面的小部件中使用 javascript):

访问者可以通过单击删除/显示来选择多个属性

  • 属性(删除/显示)
  • 属性 b(删除/显示)
  • 属性 c(删除/显示)
  • a.s.o.

根据访问者“选择”,我想显示或隐藏元素列表:

  • 元素 1(属性 a 和 b) - 如果选择了“a”或“b”,则删除
  • 元素 2(属性 a) - 如果选择了“a”,则删除
  • 元素 3(属性 a 和 c) - 如果选择了“a”或“c”,则删除
  • a.s.o.

我已经能够基于“选择”隐藏元素,但在我的解决方案中,每个元素仅根据唯一 ID 显示和隐藏(因此也仅基于单个选择)。

我为此找到的 Javascript 是:

<script type="text/javascript">
//<![CDATA[
function swap(openlink,closelink, linkid, dataid)
{
if( document.getElementById(dataid).style.display == 'none')
{
document.getElementById(dataid).style.display='inline';
document.getElementById(linkid).firstChild.nodeValue=closelink;
} else
{
document.getElementById(dataid).style.display='none';
document.getElementById(linkid).firstChild.nodeValue=openlink;
}
}
//]]>
</script>

而且我可以使用这个 HTML 代码来删除/显示元素:

attribute a <a href="#swap" onclick="javascript:swap('Show','Remove', 'swaplinkA', 'showmeA')" id="swaplinkA" onfocus="this.blur()" name="swaplinkA">Remove</a>
attribute b <a href="#swap" onclick="javascript:swap('Show','Remove', 'swaplinkB', 'showmeB')" id="swaplinkB" onfocus="this.blur()" name="swaplinkB">Remove</a>
attribute c <a href="#swap" onclick="javascript:swap('Show','Remove', 'swaplinkC', 'showmeC')" id="swaplinkC" onfocus="this.blur()" name="swaplinkC">Remove</a>

我的元素将通过以下方式删除/显示:

<div id="showmeA" style="display:inline">Element 1</div>
<div id="showmeB" style="display:inline">Element 2</div>
<div id="showmeB" style="display:inline">Element 3</div>

有没有一种简单的方法可以将 2 个 ID 添加到一个“元素”,例如元素 1 可以被 id=showmeA 和 id=showmeB 隐藏?

【问题讨论】:

  • ID 应该是唯一的
  • 使用类而不是 ID。要将多个类添加到一个元素,只需用空格分隔它们,例如&lt;div class="class-1 class-2 class-infinity"&gt;

标签: javascript


【解决方案1】:

您自己说过这个问题:ID 是唯一的

这正是您应该使用 id 以外的其他东西的原因,而 class 属性非常好,因为它不必是唯一的。

那么,这意味着该函数将不会使用getElementById() 而是使用getElementsByClassName() 来查找您的元素。

请注意,此函数获取元素s,这涉及到您必须遍历这些元素s并隐藏/显示目标。

function swap(openlink, closelink, linkid, dataclass) {
    var elements = document.getElementsByClassName(dataclass);
    for (var i = 0; i < elements.length; i++) {
        var element = elements[i];
        if(element.style.display == 'none') {
            element.style.display='inline';
            document.getElementById(linkid).firstChild.nodeValue=closelink;
        } else {
            element.style.display='none';
            document.getElementById(linkid).firstChild.nodeValue=openlink;
        }
    }
}

别忘了在你的 HTML 中用 class 属性替换 id,你想放多少就放多少,它们之间必须用空格隔开:

<div class="showmeA showmeB">Element 1</div>
<div class="showmeB">Element 2</div>
<div class="showmeC">Element 3</div>

这是一个示例,您可以使用它来更好地了解解决方案中使用的功能和属性,这可以解决您的问题:https://jsfiddle.net/sy2mxscf/

同样重要的是要通知您inline Javascript is bad,当您的 Javascript 技能提高时,您应该重新考虑您的代码。


为了解决 cmets 中指出的问题,您必须使用某种计数器,并在隐藏元素时将其递增,在显示其类之一的元素时将其递减,并在显示关联元素时显示关联元素这个计数器是 0。

这也是您需要两个不同链接的原因:“删除”用于递增,“显示”用于递减。

有几种方法可以实现此解决方案:

  • 在 Javascript 中使用关联数组
  • 在元素上使用自定义属性
  • 添加和删除特定类

我选择了最后一个,但这可能不是最好的,这只是其中一种可能性。

https://jsfiddle.net/sy2mxscf/2/

这个想法是添加或删除自定义“hidemeX”类。如果您单击针对同一元素的两个不同的“删除”链接,将添加两个类。如果您然后单击任何“显示”链接,则将删除关联类。但是在您单击第二个链接之前,仍然存在一个“hidemeX”类,因此由于 CSS,该元素不会显示。

【讨论】:

  • 非常感谢,你们是我的英雄!它完美无缺!而且我很感激,你能够以一种我也能理解的方式来解释它!完美的!如果你们谁来上海,给我一张纸条,我给你们喝啤酒!
  • @Steven 我很高兴能帮助一个好人!
  • 我有一个我无法解决的问题......抱歉,我很抱歉提出愚蠢的问题。
  • 它可以很好地过滤掉所有具有属性 A 的元素,显示 A,而不是过滤 B,而不是显示 B,过滤掉 C。但是当我尝试将它们组合起来时,它不会起作用更多的。比如元素1有属性A&B&C。一一过滤,元素会消失又回来。但是如果我按 A 过滤 A,而不是按 B 或 C,如果属性不在第一个位置,则元素将返回。我尝试了很多更改,但我太“新”了,无法找到如何正确“循环”它..或者熟练的人会解决它......并建议?
  • @Steven 我更新了我的答案以提供新的解决方案。
【解决方案2】:

正如Delgan所说,这里最好使用class,并且你可以使用那些&lt;a&gt;的id作为他们的类,所以当你使用你的函数swap时,你可以很容易地回溯以确定是否元素被选中,所以 div 应该被移除。

以下是如何分离 javascript 逻辑和 html 结构。

var swap = function(e) {
    var close = 'Remove', open = 'Show';
    var next = this.text === close ? open : close;
    // Set the clicked <a>'s text.
    this.text = next;
  
    // Get divs that will affect by this <a>
    var affectTarget = this.id;
    
    // Affected div elements
    var targets = document.getElementsByClassName(affectTarget); 
    var i, len = targets.length;
    var visible;
    
    var watch, wLen, j;
     
    // For each <div> that will be affect by the clicked <a>, we have to chec :
    for (i = 0; i < len; ++i) {
        // Get the classes that used as a list to show which <a> will have a effect on it.
        watch = targets[i].classList;
        wLen = watch.length;
        // visibilty is default to inline, if no <a> that it watches is selected, then it'll show
        visible = "inline";
        for (j = 0; j < wLen; ++j) {
            // If any of the <a> it watches is selected, set the visibilty to none.
            if (document.getElementById(watch[j]).text === open) {
                visible = "none";
                break;
            }
        }
        targets[i].style.display  = visible;
    }
};

// For each switcher, we register a click event for it.
var switchers = document.querySelectorAll("a.showSwitcher");
var i, len = switchers.length;
for (i = 0; i < len; ++i) {
    switchers[i].addEventListener('click', swap);
}
attribute a <a href="#swap"  class="showSwitcher" onfocus="this.blur()" name="swaplinkA" id="swaplinkA">Remove</a>
attribute b <a href="#swap"  class="showSwitcher" onfocus="this.blur()" name="swaplinkB" id="swaplinkB">Remove</a>
attribute c <a href="#swap"  class="showSwitcher" onfocus="this.blur()" name="swaplinkC" id="swaplinkC">Remove</a>

<hr/>

<div class="swaplinkA swaplinkB" style="display:inline">Element 1</div>
<div class="swaplinkA"style="display:inline">Element 2</div>
<div class="swaplinkA swaplinkC"style="display:inline">Element 3</div>

【讨论】:

  • 我也经常使用该代码,但不幸的是无法让他“运行”......从来没有得到效果,一个元素已经消失了......我是当然,对于所有熟练的人来说,这显然是,但我已经好几天没有找到重点了……抱歉,我的请求打扰了你。我必须进行哪些更改才能使其可行?
  • 先打开开发工具,查看页面加载时是否有错误提示,或者点击链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-01
  • 2012-03-16
  • 2019-07-20
相关资源
最近更新 更多