好的,我在这里难过。我有一个由表组成的控件。我允许用户单击底行中的超链接直接转到关联的视图。
另一方面,用户可以点击表格内的任何其他位置并进行选择。此选择激活工具栏,允许用户对所选项目执行某些任务。如果用户再次单击所选项目,我想以编程方式单击超链接。但是,当我以编程方式单击超链接运行jQuery时,我不断收到“Out of stack space”错误。我完全知道click事件是递归调用的,但我不知道如何防止它!这是我的代码......
<head runat="server">
<title></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<style>
.mouseOver, .mouseOut, .selected
{
width: 120px;
height: 120px;
text-align: center;
vertical-align: top;
display: inline-block;
margin: 5px;
cursor: pointer;
}
.mouseOver
{
border: solid thin #99defd;
background: #e9f8fe;
}
.mouseOut
{
border: solid thin White;
}
.selected
{
border: solid thin #e0a403;
background: #f8f4de;
}
</style>
<script>
(function($) {
$(document).ready(function() {
var $items = $('.mouseOut');
$items.mouseenter(function() {
if ($(this).attr('class') != 'selected')
$(this).attr('class', 'mouseOver');
});
$items.mouseleave(function() {
if ($(this).attr('class') != 'selected')
$(this).attr('class', 'mouseOut');
});
$items.click(function() {
if ($(this).attr('class') == 'selected') {
$(this).find('a').click();
}
else {
$('.selected').attr('class', 'mouseOut');
$(this).attr('class', 'selected');
}
});
});
})(jQuery);
</script>
</head>
<body runat="server">
<form id="form1" runat="server">
<table cellpadding="5" class="mouseOut">
<tr>
<td>
user module thumbnail...
</td>
</tr>
<tr>
<td>
<a id="A1" href="javascript:__doPostBack('ControlPanelHost1$cphCtrl0$lvCollectionView$ctrl0$lnkBtn','')">Users</a>
</td>
</tr>
</table>
<table cellpadding="5" class="mouseOut">
<tr>
<td>
stats module thumbnail...
</td>
</tr>
<tr>
<td>
<a id="A2" href="javascript:__doPostBack('ControlPanelHost1$cphCtrl0$lvCollectionView$ctrl1$lnkBtn','')">Stats</a>
</td>
</tr>
</table>
</form>
</body>
这个剥离版本将完全展示这个问题。感谢任何可以提供帮助的人!
答案 0 :(得分:8)
问题是在元素的后代上触发click
事件也会在该元素上触发它,因为事件会使DOM树冒泡。由于您的代码在其祖先处理同一事件时触发了后代的click
事件,因此会发生无限递归。
解决此问题的方法是使用stopPropagation()以防止在您的超链接上触发的click
事件冒泡:
$(this).find("a").click(function(e) {
e.stopPropagation();
});
编辑:但是,上面的代码无法按预期工作,因为您的逻辑也驻留在祖先的事件处理程序中。我们可以在问题上切换方法,并使用event.target和is()在后代超链接上触发click
事件,前提是我们当前处理的事件是在祖先元素上触发的,或者不是超链接本身的后代:
$items.click(function(event) {
if ($(this).attr('class') == 'selected' && !$(event.target).is("a")) {
$(this).find('a').click();
} else {
$('.selected').attr('class', 'mouseOut');
$(this).attr('class', 'selected');
}
});
答案 1 :(得分:2)
由于一些奇怪的原因,这个解决方案有效。
替换:
$(this).find('a').click();
使用:
window.location = $(this).find('a').attr('href');
FrédéricHamidi提供的代码很棒但是click()从未发布回服务器。
答案 2 :(得分:0)
似乎函数__doPostBack未定义,这可能是导致错误的原因