我在动态创建元素的表中遇到了有关事件传播的问题。
当我单击div
“菜单”(我们称其为“按钮”)时,发生onclick
操作。
我需要不执行该动作。
我在“按钮”功能中添加了event.stopPropagation();
,但这并没有任何改变。
有关工作示例,请参见以下代码段:
// Open menu function
function open_menu(elm) {
elm.css({
"top": PosY,
"left": PosX
}).fadeIn(200);
}
// Mouse move
var PosX, PosY;
$(document).mousemove(function(e) {
PosX = e.pageX;
PosY = e.pageY;
});
// If document is clicked somewhere else than the menu, close menu
$(document).on("mousedown", function(e) {
$(".menu").fadeOut(100);
});
// I bind my function on click, on the menuBtn.
// I am doing it this way because .menuBtn are created dynamically
$('table').on('click', '.menuBtn', function(event) {
event.stopPropagation(); // Why it isn't working ?
open_menu($(this).closest('tr').find(".menu"));
});
* {
margin: 0;
padding: 0;
}
p {
display: inline-block;
cursor: inherit;
}
table {
table-layout: fixed;
width: 100%;
border: 0;
border-collapse: collapse;
margin-bottom: 800px;
}
tr {
background-color: #eee;
cursor: pointer;
}
td {
position: relative;
padding-left: 10px;
height: 64px;
}
.menuBtn {
position: absolute;
display: inline-block;
left: 100px;
}
.menu {
position: fixed;
display: none;
background: #f8f8f8;
border: 2px solid #888;
height: 80px;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<table>
<tbody>
<tr onclick="console.log('I do not want to see that.')">
<td>
<p>Element</p>
<div class='menuBtn' title='Open menu'>[ ↓ ]</div>
</td>
<td>
<ul class="menu">
<p>menu of “Element”</p>
</ul>
</td>
</tr>
</tbody>
</table>
</body>
我究竟做错了什么?
拜托,请赐教。
最佳答案
您正在将委托事件绑定到<table>
,后者将监听事件并检查此事件的触发元素是否与.menuBtn
匹配。因此,直接绑定到<tr>
的事件与按钮单击事件无关。
此代码段与您的代码段相同。您可以看到tr
事件在.menuBtn
事件之前触发。在这种情况下,两个事件就像平行线一样。
// Open menu function
function open_menu(elm) {
elm.css({
"top": PosY,
"left": PosX
}).fadeIn(200);
}
// Mouse move
var PosX, PosY;
$(document).mousemove(function(e) {
PosX = e.pageX;
PosY = e.pageY;
});
// If document is clicked somewhere else than the menu, close menu
$(document).on("mousedown", function(e) {
$(".menu").fadeOut(100);
});
$('tr').on('click', function(){
console.log('tr clicked')
})
// I bind my function on click, on the menuBtn.
// I am doing it this way because .menuBtn are created dynamically
$('table').on('click', '.menuBtn', function(event) {
event.stopPropagation(); // Why it isn't working ?
console.log('btn clicked')
open_menu($(this).closest('tr').find(".menu"));
});
* {
margin: 0;
padding: 0;
}
p {
display: inline-block;
cursor: inherit;
}
table {
table-layout: fixed;
width: 100%;
border: 0;
border-collapse: collapse;
margin-bottom: 800px;
}
tr {
background-color: #eee;
cursor: pointer;
}
td {
position: relative;
padding-left: 10px;
height: 64px;
}
.menuBtn {
position: absolute;
display: inline-block;
left: 100px;
}
.menu {
position: fixed;
display: none;
background: #f8f8f8;
border: 2px solid #888;
height: 80px;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<table>
<tbody>
<tr>
<td>
<p>Element</p>
<div class='menuBtn' title='Open menu'>[ ↓ ]</div>
</td>
<td>
<ul class="menu">
<p>menu of “Element”</p>
</ul>
</td>
</tr>
</tbody>
</table>
</body>
为了显示
tr
事件不会通过单击.menuBtn
传播,这是一个演示:// Open menu function
function open_menu(elm) {
elm.css({
"top": PosY,
"left": PosX
}).fadeIn(200);
}
// Mouse move
var PosX, PosY;
$(document).mousemove(function(e) {
PosX = e.pageX;
PosY = e.pageY;
});
// If document is clicked somewhere else than the menu, close menu
$(document).on("mousedown", function(e) {
$(".menu").fadeOut(100);
});
$('tr').on('click', function(){
console.log('tr clicked')
})
// added for demonstration
$('table').on('click', function(){
console.log('table clicked')
})
// I bind my function on click, on the menuBtn.
// I am doing it this way because .menuBtn are created dynamically
$('table').on('click', '.menuBtn', function(event) {
//event.stopPropagation(); // Why it isn't working ?
console.log('btn clicked')
open_menu($(this).closest('tr').find(".menu"));
});
* {
margin: 0;
padding: 0;
}
p {
display: inline-block;
cursor: inherit;
}
table {
table-layout: fixed;
width: 100%;
border: 0;
border-collapse: collapse;
margin-bottom: 800px;
}
tr {
background-color: #eee;
cursor: pointer;
}
td {
position: relative;
padding-left: 10px;
height: 64px;
}
.menuBtn {
position: absolute;
display: inline-block;
left: 100px;
}
.menu {
position: fixed;
display: none;
background: #f8f8f8;
border: 2px solid #888;
height: 80px;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<table>
<tbody>
<tr>
<td>
<p>Element</p>
<div class='menuBtn' title='Open menu'>[ ↓ ]</div>
</td>
<td>
<ul class="menu">
<p>menu of “Element”</p>
</ul>
</td>
</tr>
</tbody>
</table>
</body>
这个绑定了一个委托事件,表明
.menuBtn
事件首先被触发。原因是它从.menuBtn
传播到table
。// Open menu function
function open_menu(elm) {
elm.css({
"top": PosY,
"left": PosX
}).fadeIn(200);
}
// Mouse move
var PosX, PosY;
$(document).mousemove(function(e) {
PosX = e.pageX;
PosY = e.pageY;
});
// If document is clicked somewhere else than the menu, close menu
$(document).on("mousedown", function(e) {
$(".menu").fadeOut(100);
});
$('table').on('click', 'tr', function(){
console.log('tr clicked')
})
// added for demonstration
$('table').on('click', function(){
console.log('table clicked')
})
// I bind my function on click, on the menuBtn.
// I am doing it this way because .menuBtn are created dynamically
$('table').on('click', '.menuBtn', function(event) {
// event.stopPropagation(); // Why it isn't working ?
console.log('btn clicked')
open_menu($(this).closest('tr').find(".menu"));
});
* {
margin: 0;
padding: 0;
}
p {
display: inline-block;
cursor: inherit;
}
table {
table-layout: fixed;
width: 100%;
border: 0;
border-collapse: collapse;
margin-bottom: 800px;
}
tr {
background-color: #eee;
cursor: pointer;
}
td {
position: relative;
padding-left: 10px;
height: 64px;
}
.menuBtn {
position: absolute;
display: inline-block;
left: 100px;
}
.menu {
position: fixed;
display: none;
background: #f8f8f8;
border: 2px solid #888;
height: 80px;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<table>
<tbody>
<tr>
<td>
<p>Element</p>
<div class='menuBtn' title='Open menu'>[ ↓ ]</div>
</td>
<td>
<ul class="menu">
<p>menu of “Element”</p>
</ul>
</td>
</tr>
</tbody>
</table>
</body>
因此,如果要防止出现此问题,也只需对
<tr>
使用一个委托事件。// Open menu function
function open_menu(elm) {
elm.css({
"top": PosY,
"left": PosX
}).fadeIn(200);
}
// Mouse move
var PosX, PosY;
$(document).mousemove(function(e) {
PosX = e.pageX;
PosY = e.pageY;
});
// If document is clicked somewhere else than the menu, close menu
$(document).on("mousedown", function(e) {
$(".menu").fadeOut(100);
});
$('table').on('click', 'tr', function(){
console.log('I do not want to see that.')
})
// I bind my function on click, on the menuBtn.
// I am doing it this way because .menuBtn are created dynamically
$('table').on('click', '.menuBtn', function(event) {
event.stopPropagation(); // Why it isn't working ?
open_menu($(this).closest('tr').find(".menu"));
});
* {
margin: 0;
padding: 0;
}
p {
display: inline-block;
cursor: inherit;
}
table {
table-layout: fixed;
width: 100%;
border: 0;
border-collapse: collapse;
margin-bottom: 800px;
}
tr {
background-color: #eee;
cursor: pointer;
}
td {
position: relative;
padding-left: 10px;
height: 64px;
}
.menuBtn {
position: absolute;
display: inline-block;
left: 100px;
}
.menu {
position: fixed;
display: none;
background: #f8f8f8;
border: 2px solid #888;
height: 80px;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<table>
<tbody>
<tr>
<td>
<p>Element</p>
<div class='menuBtn' title='Open menu'>[ ↓ ]</div>
</td>
<td>
<ul class="menu">
<p>menu of “Element”</p>
</ul>
</td>
</tr>
</tbody>
</table>
</body>
如果有任何错误,误导或不清楚的地方,请随时让我知道或编辑该帖子。