我最近调 netsurf 也遇到一个相关的 bug : alert() 被调了两次。html 代码:
- <html>
- <head>
- <title>
- alert onclick example
- </title>
- <script type="text/javascript">
- function causealert() {
- var txt = document.getElementById("p1").textContent;
- alert(txt);
- }
- </script>
- </head>
- <body>
- <div style="border: 1px solid red">
- <p id="p1">
- First line of paragraph.
- <br />
- </p>
- </div>
- <br />
- <button id="button1">
- add another textNode.
- </button>
- <script>
- var Button1 = document.getElementById("button1");
- /*var Button1Click = function() { alert(1); };
- Button1.addEventListener("click", Button1Click, false);*/
- Button1.onclick = causealert;
- </script>
- </body>
- </html>
通过 gdb, 定位到是_dom_node_dispatch_event() 里面的问题:
/* The capture phase */ for (targetnr = ntargets; targetnr> 0; --targetnr)...
/* Bubbling phase */
evt->phase = DOM_BUBBLING_PHASE;
for (targetnr = 0; targetnr < ntargets; ++targetnr)
事件流是这样的: p1(root)-->p2-->... --> pm --> T (capturing phase), T (target phase), T--> pm --> ... --> p1 (bubbling phase).
规范规定 capturing 和 bubbling 只能选其一, 代码中在 js_dom_event_add_listener() 是选 capturing。因此就解释了为什么 alert 被执行两回了。
修改: 根据 DOM 3 规范,把上面的 0 改成 1 就行了。
Ref
[1]http://hax.iteye.com/blog/162718
来源: http://lib.csdn.net/article/javascript/37786