如何在Javascript中获取兄弟元素(div)?

3

So I have this HTML:

<div class="tip-box">
    <div class="tip-title" onclick="toggleTip()">
        <h2>Tip 1</h2>
    </div>
    <div class="tip-content hidden">
        <p>Tip 1 content</p>
    </div>
</div>

并且这个JavaScript:

function toggleTip() {
    $(this).siblings(".tip-content").toggleClass("hidden");
}

希望很明显这段代码的作用,但它没有起作用。使用 .siblings() 似乎无法按照此方式工作。
正确的解决方案是什么?获取下一个特定类型或带有特定类的兄弟元素,然后隐藏/显示它?

2
喜欢这样吗?(http://jsfiddle.net/f9tcurhk/)? - Josh Crozier
2
问题在于 this 不是你所期望的。 - nnnnnn
@JoshCrozier在这里有正确的想法。你只是忘记将点击的上下文传递给函数了。 - stewart715
@JoshCrozier 哈,是的,我在和 OP 说话,说你做得很正确 :) - stewart715
你想获取只有一个类名为.tip-content的兄弟或兄弟吗? - Suman Bogati
5个回答

3
您可以使用 jQuery 函数。
<div class="tip-box">
    <div class="tip-title">
        <h2>Tip 1</h2>
    </div>
    <div class="tip-content hidden">
        <p>Tip 1 content</p>
    </div>
</div>

$(document).ready(function(){
    $('.tip-title').click(function(){
        $(this).siblings(".tip-content").toggleClass("hidden");
    });
});

你也可以使用这个。
<div class="tip-box">
    <div class="tip-title" onclick="toggloTip(this)">
        <h2>Tip 1</h2>
    </div>
    <div class="tip-content hidden">
        <p>Tip 1 content</p>
    </div>
</div>


<script>
function toggloTip(elm) {
    $(elm).siblings(".tip-content").toggleClass("hidden");
}
</script>

3
您可以使用纯JavaScript和节点的nextElementSibling属性来执行以下操作,我假设您想要在兄弟节点之间进行此操作。

function getChildrens(n, selector) {
  var nodes = [];
  while (n.nextElementSibling != null) {
    if (n.nextElementSibling.hasOwnProperty('classList')) {
      if (n.nextElementSibling.classList.contains(selector)) {
        //return n.nextElementSibling;
        nodes.push(n.nextElementSibling);
      }
    }
    n = n.nextElementSibling;
  }
  return nodes;
};

function getSiblings(n, selector) {
  return getChildrens(n, selector);
}

function toggleTip(elem) {
  var siblings = getSiblings(elem, "tip-content");
  if (siblings.length > 0) {
    for (var i = 0; i < siblings.length; i++) {
      siblings[i].classList.toggle("hidden");
    }
  }
}
.hidden {
  display: none;
}
<div class="tip-box">
  <div class="tip-title" onclick="toggleTip(this)">
    <h2>Tip 1</h2>
  </div>
  <div class="tip-content hidden">
    <p>Tip 1 content</p>
  </div>
</div>


你可以使用纯JavaScript,但是为什么要引入那么多新代码,当他们已经在使用一行jQuery(只是目前用法不正确)?这不仅不实用,而且没有用处。抱歉。 - iCollect.it Ltd
你可能是对的,但我只是提供了另一种可供其他人使用的替代解决方案。 - Suman Bogati
不属于所问问题的范围。任何发现这个问题的人都会看到“onclick =""调用jQuery时没有正确的this”问题,对于重新实现一个jQuery的一行代码而言,并不太担心要使用超过20行的原始JS。很抱歉:( - iCollect.it Ltd
1
我很欣赏这个纯JS的答案,而且问题是“如何在Javascript中获取兄弟元素(div)?”所以我认为它完全符合范围。 - SethWhite

3
这里提供另一种非JQuery的答案。
要获取下一个元素兄弟,请使用:
var nextElement = element.nextElementSibling;

要获取前一个元素的兄弟节点,请使用:

最初的回答

var previousElement = element.previousElementSibling;

要获取元素索引,请使用:
最初的回答。
var index = Array.prototype.slice.call(element.parentElement.children).indexOf(element);

如果你在第一个元素,previousElementSibling的值将为null。

如果你在最后一个元素,nextElementSibling的值将为null。

翻译:当你在第一个元素时,它的前一个元素是不存在的。同样地,当你在最后一个元素时,它的下一个元素也不存在。


1

之前的答案都没有解释问题以及为什么他们的解决方案有效,甚至包括那个 被连续点赞 的答案 ;)

问题在于内联的 onclick 处理程序没有传递它的当前上下文。在 onclick="" JavaScript 代码中,this 是被点击的元素。一旦你调用全局函数(例如你的 toggleTip),这个上下文就丢失了。函数接收到的 thiswindow 而不是元素。

通常的快速修复方法,对于原始的 JavaScript 代码,是将 this 作为参数传递给全局函数。

例如:

onclick="toggleTip(this)" 

并在函数中像这样接收参数:
function toggleTip(element) {
    $(element).siblings(".tip-content").toggleClass("hidden");
}

然而,由于您正在使用jQuery,内联事件处理程序实际上是一个不好的主意。它们没有理由将事件注册与事件处理程序代码分开,并且不允许在同一元素上有多个相同类型的事件处理程序。它们还绕过了jQuery使用的非常酷的事件冒泡系统。
在jQuery中,首选的替代方法是使用jQuery选择元素并使用jQuery在一步中连接事件。
jQuery(function($){
    $('.tip-title').click(function(){
        $(this).siblings(".tip-content").toggleClass("hidden");
    });
});

如果你只想获取其后的元素,并且可能会添加更多的对,更好的选择是使用nextAllfirst(),并与相同的jQuery过滤器一起使用,而不是使用siblings

例如:

jQuery(function($){
    $('.tip-title').click(function(){
        $(this).nextAll(".tip-content").first().toggleClass("hidden");
    });
});

或者,如果你能保证它是下一个元素,就像@Tim Vermaelen一样使用next(无论是否带有选择器都没有区别,所以可以省略):

jQuery(function($){
    $('.tip-title').click(function(){
        $(this).next().toggleClass("hidden");
    });
});

注意:在这个例子中,jQuery(function($){是一个DOM就绪事件处理程序,它是$(document).ready(function(){YOUR CODE});的非常方便的快捷方式,它还传递了一个本地作用域的$值。对于那些将此代码误认为是不正确的IIFE的人,这里有一个可工作的示例:http://jsfiddle.net/TrueBlueAussie/az4r27uz/

我需要对“为什么”不使用内联onclick处理程序进行详细的解释,以回报您的帮助。不过有一个问题,jQuery的DOM准备有很多快捷方式,但是您的好像有些错误...如果我没记错的话,$没有被传递。正确的方法应该是IIFE => (function($){}(window.jQuery)); - Tim Vermaelen
@Tim Vermaelen:不是IIFE。这是jQuery提供的一种快捷的DOM就绪函数,它将自身作为第一个参数传递。 :) - iCollect.it Ltd
我认识它们,这就是为什么它有一种特定的气味……如果你懂我的意思……让我快速测试一下。 - Tim Vermaelen
@Tim Vermaelen:这基本上是带有参数的$(function(){}); DOM准备就绪快捷方式。相信我,它是正确的:http://jsfiddle.net/TrueBlueAussie/az4r27uz/ :) - iCollect.it Ltd
@Tim Vermaelen:在1.6.4版本中也可以工作 http://jsfiddle.net/TrueBlueAussie/az4r27uz/1/,1.7.2版本中也可以工作 http://jsfiddle.net/TrueBlueAussie/az4r27uz/2/,1.8.3版本中也可以工作 http://jsfiddle.net/TrueBlueAussie/az4r27uz/3/ :) - iCollect.it Ltd
显示剩余2条评论

1
这个 JavaScript 怎么样?
$(function(){
    $('.tip-box').on('click', '.tip-title', function(){
        $(this).next('.tip-content').toggleClass('hidden');
    });
});

使用jQuery时,可以摒弃使用onclick属性的想法。


委托事件处理程序似乎有些过火,但是你的方案比Kamruzzaman那个被串联点赞的答案更明智。+1 - iCollect.it Ltd

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