我试图在点击时显示/隐藏有关名称的更多信息,但不知道如何使其通过单击进行工作。
我正在获取包含游戏相关信息的 JSON,并使用 JS 创建一个 div,如下所示:
fetch("thething.json")
.then(res => res.json())
.then(data =>{
games = data.map(game => {
const newDiv = document.createElement("div");
newDiv.className = "game-info";
newDiv.innerHTML = `
<p onclick="toggler()";>${game.Name}</p>
<div class="info">
<img src="${game.Thumbnail}">
<p>${game.Description}</p>
</div>
`;
document.body.appendChild(newDiv);
JSON 本身有一堆关于游戏的信息,其结构如下:
[{"Name: gamename1,
"Thumbnail: https://imglocation,
"Description": This game is indeed a game
},
{"Name: gamename2,
"Thumbnail: https://imglocation2,
"Description": This game2 is indeed a game2
}
]
切换器函数是这样写的:
function toggler(){
$('div.game-info').click(function(e){
$(this).children('.info').toggle();
});
}
它有点有效,但需要单击一次或多次才能查看附加信息。我知道问题是由于多次 onclick 调用造成的,但不知道如何通过单击来实现。我尝试使用不带切换器功能的 jQuery,但随后它会打开所有名称的信息,而不仅仅是单击的名称。因此,如果有人可以告诉我如何摆脱辅助 onclick 或如何正确定位我在 insideHTML 部分中单击的信息,那就太好了!
代码中的主要问题是因为您正在嵌套事件处理程序,即。原生 JS 和 jQuery 两种。这会导致奇怪的行为,您需要单击多次才能使逻辑产生任何效果。您可以通过仅使用一个事件处理程序在连续单击时隐藏/显示该元素来避免此问题:
另请注意,使用
onclick
属性并不是一个好习惯。事件处理程序应该在 JS 中不显眼地绑定,而不是在 HTML 中。
这是应用上述更改的工作示例:
const game = { Name: 'foo', Thumbnail: 'foo.jpg', Description: 'description' };
const newDiv = document.createElement("div");
newDiv.className = "game-info";
newDiv.innerHTML = `
<p>${game.Name}</p>
<div class="info hide">
<img src="${game.Thumbnail}">
<p>${game.Description}</p>
</div>`;
document.body.appendChild(newDiv);
// bind event handler
const toggler = e => e.target.nextElementSibling.classList.toggle('hide');
document.querySelectorAll('div > p').forEach(p => p.addEventListener('click', toggler));
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
您的
toggle()
函数正在建立点击事件。这就是为什么你必须在任何事情发生之前单击一次,在此之前没有事件侦听器。此外,每次您单击它时,它都会添加一个新的事件处理程序,这就是为什么您会遇到奇怪的重复行为。这就是为什么现在将 javascript 放在 html 中被认为是不好的做法的原因之一,将 javascript 保留在 <script>
标签之间。
此外
$('div.game-info')
正在选择具有 div
类的所有 game-info
,这可能就是它切换所有内容的原因。您可能想要类似 $('div').on('click', '.game-info')
的东西 .on() 方法允许您提供第二个 selector
参数,然后在处理函数中 this
指的是触发事件的特定元素,而不是所有他们。
如果你的项目正在使用 jQuery,不妨使用它!看起来可能是这样的:
$.getJSON('thething.json')
.done(function(data) {
$('body').append(data.map((game) => `
<div class="game-info">
<p class="toggle-info">${game.Name}</p>
<div class="info">
<img src="${game.Thumbnail}" alt="${game.Name} thumbnail">
<p>${game.Description}</p>
</div>
</div>`).join(``))
.find('.info').hide();
})
.fail(function(error) {
//handle errors here
});
$('body')
.on('click', '.toggle-info', function() {
$(this).siblings('.info').slideToggle();
});
$.getJSON() - 假设您的数据源返回有效的 JSON,则
.done()
方法的第一个参数将是已解析的 JSON 对象,无需额外步骤。如果来源无效,您可以使用 .fail()
方法进行处理。
接下来,您不必为每个游戏都改变 DOM,而是可以创建一个巨大的 html 字符串,并且只需要改变 DOM 一次。然后,您可以再次将事件处理程序放在动态添加的 html 的某个父级上(在本例中为
body
),并使用选择器参数来选择应处理该事件的特定元素。