如何在不使用onclick或onmousedown的情况下,通过锚点的href属性停止事件传播

3

由于某些限制,尽管我完全避免这样做,在某些情况下我必须在锚点标签的href属性中使用javascript:语法。

(说明:在我的CMS中,我使用富文本编辑器允许用户更改文本元素,包括链接。在某些情况下需要特定的javascript:调用,并且我完全禁止在链接编辑功能中使用onclick(以简化用户流程)。但是,由于其中一个链接出现在响应onclick事件的块中,因此会导致双重触发)

像这样:

<a href="javascript:doSomething()"></a>

我的问题是,这个链接位于一个已经有onclick事件的容器中。因此,我想将事件对象传递给doSomething()方法,以便我可以使用jQuery的方法。
event.stopPropagation()

方法。

然而不幸的是,似乎在传递事件对象时

<a href="javascript:doSomething(event)"></a>

似乎完全不起作用。Safari不会说任何话,而Firefox会报告ReferenceError: event is not defined

我认为这是因为href=""不是一个启动脚本的属性(例如onclick)。问题在于,在这种情况下,我将不能访问超过我已经做到的标签。

因此,我需要:

1.) 一种从href属性内部向doSomething()函数传递事件对象的方法

或者

2.) 一种通过其他方式在该锚点中停止事件传播(在其被点击后)。

感谢您提供任何有建设性的意见!


为什么不直接使用jQuery将doSomething附加到click事件处理程序呢? - ultranaut
这种情况要求仅通过使用href属性可能实现处理。 - SquareCat
如果您能分享为什么必须使用href属性,那么可能会提出一些解决方法。 - Programming Guy
你说得对,我会编辑问题。 - SquareCat
将带有href属性的<a>标签更改为带有onclick属性的<span>标签,您的问题就会得到解决。 - gmustudent
4个回答

10

你无法通过 href 属性停止事件传播,因为:

  1. href 代码执行时,它不是一个事件。它只是执行那段代码,类似于“location hack”。就像在浏览器地址栏中输入 javascript:doSomething()

  2. href 代码在链接上的事件(包括冒泡)触发之后才会执行。

    您可以在 this jsFiddle 中看到此行为。请注意,在单击链接时,mouseupmousedownclick 都会同时触发链接和容器上的事件,然后才会执行 href 代码。

如果有要阻止的事件监听器,您需要找到其他方法。


但是,如果您可以将JavaScript添加到文档中,则可以使用preventDefault()阻止href。
例如:
  • jQuery, before version 1.7:

    $("#container a").bind ("mousedown mouseup click", function (e) {
        e.preventDefault();
    } );
    
  • jQuery 1.7 and later:

    $("#container a").on ("mousedown mouseup click", function (e) {
        e.preventDefault();
    } );
    

    or (better):

    $("#container").on ("mousedown mouseup click", "a", function (e) {
        e.preventDefault();
    } );
    
你可以在jsFiddle上实时查看此最新版本

非常感谢您!我也遇到了同样的问题。将所有的<a>标签转换为带有onclick属性的<span>标签解决了问题!再次感谢! - gmustudent
1
@SgtPooki,你是正确的,但请阅读问题及其评论。OP明确指出:“情况要求仅使用href属性可能处理它。”。但由于后jQuery方法可能会帮助其他人,我已将其添加到此答案中。 - Brock Adams

1

如果您无法更改链接本身(以使用onclick),那么您唯一的选择是更改容器的onclick处理程序。

您能做类似的事情吗?

function containerClickHandler(e) {
  e = e || event;
  var el = e.target || e.srcElement;
  if (el.nodeName === 'A' && someOtherMatchChecks) {
       // eat event
  }
  else {
       // process event
  }
}

那是一种选择,但我不能这样做,因为我必须调整我的 CMS 的一些核心代码使其适用于单个情况。但你的方法完全有效。点赞。 - SquareCat

1

好的,这是一个老问题,但在我的特定情况下,我找到了一个解决方法,但它可能只适用于某些情况。我有一个带有onclick的div。但是如果该div内部的一个元素被点击,我不希望该div的onclick被触发。这是我所做的:

function myOnClick () {

  // loop over all <a>'s, and test if they are hovered over right now.
  var allLinks = document.links;
  var dont = 0;
  for (var i = 0, n = allLinks.length; i < n; i++) {
    // pure javascript test to see if element is hovered.
    if(allLinks[i].parentElement.querySelector(":hover") === allLinks[i]) {dont = 1; }
  };

  if(dont)return;

  // your stuff here, only fires when dont is false.

}

我在这里了解到了queryselector技巧: https://dev59.com/eGUq5IYBdhLWcg3wF8nw#14800287

0

我不知道是否有一种方法可以在href属性中编写JavaScript时获取参数。但是,您可以按照以下方式在onclick中获取它,但正如您所说,这不是最佳实践:

<a onclick="console.log(arguments)">your link</a>

在参数数组中,您将获得事件对象。

这里有一个演示给您:

http://jsfiddle.net/tEw5J/1/


谢谢,但我不能使用onclick。很不幸。 - SquareCat

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