javascrpt: hierarchy of event handlers (ie only)
朋友遇到了一个问题,下面的代码总是先触发tr的onclick事件,然后才触发href_click()方法
为了解决这个问题,我修改了tr_click的实现方法,
event.srcElement是触发事件的源对象,通过不断调用parentElement属性,寻找父对象直至找到sender对象(也就是调用tr_click方法的对象),如果调用sender的子对象包含onclick事件处理,或者源对象是A,则不调用sender的onclick事件处理方法。
不知道我说明白了没有,也许你看了全部的测试代码就清楚了;我没有找到更简便的方法,如果你有更方便的方法请告知;另,这段代码只在ie下好用,firefox不好用。
对了,为了说明对象的层次关系,我在table中嵌套了另一个table,在这种情况下tr_click的实现仍然好用;另外,按照以下代码修改tr_click,再分别点击click me (href)和click me (onclick event),这回应该明白为什么总是先调用tr_click方法了吧。
1 <tr onclick="tr_click();">
2 <td><a href="javascript: href_click();">click me</a></td>
3 </tr>
2 <td><a href="javascript: href_click();">click me</a></td>
3 </tr>
为了解决这个问题,我修改了tr_click的实现方法,
1 function tr_click(sender) {
2 var element = event.srcElement;
3 var invodeClick = false;
4
5 while (element != sender) {
6 if (element.onclick != null || element.tagName == "A") {
7 invodeClick = true;
8 break;
9 }
10 element = element.parentElement;
11 }
12
13 if (! invodeClick) {
14 alert("tr");
15 }
16 }
17
2 var element = event.srcElement;
3 var invodeClick = false;
4
5 while (element != sender) {
6 if (element.onclick != null || element.tagName == "A") {
7 invodeClick = true;
8 break;
9 }
10 element = element.parentElement;
11 }
12
13 if (! invodeClick) {
14 alert("tr");
15 }
16 }
17
event.srcElement是触发事件的源对象,通过不断调用parentElement属性,寻找父对象直至找到sender对象(也就是调用tr_click方法的对象),如果调用sender的子对象包含onclick事件处理,或者源对象是A,则不调用sender的onclick事件处理方法。
不知道我说明白了没有,也许你看了全部的测试代码就清楚了;我没有找到更简便的方法,如果你有更方便的方法请告知;另,这段代码只在ie下好用,firefox不好用。
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2 <html>
3 <head>
4 <title> event hierarchy test </title>
5 <script language="JavaScript">
6 <!--
7
8 function tr_click(sender) {
9 var element = event.srcElement;
10 var invokeClick = false;
11
12 while (element != sender) {
13 if (element.onclick != null || element.tagName == "A") {
14 invokeClick = true;
15 break;
16 }
17 element = element.parentElement;
18 }
19
20 if (! invokeClick) {
21 alert("tr");
22 }
23 }
24
25 function td_click() {
26 alert("td");
27 event.cancelBubble = true;
28 }
29
30 function a_click() {
31 alert("a");
32 }
33
34 //-->
35 </script>
36 </head>
37
38 <body>
39 <table border="1" width="400px">
40 <tr onclick="tr_click(this);">
41 <td onclick="td_click();" width="100px"> </td>
42 <td><a href="javascript: a_click();">click me (href)</a></td>
43 <td><a href="#" onclick="a_click();">click me (onclick event)</a></td>
44 <td> </td>
45 </tr>
46 <tr onclick="tr_click(this);">
47 <td colspan="43">
48 <table border="1" width="100%">
49 <tr>
50 <td onclick="td_click();"> </td>
51 </tr>
52 <tr>
53 <td><a href="javascript: a_click();">click me (href)</a></td>
54 </tr>
55 <tr>
56 <td> </td>
57 </tr>
58 </table>
59 </td>
60 </tr>
61 </table>
62 </body>
63 </html>
2 <html>
3 <head>
4 <title> event hierarchy test </title>
5 <script language="JavaScript">
6 <!--
7
8 function tr_click(sender) {
9 var element = event.srcElement;
10 var invokeClick = false;
11
12 while (element != sender) {
13 if (element.onclick != null || element.tagName == "A") {
14 invokeClick = true;
15 break;
16 }
17 element = element.parentElement;
18 }
19
20 if (! invokeClick) {
21 alert("tr");
22 }
23 }
24
25 function td_click() {
26 alert("td");
27 event.cancelBubble = true;
28 }
29
30 function a_click() {
31 alert("a");
32 }
33
34 //-->
35 </script>
36 </head>
37
38 <body>
39 <table border="1" width="400px">
40 <tr onclick="tr_click(this);">
41 <td onclick="td_click();" width="100px"> </td>
42 <td><a href="javascript: a_click();">click me (href)</a></td>
43 <td><a href="#" onclick="a_click();">click me (onclick event)</a></td>
44 <td> </td>
45 </tr>
46 <tr onclick="tr_click(this);">
47 <td colspan="43">
48 <table border="1" width="100%">
49 <tr>
50 <td onclick="td_click();"> </td>
51 </tr>
52 <tr>
53 <td><a href="javascript: a_click();">click me (href)</a></td>
54 </tr>
55 <tr>
56 <td> </td>
57 </tr>
58 </table>
59 </td>
60 </tr>
61 </table>
62 </body>
63 </html>
对了,为了说明对象的层次关系,我在table中嵌套了另一个table,在这种情况下tr_click的实现仍然好用;另外,按照以下代码修改tr_click,再分别点击click me (href)和click me (onclick event),这回应该明白为什么总是先调用tr_click方法了吧。
1 function tr_click(sender) {
2 alert("tr");
3 }
2 alert("tr");
3 }