我的部分内部有一个部分,其中有单选按钮
或复选框
。我想要做的是获取被单击的单选按钮或复选框。现在,最初加载页面时,我能够获取按钮,但是当我转到下一部分时,我无法获取新按钮。每次在单独的js中单击某个按钮时,如何获取新部分的按钮。如果我使用与单选按钮
或checkbox
内联的onclick
函数,那么该函数被正确调用,但我想在单独的中获取当前显示的元素js 文件。
我尝试使用window.addEventListener('change')
。如果我使用它,那么该函数不会在第一次单击时被调用,但在随后的单击中它会调用很多次,即,在第二次单击时,该函数被调用一次,在第三次单击时,该函数被调用两次,依此类推。
// window.addEventListener('change', () => {
window.addEventListener('DOMContentLoaded', () => {
if (document.querySelectorAll('[name="question[answer_id]"]').length !== 0) {
document.querySelectorAll('[name="question[answer_id]"]').forEach((questionAnswerButton) => {
questionAnswerButton.addEventListener('click', (event) => {
console.log(event);
fetchCall(event.target.value);
});
});
}
});
radio_button_partial.html.erb
<%= radio_button_tag 'question[answer_id]',
answer.id,
(user_answer == answer.id),
{
class: 'answer_opt',
// onclick: fetchCall("<%= answer.id %>")
} %>
在这里,如果我取消注释 onclick 函数,那么我将获得所需的功能。但是我应该对此进行什么更改才能从单独的 js 文件中获取当前显示的单选按钮?
最佳答案
不要将监听器直接附加到要使用事件冒泡的元素:
document.addEventListener('click', (event) => {
if (event.target.matches('[name="question[answer_id]"]')) {
console.log(event);
fetchCall(event.target.value);
}
});
当一个事件被触发时,它会在 DOM 中冒泡,直到找到处理程序。与将事件处理程序直接附加到元素不同,这是幂等的,并且处理程序将对动态插入到页面中的元素起作用。它还与 Turbolink 兼容。
此代码不应放置在脚本标记或 .js.erb
中,因为每次执行代码时它都会添加一个处理程序。将其放入 Assets 管道中。
如果 fetchCall
执行 ajax 调用,您将需要使用去抖动技术,例如禁用输入并在 the promise 时重新启用它。已解决。
document.addEventListener('click', (event) => {
if (event.target.matches('[name="question[answer_id]"]')) {
console.log(event);
// Todo refactor fetchCall so that it returns a promise
let promise = fetchCall(event.target.value);
event.target.disabled = true;
promise.then((successMessage) => {
event.target.disabled = false;
});
}
});
关于javascript - 每次由 Rails 中的 Vanilla Javascript 加载部分时查询选择元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60258705/