在 DOMContentLoaded 上的函数 javascript 中声明全局常量
Declare global constants in function javascript on DOMContentLoaded
有没有什么方法可以在 DOMContentLoaded 事件触发时声明可在外部访问的常量?
window.addEventListener('DOMContentLoaded', () => {
const button = document.getElementById("button")
})
someObject.on("EventThatWillOnlyOccurAfterDOMContentLoads", () => {
console.log(button.innerHTML) // ReferenceError
})
如果问题是:“有没有办法声明一个没有值的常量变量,然后再给它赋值?”,那么答案是没有.
再想一想:声明后,常量变量的值必须始终相同;这就是创建常量的重点。
如果您能够创建这样的变量,那么它就不会真正保持不变。看这个例子:
const button //This would throw a SyntaxError but assume it doesn't
window.addEventListener('DOMContentLoaded', () => {
button = document.getElementById("button")
})
someObject.on('EventThatMayOccurEitherBeforeOrAfterDOMContentLoaded', () => {
//We are unsure what button is here: it might be a DOM node or undefined, or... what?
console.log(button)
})
因此,您不能以这种方式在全局范围内创建常量。但是为什么要在全局范围内声明呢?
如果您知道第二个事件不会在 DOMContentLoaded
之前触发,那么只需将其声明 移到 中,如下所示:
window.addEventListener('DOMContentLoaded', () => {
const button = document.getElementById("button")
someObject.on("EventThatWillOnlyOccurAfterDOMContentLoads", () => {
console.log(button.innerHTML) // Works perfectly
})
})
这种方法至少和你想要的一样好,如果不是更好的话:
将所有变量保存在事件侦听器中:
- 完全避免了全局范围的污染(像一些使用的 IIFE)
- 仅在页面加载后才使您的代码 运行,因此您不必担心无法访问 DOM 元素。
然而,如果您无法将所有代码移动到 DOMContentLoaded
(例如,因为您想要监听一个在它之前触发的事件),您还有一个选择:利用 ES6 的异步结构,即所谓的 Promises。
通过使用它们,您的代码可以等待给定事件(在您的情况下,DOMContentLoaded
),而无需将该代码移入其侦听器,并且即使第二个事件被多次发出也能正常工作次数:
const button = new Promise(setButton => {
window.addEventListener('DOMContentLoaded', () => {
//Resolve the promise when we get the value:
setButton(document.getElementById("button"))
})
})
someObject.on('EventThatMayOccurEitherBeforeOrAfterDOMContentLoaded', () => {
//This will wait for the promise to resolve if it hasn't done so yet:
button.then(button => {
console.log(button.innerHTML)
})
})
这种方法可能看起来更复杂,但是当您的代码变成异步时,在任何地方使用 promises 可以简化您的生活。
另请注意,这种方法有其局限性,例如,您不能嵌套其中的两个承诺(如果您尝试这样做,您会发现自己处于与您询问的情况类似的情况中):
const button = new Promise(setButton => {
//How to make this one global as well?
const anotherButton = new Promise(setAnotherButton => {
window.addEventListener('DOMContentLoaded', () => {
setButton(document.getElementById("button"))
setAnotherButton(document.getElementById("button2"))
})
})
})
相反,您可以将所有 DOM 个元素收集到一个对象中,并用它解决您的承诺:
const DOMElements = new Promise(resolve => {
window.addEventListener('DOMContentLoaded', () => {
//Resolve the promise when we get the value:
resolve(Object.freeze({
button: document.getElementById("button"),
anotherButton: document.getElementById("button2")
}))
})
})
someObject.on('EventThatMayOccurEitherBeforeOrAfterDOMContentLoaded', () => {
//Destructure button:
button.then(({button}) => {
console.log(button.innerHTML)
})
})
有没有什么方法可以在 DOMContentLoaded 事件触发时声明可在外部访问的常量?
window.addEventListener('DOMContentLoaded', () => {
const button = document.getElementById("button")
})
someObject.on("EventThatWillOnlyOccurAfterDOMContentLoads", () => {
console.log(button.innerHTML) // ReferenceError
})
如果问题是:“有没有办法声明一个没有值的常量变量,然后再给它赋值?”,那么答案是没有.
再想一想:声明后,常量变量的值必须始终相同;这就是创建常量的重点。
如果您能够创建这样的变量,那么它就不会真正保持不变。看这个例子:
const button //This would throw a SyntaxError but assume it doesn't
window.addEventListener('DOMContentLoaded', () => {
button = document.getElementById("button")
})
someObject.on('EventThatMayOccurEitherBeforeOrAfterDOMContentLoaded', () => {
//We are unsure what button is here: it might be a DOM node or undefined, or... what?
console.log(button)
})
因此,您不能以这种方式在全局范围内创建常量。但是为什么要在全局范围内声明呢?
如果您知道第二个事件不会在 DOMContentLoaded
之前触发,那么只需将其声明 移到 中,如下所示:
window.addEventListener('DOMContentLoaded', () => {
const button = document.getElementById("button")
someObject.on("EventThatWillOnlyOccurAfterDOMContentLoads", () => {
console.log(button.innerHTML) // Works perfectly
})
})
这种方法至少和你想要的一样好,如果不是更好的话:
将所有变量保存在事件侦听器中:
- 完全避免了全局范围的污染(像一些使用的 IIFE)
- 仅在页面加载后才使您的代码 运行,因此您不必担心无法访问 DOM 元素。
然而,如果您无法将所有代码移动到 DOMContentLoaded
(例如,因为您想要监听一个在它之前触发的事件),您还有一个选择:利用 ES6 的异步结构,即所谓的 Promises。
通过使用它们,您的代码可以等待给定事件(在您的情况下,DOMContentLoaded
),而无需将该代码移入其侦听器,并且即使第二个事件被多次发出也能正常工作次数:
const button = new Promise(setButton => {
window.addEventListener('DOMContentLoaded', () => {
//Resolve the promise when we get the value:
setButton(document.getElementById("button"))
})
})
someObject.on('EventThatMayOccurEitherBeforeOrAfterDOMContentLoaded', () => {
//This will wait for the promise to resolve if it hasn't done so yet:
button.then(button => {
console.log(button.innerHTML)
})
})
这种方法可能看起来更复杂,但是当您的代码变成异步时,在任何地方使用 promises 可以简化您的生活。
另请注意,这种方法有其局限性,例如,您不能嵌套其中的两个承诺(如果您尝试这样做,您会发现自己处于与您询问的情况类似的情况中):
const button = new Promise(setButton => {
//How to make this one global as well?
const anotherButton = new Promise(setAnotherButton => {
window.addEventListener('DOMContentLoaded', () => {
setButton(document.getElementById("button"))
setAnotherButton(document.getElementById("button2"))
})
})
})
相反,您可以将所有 DOM 个元素收集到一个对象中,并用它解决您的承诺:
const DOMElements = new Promise(resolve => {
window.addEventListener('DOMContentLoaded', () => {
//Resolve the promise when we get the value:
resolve(Object.freeze({
button: document.getElementById("button"),
anotherButton: document.getElementById("button2")
}))
})
})
someObject.on('EventThatMayOccurEitherBeforeOrAfterDOMContentLoaded', () => {
//Destructure button:
button.then(({button}) => {
console.log(button.innerHTML)
})
})