如何在js中排序嵌套的事件侦听器



我的js中有以下代码:

const someElement = document.getElementById('some-element')

someElement.addEventListener('click', function(){
console.log('The start of main event')

const someOtherElement = document.getElementById('some-other-element')
someOtherElement.addEventListener('load', function () {
console.log("someOtherElement is invoked")
})

console.log("This is the end of main event")
})

如何使此代码完全按照实际编写的代码的顺序运行。我想要以下结果:

主事件的开始

调用someOtherElement

这是主事件的结束


然而,当代码运行时,我得到以下结果:

主事件的开始

这是主事件的结束

调用someOtherElement

加载事件将只调用一次(在元素加载后(。例如,如果您有一个已放置加载事件的图像,则加载事件将在元素加载后仅触发一次。因此,如果在some-other-element已经加载之后单击some-element,则加载事件不会激发。

此外,如果some-other-element在单击some-element之后加载,则它将在The start of main eventThis is the end of main event之后记录someOtherElement invoked

记住:您只能在<body><frame><iframe><img><input type="image"><link><script><style>标记上添加加载事件。

编辑:正如@epascarello在评论中所说,如果您多次单击some-element,它将向some-other-element添加多个事件侦听器。为了解决这个问题,你可以有一个变量:

const someElement = document.getElementById("some-element");
let eventBinded = false;
someElement.addEventListener("click", function () {
console.log("The start of main event");
const someOtherElement = document.getElementById("some-other-element");
if (!eventBinded) {
eventBinded = true;
someOtherElement.addEventListener("load", function () {
console.log("someOtherElement is invoked");
});
} else {
console.log("Event already binded");
}
console.log("This is the end of main event");
});

它是这样运行的,因为这是在两个不同的函数中运行的两个不同事件。要解决此问题,您可以使用异步JavaScript

const someElement = document.getElementById('some-element')
someElement.addEventListener('click', async function(){
var p = new Promise(function(resolve, fail) {
console.log('The start of main event')
const someOtherElement = document.getElementById('some-other-element')
someOtherElement.addEventListener('load', function () {
console.log("someOtherElement is invoked")
resolve(true);
})
});
await p;
console.log("This is the end of main event")
})

最新更新