【问题标题】:Iteration over HTML sections迭代 HTML 部分
【发布时间】:2022-01-15 07:25:49
【问题描述】:

我想遍历我的 HTML 中的三个元素,更改每个部分的属性,一次一个部分。我想我会得到一个带有 querySelectorAll 的 NodeList,然后使用带有 NodeList 的计数器进行迭代。它仅在第一部分有效,并返回此错误消息:

通过指定其 SameSite 属性指示是否在跨站点请求中发送 cookie

我觉得这应该更简单,有没有更简单的方法来遍历绕过 cookie 问题的部分?

const button = document.querySelector('button');

generateRandom = () => {
  return Math.floor(Math.random() * 826);
}

getCharacters = () => {
  var sections = document.querySelectorAll('section');

  for (var i = 0; i < 4; i++;) {
    let randomNumber = generateRandom();

    return fetch(`https://rickandmortyapi.com/api/character/${randomNumber}`, {
      method: 'GET',
      headers: {
        Accept: 'application/json',
        "Content-type": 'application/json'
      }
    }).then((response) => response.json()).then((data) => {
      let section = sections[i];
      let image = section.querySelector('img');
      let characterName = section.querySelector('#name');
      let especie = section.querySelector('#species');
      let state = section.querySelector('#status');
      image.src = data.image;
      image.alt = data.name;
      characterName.innerHTML = data.name
      species.innerHTML = data.species;
      state.innerHTML = data.status;
    })
  }
}

button.onclick = getCharacters;
<main>
  <section>
    <img alt="Smiling Rick" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfO2QcnGNdEZnWgjmwCDTUN1okIqAlXt5UkwZEl7qui4Poc-vO">
    <ul id="config-container">
      <li>Name:
        <p id="name"></p>
      </li>
      <li>Species:
        <p id="species"></p>
      </li>
      <li>Status:
        <p id="status"></p>
      </li>
    </ul>
  </section>
  <section>
    <img alt="Rick and Morty logo" src="https://www.baconfrito.com/wp-content/uploads/2017/10/rick-morty-title.jpg">
    <ul id="config-container">
      <li>Name:
        <p id="name"></p>
      </li>
      <li>Species:
        <p id="species"></p>
      </li>
      <li>Status:
        <p id="status"></p>
      </li>
    </ul>
    <button>Click to see more characters</button>
  </section>
  <section>
    <img alt="Smiling Morty" src="https://static.wikia.nocookie.net/rickandmorty/images/e/ee/Morty501.png/revision/latest/top-crop/width/360/height/360?cb=20210827150137">
    <ul id="config-container">
      <li>Name:
        <p id="name"></p>
      </li>
      <li>Species:
        <p id="species"></p>
      </li>
      <li>Status:
        <p id="status"></p>
      </li>
    </ul>
  </section>
</main>

【问题讨论】:

  • 你的 html 是什么样的?
  • 添加了 HTML 代码,tks

标签: javascript html loops iteration samesite


【解决方案1】:
  1. if 中的分号过多
  2. 您有重复的 ID - 使用类
  3. 拼错的物种

我添加了一个计数器和一个重置来简化并允许 fetch 以 100 毫秒的延迟运行

注意 window.addEventListener 在运行点击脚本之前等待页面加载

const generateRandom = () => {
  return Math.floor(Math.random() * 826);
}
const sections = document.querySelectorAll('section');
let cnt = 0;
let tId;

const getCharacters = () => {
  if (cnt == sections.length) return;
  let randomNumber = generateRandom();

  fetch(`https://rickandmortyapi.com/api/character/${randomNumber}`, {
    method: 'GET',
    headers: {
      Accept: 'application/json',
      "Content-type": 'application/json'
    }
  }).then((response) => response.json()).then((data) => {
    let section = sections[cnt];
    let image = section.querySelector('img');
    let characterName = section.querySelector('.name');
    let species = section.querySelector('.species');
    let state = section.querySelector('.status');
    image.src = data.image;
    image.alt = data.name;
    characterName.innerHTML = data.name
    species.innerHTML = data.species;
    state.innerHTML = data.status;
    cnt++;
    tId = setTimeout(getCharacters, 100); // fetch again in 100 milliseconds
  })
}

window.addEventListener("load", function() {
  const button = document.querySelector('button');


  button.addEventListener("click", function() {
    cnt = 0; // start from 0
    clearTimeout(tId); // stop any running process
    getCharacters();
  })
  getCharacters(); // initialise
})
<main>
  <button>Click to see more characters</button>

  <section>
    <img alt="Smiling Rick" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfO2QcnGNdEZnWgjmwCDTUN1okIqAlXt5UkwZEl7qui4Poc-vO">
    <ul class="config-container">
      <li>Name:
        <p class="name"></p>
      </li>
      <li>Species:
        <p class="species"></p>
      </li>
      <li>Status:
        <p class="status"></p>
      </li>
    </ul>
  </section>
  <section>
    <img alt="Smiling Rick" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfO2QcnGNdEZnWgjmwCDTUN1okIqAlXt5UkwZEl7qui4Poc-vO">
    <ul class="config-container">
      <li>Name:
        <p class="name"></p>
      </li>
      <li>Species:
        <p class="species"></p>
      </li>
      <li>Status:
        <p class="status"></p>
      </li>
    </ul>
  </section>
</main>

【讨论】:

  • 感谢您指出 1、2 和 3。已修复这些问题。我仍然只得到第一个字符,而不是其他两个。
  • 已修复 - 为 fetch 添加了一个计数器
  • 泰!现在我收到这个错误:“Uncaught ReferenceError: getCharacters is not defined at HTMLButtonElement. (script.js:40:9)”另外,我想我应该明确表示我打算让按钮改变所有一键三个部分,并在每次单击时继续执行。我应该编辑问题以添加它吗?感谢您的耐心等待。
  • 如您所见,我发布的脚本正是这样做的。也许您没有将其正确粘贴到您的页面中?我需要出去一个小时
  • 解决了!非常感谢!
【解决方案2】:

@mplungjan 在所有方面都清楚地回答了这个问题。没有什么可添加的。

但是,我有一些空闲时间并想出了这个也应该有效的替代解决方案:

它提供所有 (numc) 字符的随机非重复序列,并且可以扩展到任意数量的显示部分 (nums)。

关于时间的进一步说明:如果您将此脚本放在&lt;script&gt; 标记中 您的&lt;body&gt; 中,它将在加载 DOM 后立即开始运行。

function shfl(a){ // Durstenfeld shuffle
 for(let j,i=a.length;i>1;){
  j=Math.floor(Math.random()*i--);
  if (i!=j) [a[i],a[j]]=[a[j],a[i]]
 }
 return a
}
const numc=826,nums=2; // 826 characters, 2 sections

// random sequence of all characters:
const seq=shfl([...new Array(numc)].map((_,i)=>i));

// Create the `nums` section elements and store 
// them in an array of objects, together with 
// their IMG and P child nodes:
const sects=[document.querySelector("section")];
for(let i=1; i<nums; i++)
 sects[i-1].after(sects[i]=sects[0].cloneNode(true));
sects.forEach(s=>{
 ["img","p"].forEach(e=>s[e]=s.querySelectorAll(e));
});
sects.i=0;

// define button-click event:
(document.querySelector('button').onclick=ev=>{ 
 sects.forEach(s=>{
  fetch(`https://rickandmortyapi.com/api/character/${seq[sects.i++%numc]}`).then(t=>t.json()).then(j=>{
   s.img[0].title=j.name;
   s.img[0].src=j.image;
   s.p.forEach(e=>e.textContent=j[e.className]);
  })
 })
})() // make it an IIFE, thereby running immediately at start-up
<main>
  <button>Click to see more characters</button>
  <section>
    <img>
    <ul class="config-container">
      <li>Name:
        <p class="name">name</p>
      </li>
      <li>Species:
        <p class="species">species</p>
      </li>
      <li>Status:
        <p class="status">status</p>
      </li>
    </ul>
  </section>
</main>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-07
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    相关资源
    最近更新 更多