使用纯js获取具有特定类的单击元素的下一个元素

问题描述 投票:0回答:4

我试图通过以下方式获取具有特定类的第一个元素,该类跟随用纯 JS(无 JQuery)单击的元素,但 get el.nextSibling 不是函数错误。最初我使用的是 JQueryparents().next() 但想用纯 JS 来做到这一点:

const togglers = document.querySelectorAll('.toggler');
//console.log(togglers);
togglers.forEach(function(el) {
  el.addEventListener('click', function(e) {
    //const content = el.innerHTML;
    //console.log(content);
    el.nextSibling('.folder-content').style.display = 'block';
  })
});
<div class="folder">
  <div class="toggler">Click me 1</div>
  <div class="folder-content" style="display: none">
    Lorem ipsum
  </div>
</div>
<div class="folder">
  <div class="toggler">Click me 2</div>
  <div class="folder-content" style="display: none">
    Lorem ipsum
  </div>
</div>

如有任何帮助,我们将不胜感激:)

javascript
4个回答
12
投票

nextElement
是一个属性,而不是函数,因此您不要将
()
与它一起使用。也就是说,使用
nextSibling
会给你带来你不想要的空白内容。相反,您可以使用
nextElementSibling
:

el.nextElementSibling.style.display = 'block';

const togglers = document.querySelectorAll('.toggler');
//console.log(togglers);
togglers.forEach(function(el) {
  el.addEventListener('click', function(e) {
    //const content = el.innerHTML;
    //console.log(content);
    el.nextElementSibling.style.display = 'block';
  })
});
<div class="folder">
  <div class="toggler">Click me 1</div>
  <div class="folder-content" style="display: none">
    Lorem ipsum
  </div>
</div>
<div class="folder">
  <div class="toggler">Click me 2</div>
  <div class="folder-content" style="display: none">
    Lorem ipsum
  </div>
</div>


2
投票

您可以添加一个

while
循环来搜索第一个符合您条件的
nextSibling

编辑: 正如@j08691指出的,如果你的真实代码只关心元素而不关心其他节点类型,你可以使用nextElementSibling。

const togglers = document.querySelectorAll('.toggler');
//console.log(togglers);
togglers.forEach(function(el) {
  el.addEventListener('click', function(e) {
    var nextSibling = el.nextSibling;
    while (nextSibling) {
        if (
            nextSibling.nodeType == Node.ELEMENT_NODE
         && nextSibling.classList.contains('folder-content')
        ) {
            nextSibling.style.display = 'block';
            break;
        }
        nextSibling = nextSibling.nextSibling;
    }
  })
});
<div class="folder">
  <div class="toggler">Click me 1</div>
  <div>not this</div>
  <div>not this</div>
  <div class="folder-content" style="display: none">
    Lorem ipsum 1!
  </div>
  <div>not this</div>
  <div class="toggler">Click me 1.5</div>
  <div>not this</div>
  <div class="folder-content" style="display: none">
    Lorem ipsum 1.5!
  </div>
  <div>not this</div>
  <div>not this</div>
</div>
<div class="folder">
  <div class="toggler">Click me 2</div>
  <div class="folder-content" style="display: none">
    Lorem ipsum
  </div>
</div>
<div class="folder">
  <div class="toggler">Click me 3</div>
  <div>no folder content here!</div>
</div>


2
投票

我正在构建这个答案,而其他人进来了,为了多样性和简洁的 DOM 编程,这是另一种给这只猫换皮的方法:

这是您提供的初始代码,调用一个单独的函数来执行所请求的操作(查找与指定查询字符串匹配的下一个同级)

const togglers = document.querySelectorAll('.toggler');

togglers.forEach(function(el, i) {
  el.addEventListener('click', function(e) {

    searchNextSiblings(el, ".folder-content", function(ele) {
      ele.style.display = "block";
    });
  })
});

您会注意到我提供的函数称为

searchNextSiblings
,它需要三个参数:

  1. 您要从中搜索的元素。
  2. 您希望找到的元素匹配的查询字符串。
  3. 接收找到的元素的函数,您可以使用它来操作它。

这是函数本身:

function searchNextSiblings(ele, q, fn) {
    let flag = false;
    const nodeIterator = document.createNodeIterator(
  ele.parentNode, 
  NodeFilter.SHOW_ELEMENT, 
  function(node) {
        if (ele.isSameNode(node)) flag = true;
        if (!flag) return NodeFilter.FILTER_REJECT;
        else {
            if (node.matches(q)) {
                flag = false;
                return NodeFilter.FILTER_ACCEPT
            };
        }
    });
    let currentNode;
    while (currentNode = nodeIterator.nextNode()) {
        fn(currentNode);
    }
}

这是带注释的版本:

    function searchNextSiblings(ele, q, fn) {
// we want to search from the first Element provided
// to properly search we will set our crawler to begin
// from its parent node, and when we reach the first Element
// we will begin searching for the Query String
// in order to do this we declare a flag to False
// when we reach the first Element we will set it as True
// This will let us know when we can search for the Matching Query

    let flag = false;
    const nodeIterator = document.createNodeIterator(
      ele.parentNode, //root to search from
      NodeFilter.SHOW_ELEMENT, //set the iterator to search for elements
      function(node) { 
        if (ele.isSameNode(node)) flag = true;
//if we've found the first Element, set the flag to True
        if (!flag) return NodeFilter.FILTER_REJECT;
//if the flag is False, continue searching for first Element
        else {
//if we have found the first Element,
//we are now searching for the Element that Matches the Query
            if (node.matches(q)) {
//if we find a matching element
                flag = false;
//set the flag to false to stop the search
                return NodeFilter.FILTER_ACCEPT
//return the found node
            };
        }
    });
// the above declares the node iterator
// but does not start it up

    let currentNode;
    while (currentNode = nodeIterator.nextNode()) {
        fn(currentNode);
    }
//the above "starts up" the nodeIterator
}

const togglers = document.querySelectorAll('.toggler');
togglers.forEach(function(el, i) {
	el.addEventListener('click', function(e) {
		searchNextSiblings(el, ".folder-content", function(ele) {
			ele.style.display = "block";
		});
	})
});

function searchNextSiblings(ele, q, fn) {
	let flag = false;
	const nodeIterator = document.createNodeIterator(
  ele.parentNode, 
  NodeFilter.SHOW_ELEMENT, 
  function(node) {
		if (ele.isSameNode(node)) flag = true;
		if (!flag) return NodeFilter.FILTER_REJECT;
		else {
			if (node.matches(q)) {
				flag = false;
				return NodeFilter.FILTER_ACCEPT
			};
		}
	});
	let currentNode;
	while (currentNode = nodeIterator.nextNode()) {
		fn(currentNode);
	}
}
<div class="folder">
  <div class="toggler">Click me 1</div>
  <div class="folder-content" style="display: none">
    Lorem ipsum
  </div>
</div>
<div class="folder">
  <div class="toggler">Click me 2</div>
  <div class="folder-content" style="display: none">
    Lorem ipsum
  </div>
</div>


0
投票

节点与元素 在 HTML DOM 术语中:

节点是所有节点(元素节点、文本节点、注释节点)。

元素之间的空白也是文本节点。

元素只是元素节点。

兄弟姐妹 vs 元素兄弟姐妹 兄弟姐妹是“兄弟”和“姐妹”。

兄弟节点是具有相同父节点的节点(在相同的子节点列表中)。

元素同级是具有相同父级的元素(在相同的子级列表中)。

子节点与子节点 childNodes 返回子节点(元素节点、文本节点和注释节点)。

children 返回子元素(不是文本和注释节点)。

nextSibling 与 nextElementSibling nextSibling 返回下一个节点(元素节点、文本节点或注释节点)。元素之间的空白也是文本节点。

nextElementSibling 返回下一个元素(不是文本和注释节点)。

previousSibling 与 previousElementSibling previousSibling 返回前一个节点(元素节点、文本节点或注释节点)。元素之间的空白也是文本节点。

previousElementSibling 返回前一个元素(不是文本和注释节点)。

© www.soinside.com 2019 - 2024. All rights reserved.