这个问题更多的是看我是否可以从我尝试在此处实现的“设计模式”中获得一些输入。我只是在学习JavaScript闭包,我想我已经开始了解它了。我想知道我编写此代码的方式是否质量好-您希望在生产代码中看到这种东西,或者至少有些“拼凑在一起”的东西。显然对任何批评开放-在这里学习。
有问题的代码正试图回答JavaScript中提出的挑战:Front Masters上的Hard部分(由Will Sentance撰写)。基于挑战,似乎我超越了要求,因为所提供的解决方案在运行时无法正常工作。
挑战:
编写一个函数changeColor,该函数在被调用时将首先检查是否 当前页面背景颜色为“ rgb(221,238,255)”。如果是的话 将颜色更改为“ rgb(255,238,221)”。如果不是,它将设置 颜色改为“ rgb(221,238,255)”。
将点击事件监听器添加到上方的按钮#1(其ID为 “启用”)。单击后,该按钮应登录到控制台 1“。它还应该在按钮#2(ID为“ color”)上设置点击事件监听器。该监听器应登录控制台“ clicked 2”,然后 调用刚刚创建的changeColor函数。
清除控制台,然后点击“使用JS运行”按钮。看什么代码 通过分析控制台来运行。然后尝试更改背景 单击按钮#2进行颜色显示。该按钮需要发生什么 工作吗?
基于挑战的措辞,似乎暗示的解决方案是(使用伪ish代码):
activationButton.addEventListener("click", () => {
console.log("clicked activation button")
colorChangerButton.addEventListener("click", () => {
console.log("clicked color changer button")
changeTheColor()
})
})
上述代码的明显问题是,每次您单击colorChangerButton
时,都会将一个新的事件侦听器添加到activationButton
中。在这里,我开始考虑尝试使用闭包来跟踪状态变量,以便可以确保将事件侦听器仅添加到第二个按钮一次。同样,这是解决方案集中提供的解决方案。
为此,这就是我想出的(请假设那里有正确的HTML等):
(function () {
let clickCount = 0
function changeColor() {
if (document.body.style.backgroundColor === "rgb(221, 238, 255)") {
document.body.style.backgroundColor = "rgb(255, 238, 221)"
} else {
document.body.style.backgroundColor = "rgb(221, 238, 255)"
}
}
function activateButton2() {
const btn2 = document.querySelector('#color')
btn2.addEventListener("click", () => {
console.log("clicked #2")
changeColor()
})
}
const btn1 = document.querySelector('#activate')
btn1.addEventListener("click", () => {
clickCount++
if (clickCount === 1) {
activateButton2()
}
console.log("clicked #1")
return
})
return {
changeColor: changeColor,
activateButton2: activateButton2
}
})()
这是我期望的那样工作-颜色更改功能和控制台日志正在按我期望的方式触发。
我的一个问题是关于将按钮变量包含在IIFE中。我觉得我看到很多前端脚本都将所有查询选择器放在脚本顶部–与将它们包括在这样的函数中相比,有理由这样做吗?如果我正确地理解了闭包,那么一旦创建了事件处理程序,就会对IIFE中的所有内容进行持久引用,因此我可以触发此函数,并且按钮及其处理程序将继续存在并按预期运行。
似乎我也可以使用布尔值来跟踪第一个按钮的“单击”状态,并使用switch语句来检查页面的背景色。
任何人想提供的其他指针吗?预先感谢您的浏览。