首页 > 解决方案 > 遍历 DOM 元素并动态添加数据属性

问题描述

我有以下 DOM 结构,我需要在我的 h1 或 h2 标记中获取文本(但总是第一个孩子)并将该文本值作为数据属性添加到第二个孩子。

<div class="my-item">
    <div class="mac">
        <h1>test123</h1>
        <div>p1</div>
    </div>
</div>
<div class="my-item">
    <div class="mac">
        <h2>test456</h2>
        <div>p2</div>
    </div>
</div>

所以我在 JS 之后的 DOM 应该是这样的:

<div class="my-item">
<div class="mac">
    <h1>test123</h1>
    <div data-head="test123">p1</div>
</div>
</div>
<div class="my-item">
<div class="mac">
    <h2>test456</h2>
    <div data-head="test456">p2</div>
</div>
</div>

我试图通过获取所有选择器的列表并遍历列表来做到这一点,但它不会添加数据属性,而且我没有看到任何控制台错误。我相信我这样做的方式是找不到元素:

var items = document.querySelectorAll("div.my-item"); 
for (var i=0, max=items.length; i < max; i++) { 
  var itemH = $( "div.body:first-child" ).find(items[i]); 
  var itemP = $( "div.body:nth-child(2)" ).find(items[i]); 
  itemP.setAttribute('data-head', itemH.text()); 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="my-item">
	<div class="mac">
		<h1>test123</h1>
		<div>p1</div>
	</div>
</div>
<div class="my-item">
	<div class="mac">
		<h2>test456</h2>
		<div>p2</div>
	</div>
</div>

标签: javascripthtmljquerycss

解决方案


当您使用 JQuery 选择器时,它们会返回一个 JQuery 包装的集合对象,它不是 JavaScript 中的本机对象,因此当您尝试调用setAttribute()该 JQuery 对象时,您将在开发人员的控制台中收到一条错误消息。

确实,对于这个问题,JQuery 是矫枉过正的。如果您只是定位各个组的每个第二个子元素并遍历它们,则可以使用APIdata-head更新其属性以包含该div前一个兄弟元素的文本。dataset

// Get all the second child elements within the my-item groups
var items = document.querySelectorAll("div.my-item > div.mac > :nth-child(2)"); 

// Loop over the returned node list with the Array.forEach() API
// which is simpler than for loops because there's no index you
// have to manage.
items.forEach(function(item){
  // Set data-* attribute using the dataSet API
  item.dataset.head = item.previousElementSibling.textContent;
  console.log(item);
});
<div class="my-item">
  <div class="mac">
    <h1>test123</h1>
    <div>p1</div>
  </div>
</div>
<div class="my-item">
  <div class="mac">
    <h2>test456</h2>
    <div>p2</div>
  </div>
</div>


推荐阅读