首页 > 解决方案 > 如何在javascript中从多个div中创建一个具有多个并行值的数组?

问题描述

我想将函数应用于多个包装器中的多个 div 对。应按顺序从 2 个不同的类中并行选择 Div。

我能想到的最好的方法是从 n 个模块中创建一个包含 n 对 div 的数组,但我不知道这个概念本身和语法是否正确。

现在,我想同时将函数应用于仅一个模块内的第一个/第二个/第三个/... object-1 和 descript-1 div。下一个模块也是如此,而是应该将函数应用于 object-2 - descript-2 对。

更新代码:

现在我有了三个不同的功能,一个用于下一个按钮,一个用于缩略图控制,最后一个用于显示对象/描述类 div 和突出显示缩略图。我已经尝试了嵌套函数,但它不起作用。modules.forEach我应该在创建 3 个单独的函数之前声明 var 并获取内容吗?

<script>
  // nodes Array
  let modules = Array.prototype.slice.call(document.querySelectorAll(".module"));
	
  // Loop over the modules without index.
  modules.forEach(function(module){
	
  var divIndex = 1;
  showDivs(divIndex);
	
  // Objects, descr, thumbs
  let objects = module.querySelectorAll(".object");
  let descripts = module.querySelectorAll(".descript");
  let thumbs = module.querySelectorAll(".thumb");

  // next-prev buttons
  function plusDivs(n) {
    showDivs(divIndex += n);
  }
	
  // thumb control
  function currentDiv(n) {
    showDivs(divIndex = n);
  }

  // div display
  function showDivs(n) {
    if (n > objects.length) {divIndex = 1}
    if (n < 1) {divIndex = objects.length}
    // hide content, shade thumb
    objects.style.display = "none";
    descripts.style.display = "none";
    thumbs.className = thumbs.className.replace(" active", "");
	
    // show only selected object-descr pair and highlight thumb
    for(var i = 0; i < objects.length; i++) {
      objects[divIndex-1].style.display = "block";
      descripts[divIndex-1].style.display = "block";
      thumbs[divIndex-1].className += " active";
    }
  }
});
</script>
<div class="module">
  <div class="content">LOREM IPSUM 1</div>
	
  <div class="wrapper">
  <div class="content">LOREM IPSUM 1</div>
		
    <div class="object">o1</div>
    <div class="object">o2</div>
    <div class="object">o3</div>

    <div class="descript">d1</div>
    <div class="descript">d2</div>
    <div class="descript">d3</div>
	
    <div class="thumb" onclick="currentDiv(1)">t1</div>
    <div class="thumb" onclick="currentDiv(2)">t2</div>
    <div class="thumb" onclick="currentDiv(3)">t3</div>
		
    <a class="prev" onclick="plusDivs(-1)">X</a>
    <a class="next" onclick="plusDivs(1)">X</a>
   </div>
</div>

<div class="module">
  <div class="content">LOREM IPSUM 2</div>
	
  <div class="wrapper">
  <div class="content">LOREM IPSUM 2</div>
		
    <div class="object">o4</div>
    <div class="object">o5</div>
    <div class="object">o6</div>

    <div class="descript">d4</div>
    <div class="descript">d5</div>
    <div class="descript">d6</div>
		
    <div class="thumb" onclick="currentDiv(1)">t4</div>
    <div class="thumb" onclick="currentDiv(2)">t5</div>
    <div class="thumb" onclick="currentDiv(3)">t6</div>
		
    <a class="prev" onclick="plusDivs(-1)">X</a>
    <a class="next" onclick="plusDivs(1)">X</a>
  </div>
</div>

标签: javascripthtml

解决方案


这是你想要的?见内联评论。另外,不要使用.getElementsByClassName().

// Convert the node list into an Array for the best browser compatibility with Array.forEach()
let modules = Array.prototype.slice.call(document.querySelectorAll("div[class^='module-']"));

// Loop over the modules.
// The Array.forEach() method is much simpler than manual loops because you don't have
// to maintain the loop indexer.
modules.forEach(function(module){

  // Get the objects and descriptions (no arrays needed here because we're just
  // going to need to use indexes against the node lists.
  let objects = module.querySelectorAll("div[class='object']");
  let descriptions = module.querySelectorAll("div[class='descript']");
  
  // Clear out the objects and descriptions in the module.
  // Start by getting all the objects and descriptions into an array.
  let objectsDescriptions = Array.prototype.slice.call(
      module.querySelectorAll("[class='object'], [class='descript']"));
      
  // Then remove each item in the array from the document
  objectsDescriptions.forEach(function(element){ element.parentNode.removeChild(element); });
  
  // Loop the amount of times that matches the number of items in one of the arrays.
  // Here, a regular counting loop makes the most sense because it's all about looping
  // the correct number of times, not looping over DOM elements.
  for(var i = 0; i < objects.length; i++){
    // Repopulate the module with the current child elements, but in the new sequence
    module.insertBefore(objects[i], module.querySelector(".thumb"));
    module.insertBefore(descriptions[i], module.querySelector(".thumb"));
  }
  
  // Set up all the clickable elements to have click event handlers
  module.addEventListener("click", function(evt){
    // Check to see if it was a thumb or a prev/next that was clicked
    if(evt.target.classList.contains("thumb")){
      // Show the div that has the same index as the thumbnail that was clicked
      let thumbs = Array.prototype.slice.call(evt.target.parentNode.querySelectorAll(".thumb"));
      showDiv(evt.target.parentNode, thumbs.indexOf(evt.target));
    } else if(evt.target.classList.contains("prev") || evt.target.classList.contains("next")){
      // Show the div according to the data-offset attribute of the clicked element
      showDiv(evt.target.parentNode, +evt.target.dataset.offset, true);
    } 
  });
  
});

// ****************************************************************
// CODE TO SHOW DIVS
// ****************************************************************

let currentIndex = 0;

// div display
function showDiv(parent, index, nav) {
  // Hide all the objects and descriptions
  let items = parent.querySelectorAll(".object, .descript");
  Array.prototype.slice.call(items).forEach(function(el){
    el.classList.add("hidden");
  });
  
  if(nav){
    currentIndex += index; // Adjust for the offset
    if(currentIndex < 0){
      currentIndex = 0;
    } else if(currentIndex > (items.length / 2) - 1){
      currentIndex = (items.length / 2) - 1;
    }
    // Show just the ones that are supposed to be shown
    parent.querySelectorAll(".object")[currentIndex].classList.remove("hidden");
    parent.querySelectorAll(".descript")[currentIndex].classList.remove("hidden");
  } else {   
    // Show just the ones that are supposed to be shown
    parent.querySelectorAll(".object")[index].classList.remove("hidden");
    parent.querySelectorAll(".descript")[index].classList.remove("hidden");
  }

}
.hidden { display:none; }
.thumb, .prev, .next { cursor:pointer; color:blue; }
<div class="module-1">
    <div class="object">o1</div>
    <div class="object">o2</div>
    <div class="object">o3</div>

    <div class="descript">d1</div>
    <div class="descript">d2</div>
    <div class="descript">d3</div>
    
		<div class="thumb">t1</div>
		<div class="thumb">t2</div>
		<div class="thumb">t3</div>
		
		<span class="prev" data-offset="-1">&lt;</span>
		<span class="next" data-offset="1">&gt;</span>    
</div>

<div class="module-2">
    <div class="object">o4</div>
    <div class="object">o5</div>
    <div class="object">o6</div>

    <div class="descript">d4</div>
    <div class="descript">d5</div>
    <div class="descript">d6</div>
    
		<div class="thumb">t4</div>
		<div class="thumb">t5</div>
		<div class="thumb">t6</div>
		
		<span class="prev" data-offset="-1">&lt;</span>
		<span class="next" data-offset="1">&gt;</span>   
</div>


推荐阅读