首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何向动态创建的元素添加类

如何向动态创建的元素添加类
EN

Stack Overflow用户
提问于 2017-10-13 06:37:35
回答 3查看 530关注 0票数 0

我想将侦听器添加到JavaScript中动态创建的元素中,但它似乎不起作用。它不会抛出任何错误,所以我不知道我首先要做什么。你有什么想法吗?

代码语言:javascript
复制
{
  const API_KEY = "9829fe5eab6c963bbe4850df2d7de4aa";
  const container = document.getElementById("container");
  const flippers = document.getElementsByClassName("header__flipper");
  const cityTemplate = () => {
    const template = `<section class="weather">
      <button class="header__flipper"><span aria-hidden="true">&rarr;</span></button>
      <header class="header">
        <h1 class="header__heading">dfgdfgd
        </h1>
      </header>
    </section>`;
    return template;
  };
  const addListeners = (collection, ev, fn) => {
    for (let i = 0; i < collection.length; i++) {
      collection[i].addEventListener(ev, fn, false);
    }
  }
  const req = (id, key) => {
    const url = `https://api.openweathermap.org/data/2.5/forecast?id=${id}&APPID=${key}`;
    fetch(url).then((res) => {
      res.json().then((data) => {
        container.innerHTML += cityTemplate(data);
      });
    })
  }
  req("6695624", API_KEY);
  req("6695624", API_KEY);
  req("6695624", API_KEY);
  addListeners(flippers, "click", () => {
    alert("test");
  })
}
代码语言:javascript
复制
<div id="container"></div>

EN

Stack Overflow用户

回答已采纳

发布于 2017-10-13 07:42:14

问题是在fetch请求完成之前添加事件侦听器。在调用addListeners时,触发器尚未在DOM中。

我已经修改了req方法,以返回fetch的承诺。使用Promise.all,代码将等待到所有三个获取完成。这仍然不能完全解决问题,代码知道何时完成获取,但这与将req方法添加到DOM中的cityTemplate方法不同。

有两种解决办法:

  1. setTimeout处理程序中使用Promise.all。这很可能会延迟添加事件侦听器足够长的时间,以便将模板添加到DOM中。我添加了一些console.log语句,这些语句将显示上一次呈现的日志行之前的Promise.all日志行。
  2. req方法返回您自己创建的承诺,而不是fetch承诺。在将cityTemplate添加到DOM之后,解析自创建的承诺。通过这种方式,您可以肯定地知道,在所有东西都在DOM中之前,Promise.all是不会实现的。

解决方案1不是一个非常健壮的解决方案,应该避免。解决方案2提供了所需的控制类型。我的答案显示了解决方案2的基本设置,它不执行任何错误处理。

代码语言:javascript
复制
{
  const API_KEY = "9829fe5eab6c963bbe4850df2d7de4aa";
  const container = document.getElementById("container");
  const flippers = document.getElementsByClassName("header__flipper");
  const cityTemplate = () => {
    const template = `<section class="weather">
      <button class="header__flipper"><span aria-hidden="true">&rarr;</span></button>
      <header class="header">
        <h1 class="header__heading">dfgdfgd
        </h1>
      </header>
    </section>`;
    return template;
  };
  const addListeners = (collection, ev, fn) => {
    for (let i = 0; i < collection.length; i++) {
      collection[i].addEventListener(ev, fn, false);
    }
  }
  const req = (id, key) => {
    console.log(`getting ${id}`);
    // Return a new promise, this promise will be fulfilled once the template
    // has been added with the retrieved data.
    return new Promise(resolve => {
      const url = `https://api.openweathermap.org/data/2.5/forecast?id=${id}&APPID=${key}`;
      // Get the data
      fetch(url).then((res) => {
        res.json().then((data) => {
          // Add the template to the DOM
          container.innerHTML += cityTemplate(data);
          console.log(`rendered ${id}`);
          // Relove that promise that was returned by the method.
          resolve();
        });
      })    
    });
  }
  
  // Wait for all three promises to be done. These promises will be fulfilled after
  // the DOM has been updated.
  Promise.all([req("6695624", API_KEY), req("6695624", API_KEY), req("6695624", API_KEY)])
    .then(() => {
      console.log(`promise all done`);
      // There is no longer a need for a timeout, due to the change to the 
      // req method.
      addListeners(flippers, "click", () => {
        alert("test");
      })          
    });
}
代码语言:javascript
复制
<div id="container"></div>

票数 1
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46723864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档