纯JavaScript替代jQuery.prev()的方法?

5

我有这段jQuery代码:

$(".q-block-container").prev(".sub-block-container").css("border-bottom","none");

我需要一个纯JavaScript的等价物,可以选择前一个同级元素仅当它与选择器匹配(在本例中为.sub-block-container)。

例如,假设我有一个列表,列表中的每个项目都有一个border-bottom样式。取决于特定列表项之前的兄弟姐妹是什么,这应该确定是否应该应用边框:

<ul>
    <li class="q"></li>
    <li class="q"></li>
    <li class="q"></li>
    <li class="s"></li>
    <li class="s"></li>
    <li class="q"></li>
    <li class="s"></li>
    <li class="q"></li>
</ul>

在这个例子中,如果以下情况发生,则前一个同级元素<li>不应出现边框:
  • 元素是 q 并且前一个同级元素是 s

  • 元素是 s 并且前一个同级元素是 q

  • 元素是 s 并且前一个同级元素也是 s


我可以问一下为什么吗?这似乎不是一个有效的做法。 - Derek 朕會功夫
我已经查看了你的示例。在这种情况下,我假设你的行是通过编程生成的。通常的做法是直接为你希望具有某些属性的元素分配类,即在这种情况下,你应该在将元素放入DOM之前向它们添加一个名为“with-border”的类。 - Derek 朕會功夫
当然可以,但是列表项是由用户随时添加的,他们也可以重新排序,因此每次更改发生时,列表需要重新更新边框。 - JoeTidee
1
可能会有帮助 https://dev59.com/YHRB5IYBdhLWcg3wl4Sc - Robert
1
如果决定是否应用边框是基于将一个元素的内容与其“下一个兄弟元素”的内容进行比较,那么逻辑可能会更容易。 - traktor
显示剩余5条评论
2个回答

6
如果您的元素 .sub-block-container 只有这一个类,请尝试以下操作。
var elem = document.getElementsByClassName("q-block-container");
for (i=0; i<elem.length; i++) {
    var prev = elem[i].previousElementSibling;
    if (prev.className == "sub-block-container") {
        prev.style.borderBottom = "none";
    }
}

如果您的元素可能有多个类,请改用以下方式:
var elem = document.getElementsByClassName("q-block-container");
for (i=0; i<elem.length; i++) {
    var prev = elem[i].previousElementSibling;
    if (prev.classList.contains("sub-block-container")) {
        prev.style.borderBottom = "none";
    }
}

1
对于IE >= 10,也可以使用if(prev.classList.contains("sub-block-container")){...} - JoeTidee
2
应该使用previousElementSibling,否则会与文本节点冲突导致崩溃。 - Kaiido
@JoeTidee 是的,没错。我之前不知道那个属性。 - Abraham Murciano Benzadon

0
也许可以尝试这个:
if (!Element.prototype.matches) {
    Element.prototype.matches = 
        Element.prototype.matchesSelector || 
        Element.prototype.mozMatchesSelector ||
        Element.prototype.msMatchesSelector || 
        Element.prototype.oMatchesSelector || 
        Element.prototype.webkitMatchesSelector ||
        function(s) {
            var matches = (this.document || this.ownerDocument).querySelectorAll(s),
                i = matches.length;
            while (--i >= 0 && matches.item(i) !== this) {}
            return i > -1;            
        };
}

var elements = document.querySelectorAll('.q-block-container');

for (var i = 0; i < elements.length; i++) {
    var element = elements[i];
    var previous = element.previousElementSibling;
    if(previous.matches('.sub-block-container')){
        previous.style.borderBottom = 'none';
    }
}​

所以这很简单,你遍历所有的.q-block-container,如果有一个前面的兄弟元素与.sub-block-container选择器匹配,就会改变其border-bottom。
编辑:
感谢Abraham Murciano Benzadon指出代码中的错误(JS中不需要分号,但最好保持相同的代码风格)
编辑2:
已将代码修复为您想要的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接