对不起,标题。我只是看到一些我想了解的有趣行为。代码:
var element;
var testFunction = (function() {
var mount = false;
return {
act: function() {
if (mount == false) {
element = $("#element")
element.click(function() {
console.log("detected click")
})
mount = true
}
}
}
})();
对我来说很重要,testFunction.act
中的操作仅运行一次,因此使用mount
。这样实现的众多用例之一是,在测试代码中,如果我们多次调用testFunction.act
,则不会附加多个单击处理程序,这将是一个问题,因为您只希望触发单击。 ,而不是多个。
但是mount
的存在引起了另一种现象,即只有第一个规范通过。
规格:
fdescribe("testFunction", function() {
beforeAll(function() {
element_spec = affix("#element")
testFunction.act();
})
describe("first spec", function() {
beforeEach(function() {
console.log("first spec")
console.log(element.length)
element_spec.click()
})
it("should write in console", function() {
})
})
describe("second spec", function() {
beforeEach(function() {
console.log("second spec")
console.log(element.length)
element_spec.click()
})
it("should write in console", function() {
})
})
});
我对测试运行时应该发生的事情的理解:
beforeAll
调用testFunction.act
会保存element
并将点击处理程序绑定到它element
称为每个#1绑定了一个事件处理程序但是,从console.log
的输出中可以清楚地看出,即使它们都对存在的同一已保存element
进行操作,第一个单击也会触发单击处理程序,第二个则不会触发单击处理程序( length == 1
)用于两个测试。
first spec
1
detected click
second spec
1
我可以进一步确认这一点,如果我进行2次更改:1)删除mount
中的testFunction.act
元素,以及2)将beforeAll
更改为beforeEach
,然后我得到预期的console.log
输出:
first spec
1
detected click
second spec
1
detected click
有人可以向我解释为什么会这样吗?
答案 0 :(得分:0)
element.click(function() {
console.log("detected click")
})
它不绑定。它的调度点击。
如果要绑定,请执行以下操作:
element.addEventListener("click",function(){console.log("detected click")});
答案 1 :(得分:0)
有趣的是,beforeAll
和beforeEach
refer
对于每个规范,dom
将重新显示,并且旧上下文将丢失。因此,对于每个测试,您都需要重新附加事件监听器。
在您的实现中,mount
作为关闭变量不允许多次“事件附加”。
因此正确的实现方法是删除“ closure”变量。您应该可以通过“ beforeAll”获得“预期结果”。