【问题标题】:How would I implement event listeners instead of inline html event handlers in this Javascript example?在这个 Javascript 示例中,我将如何实现事件侦听器而不是内联 html 事件处理程序?
【发布时间】:2021-02-09 02:34:08
【问题描述】:

我试图从一个提供电影列表的 API 获取数据,这就是我实现结果呈现的方式。

const getAllData = async () => {
const movieData = await getMovies()
const movieContainer = movieData.map((movie)=> {
    const listItem = `
    <li class="movie">
        <img src="${movie.Poster}"></img>
        <h1>
            ${movie.Title}
        </h1>
        <h2>Release Year: ${movie.Year}</h2>
        <p>
            <button onclick="getDetails('${movie.imdbID}')">
            Click for more details
            </button>
        </p>
        </li>
    `;  
    return listItem
}).join('')
document.getElementById("movieList").innerHTML = movieContainer;
 }

这里是按钮点击调用的getDetails函数。

function getDetails(id){
sessionStorage.setItem('movieId', id);
window.location = 'movie.html';
return false;}

此代码按预期工作。但是,我遇到的问题是我想用事件侦听器而不是内联 HTML 事件处理程序来实现这个逻辑。我怎么能实现这个? 我是否需要对当前代码进行任何重大更改?

【问题讨论】:

  • 请注意,这种方法很容易受到 HTML 字符串注入的 XSS 攻击。

标签: javascript async-await scope event-handling


【解决方案1】:

创建一个&lt;li&gt; 元素而不是HTML 字符串,然后使用querySelector 选择按钮后代,您可以使用addEventListener

const getAllData = async () => {
    const movieData = await getMovies();
    const ul = document.getElementById("movieList");
    for (const movie of movieData) {
        const li = ul.appendChild(document.createElement('li'));
        li.className = 'movie';
        li.innerHTML = `
            <img src="${movie.Poster}"></img>
            <h1>
                ${movie.Title}
            </h1>
            <h2>Release Year: ${movie.Year}</h2>
            <p>
                <button>
                Click for more details
                </button>
            </p>
        `;
        li.querySelector('button').addEventListener('click', () => {
            getDetails(movie.imdbID);
        });
    }
};

我还强烈建议不要将外部输入直接连接到 HTML 字符串中,例如

<img src="${movie.Poster}"></img>

除非输入是绝对可信的,否则会导致任意代码执行,这是一种安全风险。如果您还没有这样做,我建议您验证插值的格式是否正确(例如,没有任何会导致 HTML 标记的内容,例如 &lt;script&gt; 标签),或者在之后分配动态属性/属性&lt;li&gt; 已填充基本模板。

【讨论】:

  • 非常感谢!我阅读了将 API 直接连接到 html 的问题,并对其进行了修改以防止任何 html 攻击。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-16
  • 1970-01-01
  • 1970-01-01
  • 2018-01-23
  • 1970-01-01
  • 2013-01-11
  • 1970-01-01
相关资源
最近更新 更多