在这个Javascript示例中,我如何实现事件侦听器而不是内联html事件处理程序?



我试图从一个给我一个电影列表的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事件处理程序。我该如何实现呢?我是否需要对我当前的代码做任何剧烈的改变?

创建一个<li>元素而不是一个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标记的东西,如<script>标记),要么在<li>填充了基本模板后分配动态属性/属性。

最新更新