event.preventDefault()无效

3

我在使用Telerik Grid的视图中有这一行代码:

      columns.Bound(o => o.URI).Width(10).Sortable(false)
                .ClientTemplate("<A class='btnGrid' id=source<#= ID #> onclick=GridSelection.addItem('<#= ID #>') >Add</A>").Title("").Width(50);

GridSelection的addItem和disableSelected函数的JS代码:

  GridSelection = {
      addItem: function (value) {

         var anchorOption = $("a[id=source" + value + "]");

         anchorOption.click(function (e) { // variable name changed from "event"
               e.preventDefault();
               return false;    // as suggested by mr. Hamdi
               });

         anchorOption.fadeTo("slow", .5);

         GridSelection.disableSelected(anchorOption, true);

         var data = $("#GridSource").data('tGrid').data;
         var selectedObject;
         for (var item in data) {
            if (data[item].ID == value) {
               selectedObject = data[item];
               break;
            }
         }

          var grid = $("#GridSelected").data('tGrid');
          var newData = $("#GridSelected").data('tGrid').dataSource._data;
          newData.push(selectedObject);
          grid.dataBind(newData);
          grid.sort("");
          anchorOption.fadeTo("slow", .5);
      },

      disableSelected: function (element, disable) {
              //false on IEs 6, 7 and 8
              if (!$.support.leadingWhitespace) {
                  if (disable) {
                      $(element).attr('disabled', 'disabled');
                  } else {
                      $(element).removeAttr('disabled');
                  }
              }
     },
         // other GridSelection subfunctions here...

当我在IE中运行MVC3 Web应用程序时,由于GridSelection.disableSelected函数的作用,它可以很好地运行。但是在Chrome和Mozilla Firefox中,event.preventDefault()无法起作用。即使用户已经在那里添加了数据项,锚链接仍会添加数据项。
在GridSelection.addItem函数中使用preventDefault方法是否OK? preventDefault方法阻止哪个属性,是href还是onclick?
这有什么问题吗?如何修复此错误?有谁能帮忙?

你是否忘记在 return false 后面加上分号了?这不应该会导致错误,但值得一试。 - Hamdi
抱歉,这是我发布的笔误,但不是我的代码中的错误 ;) - ideAvi
现在我总算理解了你的问题。如果你在 disableSelected 函数中移除 if 语句 if (!$.support.leadingWhitespace),会发生什么呢?那么你只会得到那个条件语句的主体部分。 - Hamdi
当你编辑帖子时,我正在输入我的答案,纯粹是运气好,我认为我已经回答了你的额外问题。但我不确定我的答案是否真正解决了你的问题 - 请澄清你的GridSelection.addItem()函数实际上是如何调用的(以及它如何与标记中的.verify()函数相关)。 - nnnnnn
非常抱歉那个打字错误。我的应用程序必须防止.addItem()而不是.verify().verify()是我以前的解决方案之一,即创建一个单独的函数在onclick中调用。但我已经删除它并选择不使用它。再次道歉。 - ideAvi
显示剩余5条评论
5个回答

5
您的链接标记具有内联的单击处理程序,但没有 href 属性:
<A class='btnGrid' id=source<#= ID #> onclick=GridSelection.verify('<#= ID #>') >Add</A>

如果您想要防止 GridSelection.verify(),请注意以下几点:
  1. 内联单击处理程序可能在您的其他事件处理程序之前被调用,这意味着从您的其他处理程序取消它已经太晚了,并且
  2. e.preventDefault() 不能阻止其他处理程序运行,它只能停止事件的默认操作,对于链接而言,就是导航到 href 属性中指定的 URL。而您没有指定 href

如果您想在同一元素上为同一事件设置多个处理程序,应按照您希望它们被调用的顺序全部使用 jQuery 进行分配,然后在其中一个处理程序中使用 event.stopImmediatePropagation() 方法 如果您想要停止其余处理程序的运行。

鉴于您未显示要防止的代码部分,我不知道如何将其适合其中,但一般原则是:

<a id="myLink" href="someURL">My link</a>

<script>
$("#myLink").click(function(e) {
    // some processing
    if (someCondition)
       e.stopImmediatePropagation();
    // some other processing
});

$("#myLink").click(function(e) {
    // some processing
});
</script>

话虽如此,如果.verify()函数调用了你的.addItem()函数,并且你的意图是防止同一链接在未来的点击事件中再次生效,因为第一次点击应该进行验证/添加,然后你不希望再次添加,则在.addItem()函数内执行以下操作:

anchorOption.removeAttr("onclick");
// or
anchorOption[0].onclick = null;

那很精确。但是我应该把 preventDefault() 放在哪里?我应该把它放在 .addItem() 里面吗?还是应该把它放在 .addItem() 外面的另一个事件处理程序中? - ideAvi
1
随着问题版本的更新,我认为您根本不需要preventDefault()stopImmediatePropagation(),也不应该像您目前所做的那样在addItem()中创建click处理程序,因为这样做是没有帮助的。尝试使用我的答案末尾的代码并查看发生了什么 - 这个想法是“关闭”在html中使用内联onclick属性设置的现有click处理程序。 - nnnnnn

3
你是否尝试过使用return false;来替代event.preventDefault();?这可能会更有效。

实际上,在 event.preventDefault(); 之后可以添加 return false; 语句。您不需要删除 event.preventDefault(); - Hamdi
谢谢,我已经尝试将它与我的代码添加在一起,但仍然没有改变任何东西。 - ideAvi
这真的很奇怪。我之前也遇到过同样的问题,然后返回false; 对我有用。 - Hamdi
请查看我的更新帖子。我添加了一些困扰我的问题,也许你可以帮我回答它们。 - ideAvi

2

在不使用jQuery的情况下,香草中的魔法酱是stopPropagation。为了阻止任何可能的事件冒泡,通常您需要将两者配对使用。当结合使用时,您可以同时实现以下两点:

  1. 防止默认环境/浏览器行为(preventDefault)和
  2. 不触发附加到DOM祖先的任何其他脚本(stopPropagation)。

制作最终解决方案:

evt.preventDefault();
evt.stopPropagation();

这两者之间的区别已经在这里和许多其他地方进行了更详细的讨论。


对我来说,stopPropagation 没有起作用,但是 stopImmediatePropagation 起了作用 - 例如 evt.stopImmediatePropagation()。一定有其他事件在我的 JQuery 中调用了它! - Andy Brown
stopPropagation解决了我的问题,当我试图阻止按下回车键提交表单时,在输入字段上。 - seagulledge

2

你尝试过重命名事件变量吗?也许有点疯狂,但我记得曾经遇到过问题,只需尝试function(e){e.preventDefault();}并查看结果。


1
你疯了。(但说真的,那也是我的第一反应。) - nnnnnn
谢谢,但那是我用于事件变量的第一个名称,它仍然不起作用。 - ideAvi

1
如果锚点有一个id,请使用id选择器而不是将其用作属性选择器。
更改
$("a[id=source" + value + "]")

$("#source" + value)

我不是说这就是问题,但你可以尝试更改一下。

更新:

event.preventDefault()会阻止浏览器跟随锚点元素中设置的href属性链接。它不会阻止或停止click事件。


谢谢,但这并不是问题,因为我在我的其他函数中也使用了这个语法,它可以正常工作。 - ideAvi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接