JavaScript的“onclick”只能执行一次。

3
我正在用Javascript制作类似点击器的东西,“onclick”只能在刷新页面之前起作用一次。
我的HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
    <div id="main">
        <button id="o"> Click Me</button>
    </div>
    <script type="module" src="/main.js"></script>
</body>
</html>

JS 代码:

import './style.css';

let x = 0;

document.querySelector('#main').innerHTML = `
    <button id="o">Click Me</button>
    <p>${x}</p>
`;

document.querySelector("#o").onclick = function() {
    x++;
    console.log(x);
    document.querySelector('#main').innerHTML = `
        <button id="o">Click Me</button>
        <p>${x}</p>
    `;
};

当我打开控制台时,只有在我第一次点击按钮时才会看到日志“1”,之后就不再显示了。没有CSS样式。
我正在使用Vite来完成这个任务。

5
这是因为您正在将元素重新插入到DOM中,初始事件不再附加到这些新按钮上。现在,一切都取决于您想要完成的任务是什么。再次重新插入一个新按钮似乎是一件相当奇怪的事情。 - Roko C. Buljan
5
这是因为您正在将元素重新插入到DOM中,初始事件不再附加到这些新按钮上。现在一切取决于您想要完成的任务是什么。重新再次插入一个新按钮似乎是一件相当奇怪的事情。 - Roko C. Buljan
5
这是因为您正在将元素重新插入到DOM中,初始事件不再与这些新按钮关联。现在,一切取决于您想要完成的任务是什么。重新再次插入一个新按钮似乎是一件相当奇怪的事情。 - undefined
1
不要使用innerHTML来设置新的按钮,而是使用appendChild - 0stone0
1
不要使用innerHTML来设置新的按钮,而是使用appendChild - 0stone0
显示剩余2条评论
1个回答

0
你只是给现有的按钮添加了点击事件。 然后,你(出于某种未知的原因)重新插入了一个类似的元素,并期望它具有附加的事件。你需要的是事件委托,即将监听器附加到静态元素上,然后在函数内部检查实际的 event.target。 此外,保持你的代码DRY(不要重复自己),并将模板创建放在一个单独的函数中:

let x = 0;
const elMain = document.querySelector('#main');
const updateMainHTML = () => elMain.innerHTML = `
  <button id="o">Click Me</button>
  <p>${x}</p>
`;

elMain.addEventListener("click", (evt) => {
  if (!evt.target.closest("#o")) return; // Do nothing. Not our button
  x++;
  updateMainHTML();
});

updateMainHTML();
<div id="main">
  <button id="o"> Click Me</button>
</div>

我不知道为什么你想要在每次点击后动态插入元素。
这就是实现完全相同的用户界面所需的全部内容。

let x = 0;

const elMain = document.querySelector('#main');

const elResult = Object.assign(document.createElement("p"), {
  textContent: x
});

const elBtn = Object.assign(document.createElement("button"), {
 type: "button",
 textContent: "Click me",
 onclick() {
   x += 1;
   elResult.textContent = x;
 }
});

elMain.append(elBtn, elResult);
<div id="main"></div>

或者是超基本的 - 没有任何动态元素插入:

let x = -1;

const elButton = document.querySelector('#o');
const elResult = document.querySelector('#result');
const incrementX = () => {
  x += 1;
  elResult.textContent = x;
};

incrementX(); // Do it immediately
elButton.addEventListener("click", incrementX); // and on btn click
<div id="main">
  <button type="button" id="o">Click me</button>
  <p id="result">0</p>
</div>


一个网站问题:&lt;button&gt;...&lt;/button&gt;&lt;button type=&#39;button&#39;&gt;...&lt;/button&gt;之间有什么区别? - Reporter
一个网站问题:<button>...</button><button type='button'>...</button>之间有什么区别? - Reporter
2
在这种情况下没有任何区别。但是如果你将它用在表单中,按钮将不会提交。 - Wimanicesir
2
在这种情况下没有任何区别。但是如果你将它用在表单中,按钮将不会提交。 - Wimanicesir
正如Wimanicesir所说,<button>默认情况下是type=submit。严格来说,将按钮设置为type=button是一种良好的习惯,以便于记忆(除非需要用于提交表单等情况 - 换句话说,它的默认提交类型)。 - Roko C. Buljan
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接