简体   繁体   English

如何使用 for 循环编写这些 js 代码?

[英]How can I write these js codes with for loop?

I have 3 buttons and 3 content.我有 3 个按钮和 3 个内容。 When I click on any button, I want to show the content of that button.当我单击任何按钮时,我想显示该按钮的内容。 When I click on the other button, I want to show the content of that button and delete the content of the other button.当我单击另一个按钮时,我想显示该按钮的内容并删除另一个按钮的内容。

I managed to do this with simple logic, but how can I do it with a for loop?我设法用简单的逻辑做到了这一点,但我怎么能用 for 循环做到这一点?

照片

const content = document.querySelectorAll('.content');
const contentClose = document.querySelector('.close-content');
const btnsOpenContent = document.querySelectorAll('.show-content');


btnsOpenContent[0].addEventListener('click',
  function() {
    content[1].classList.remove('show-modal');
    content[2].classList.remove('show-modal');
    content[0].classList.add('show-modal');
  }
)

btnsOpenContent[1].addEventListener('click',
  function() {
    content[0].classList.remove('show-modal');
    content[2].classList.remove('show-modal');
    content[1].classList.add('show-modal');
  }
)

btnsOpenContent[2].addEventListener('click',
  function() {
    content[0].classList.remove('show-modal');
    content[1].classList.remove('show-modal');
    content[2].classList.add('show-modal');
  }
)

Use simple forEach loops along with classList.toggle(className: string, force: boolean) :使用简单的forEach循环和classList.toggle(className: string, force: boolean)

const content = document.querySelectorAll('.content');
const contentClose = document.querySelector('.close-content');
const btnsOpenContent = document.querySelectorAll('.show-content');

btnsOpenContent.forEach((btn, index) => {
  btn.addEventListener('click', () => {
    content.forEach((cnt, idx) => cnt.classList.toggle('show-modal', idx === index))
  })
})

I strongly suggest to delegate , which means instead of adding a listener to each and every button, you instead capitalize on the bubbling mechanism of events, listening to clicks instead on just one common ancestor element of all buttons.我强烈建议使用delegate ,这意味着不是为每个按钮添加一个监听器,而是利用事件的冒泡机制,只在所有按钮的一个共同祖先元素上监听点击。 Then inside the click handler you implement a guard that checks if the click actually came from a button.然后在点击处理程序中实现一个守卫,检查点击是否真的来自按钮。

Note I added hidden to the last two content to start with content 1注意我在最后两个内容中添加了隐藏以从内容 1 开始

You can also add active to the button that was clicked and remove from the siblings您还可以将活动添加到单击的按钮并从兄弟姐妹中删除

NOTE: This code does not change no matter how many buttons as long as there is a matching number of content divs.注意:只要有匹配数量的内容 div,无论有多少按钮,此代码都不会更改。

Also note there is no need for a class to show and hide另请注意,无需显示和隐藏类

Lastly note I implemented your close too最后注意我也实现了你的关闭

 const nav = document.getElementById("nav"); const contents = document.getElementById("contents"); const buttons = nav.querySelectorAll("#nav .show-content"); const contentDivs = contents.querySelectorAll("div.content") nav.addEventListener("click", e => { const tgt = e.target; // what was clicked? if (!tgt.matches(".show-content")) return; // not a button buttons.forEach((but,i) => contentDivs[i].hidden = but !== tgt); // hide if not the content that belongs to button }) contents.addEventListener("click", e => { const tgt = e.target; if (!tgt.matches(".close")) return; // not a button tgt.closest("div").hidden = true; // hide the div the close button is in })
 <div id="nav"> <button class="show-content">Show 1</button> <button class="show-content">Show 2</button> <button class="show-content">Show 3</button> </div> <div id="contents"> <div class="content">Content 1 <button class="close">X</button></div> <div class="content" hidden>Content 2 <button class="close">X</button></div> <div class="content" hidden>Content 3 <button class="close">X</button></div> </div>

The most important thing to note is that querySelectorAll does not return an array, and instead returns a NodeList.最需要注意的是querySelectorAll不返回数组,而是返回一个NodeList。 ES6 has introduced a handy method that is intended for this exact purpose NodeList.prototype.forEach() . ES6 引入了一个方便的方法,专门用于此目的NodeList.prototype.forEach()

The easiest approach in my experience to create tabbed content is to add some sort of identifier for each ".content" tab on the button triggering the event.根据我的经验,创建选项卡式内容的最简单方法是为触发事件的按钮上的每个“.content”选项卡添加某种标识符。 the "data" attribute is often used for this, however, there several other options. “数据”属性通常用于此,但是,还有其他几个选项。

An example of your button html using the data attribute would look like the following:使用 data 属性的按钮 html 示例如下所示:

<button class="show-content" data-content="content1">Show content 1</button>
<button class="show-content" data-content="content2">Show content 2</button>
<button class="show-content" data-content="content3">Show content 3</button>

For this technique your content HTML would need an id that matches the identifier used on your buttons:对于这种技术,您的内容 HTML 将需要一个与按钮上使用的标识符匹配的 id:

<div class="content" id="content1">Some content for 1</div>
<div class="content" id="content2">Some content for 2</div>
<div class="content" id="content3">Some content for 3</div>

And the corresponding javascript would look similar to below:相应的 javascript 如下所示:

const btnsOpenContent = document.querySelectorAll('.show-content');

btnsOpenContent.forEach((button) => {
  button.addEventListener('click', (event) => {
    let contentId = event.target.getAttribute('data-content');
    let targetContent = document.getElementById(contentId);

    // Hide all contents
    document.querySelectorAll('content').forEach((element) => {
      element.classList.remove('show-modal');
    })

    // Show selected content
    targetContent.classList.add('show-modal');
  });
});

This code can even be shortened:这段代码甚至可以缩短:

const btnsOpenContent = document.querySelectorAll('.show-content');

btnsOpenContent.forEach((button) => {
  button.addEventListener('click', (event) => {
    let contentId = event.target.dataset.content;
    let targetContent = document.getElementById(contentId);

    document.querySelectorAll('content').forEach((element) => {
      element.classList.toggle('show-modal', contentId === element.id);
    })

  });
});

Maybe something like this?也许是这样的?

const content = document.querySelectorAll('.content');
const contentClose = document.querySelector('.close-content');
const btnsOpenContent = document.querySelectorAll('.show-content');

for (let i = 0; i <= 2; i++) {
  btnsOpenContent[i].onclick = () => {
    for (let j = 0; j <= 2; j++) {
      i == j ? content[j].classList.add('show-modal') : content[j].classList.remove('show-modal');
    }
  };
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM