文章目录
  1. 1. 模态框:早就发现但没有重视的问题
  2. 2. 模态框又出现了其它问题
    1. 2.1. 事件还原:
    2. 2.2. 解决问题
  3. 3. 其它组件中也出现了bug
  4. 4. 总结及思考

模态框:早就发现但没有重视的问题

之前写模态框时就注意到了一些问题,例如有些时候点击按钮会弹出多个模态框,这并不是我想要的结果。

我不清楚这是为什么,但是这种情况很好解决,我直接在模态框组件的构造函数里加一个判断,就解决了这个问题:

1
if(_.$('.m-modal')) return

模态框又出现了其它问题

事件还原:

模态框的“确定”按钮会调用一个自身的事件,注销掉这个窗体:

1
2
3
4
hide: function() {
var container = this.container; // 整个窗体节点
document.body.removeChild(container);
}

某一次我调用完模态框,点击其中的“确定”按钮,窗体正常关闭了。但控制台报了一个错:
Failed to execute 'removeChild' on 'Node',也就是说,它没有找到窗体节点,在控制台console了一下,果然是这样的。

但是窗体毕竟是正常关闭了,出现这个bug只能说明这个接口被多次调用了。

解决问题

好吧,延续上个问题的解决思路:

1
2
3
4
5
hide: function() {
if(_.$('.m-modal')) return
var container = this.container; // 整个窗体节点
document.body.removeChild(container);
}

这个时候其实就应该考虑到了,这个组件已经实现了很多接口了,难道要一直用这种笨办法吗?

但是毕竟还有其它的工作等着完成(其实是其它bug等着修复),就先把这个问题搁置了。

其它组件中也出现了bug

很不幸,紧接着就发现其它组件中出现了同一个方法点击时被执行了两次,如图:
同一个方法被执行两次

看来这个问题不彻底解决是不行了。

一开始我怀疑是元素冒泡导致的问题,然后在事件调用时添加了event.stopPropagation()来阻止冒泡,但发现没什么卵用。

在网上查资料,发现有很多类似的案例,原来是因为事件被重复多次绑定到了这个元素上:
chrome可以查看元素绑定的事件
如图,在event listenners选项卡中,可以查看绑定的全部事件,在这里我的m-works组件被绑定了两个完全一样的事件。

解决办法就是用JQuery的once去接口绑定事件或者off接口及时解绑。

但我并不能因为一个bug去调用一个如此庞大的库。随后,我又在stackoverflow里找到了一个原生的解决办法,思路是把这个事件方法拿出来,写在一个新的函数中,然后绑定到这个新的函数

1
2
3
4
var newHandle = function(event) { handle(event, myArgument); };

el.addEventListener("click", newHandle, false);
el.addEventListener("click", newHandle, false);

但不知为什么,它在我这里仍然是无效的。

无奈之下问群里的同学,有个同学给出了一个这样的接口:
event.stopImmediatePropagation,
它的作用是阻止调用相同事件的其他侦听器。

万万没想到,竟有这样的神器?!果然,在我把它加在事件函数内的首行后,虽然它仍旧绑定了两个相同的方法,但实际上只会被调用一次,问题就这样解决了。

总结及思考

  1. 遇到bug最好还是追根刨底,斩草不除根,春风吹又生啊
  2. 多记一些API是很有用的,哪怕只是过一遍,也比杆瞎强多了
文章目录
  1. 1. 模态框:早就发现但没有重视的问题
  2. 2. 模态框又出现了其它问题
    1. 2.1. 事件还原:
    2. 2.2. 解决问题
  3. 3. 其它组件中也出现了bug
  4. 4. 总结及思考