如何从隐藏/显示中删除其中一个点击?

问题描述 投票:0回答:2

我试图在点击时显示/隐藏有关名称的更多信息,但不知道如何使其通过单击进行工作。

我正在获取包含游戏相关信息的 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 部分中单击的信息,那就太好了!

javascript jquery onclick
2个回答
1
投票

代码中的主要问题是因为您正在嵌套事件处理程序,即。原生 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>


0
投票

您的

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
),并使用选择器参数来选择应处理该事件的特定元素。

© www.soinside.com 2019 - 2024. All rights reserved.