迭代 HTML 个部分

Iteration over HTML sections

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

Indicate whether to send a cookie in a cross-site request by specifying its SameSite attribute

我觉得这应该更简单,有没有更简单的方法来遍历绕过 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>

  1. 您在 if
  2. 中分号过多
  3. 您有重复的 ID - 使用 class
  4. 拼写错误的物种

我添加了一个计数器和一个重置来简化并允许以 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>

@mplungjan 清楚地回答了所有要点的问题。没有什么可添加的。

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

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

关于时间的进一步说明:如果您将此脚本放在 <script> 标签中 在您的 <body><body> 它将开始 运行, 一旦加载 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>