简体   繁体   中英

How to stop event propagation from within an anchor's href attribute without using onclick or onmousedown

Due to restrictions, even though it is something i avoid altogether, in a certain situation i have to use the javascript: syntax in a href attribute of an achor tag.

(EXPLANATION: In my CMS i use a rich text editor to allow the user to make changes to text elements, including links. In some cases specific javascript: calls are required and i banned onclick completely from the link editing features (to simplify the process for the user). However, as one of the links appears within a block that reacts to an onclick event, the thing double-fires)

Like this:

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

My problem is that this link is inside a container that already reacts to an onclick event. Therefore i wanted to pass the event object along to the doSomething() method, so that i could then use jQuery's

event.stopPropagation()

method.

Unfortunately however, it seems that passing the event object along

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

does not seem to work at all. Safari won't say anything while Firefox will report ReferenceError: event is not defined

I assume that this is the case because href="" is not a script-initiating attribute (such as onclick). The problem is that in this situation i won't be able to access the tag beyond what i already do.

Therefore i either need

1.) A way to pass the event object to the doSomething() function from within the href attribute

or

2.) A way to stop the event propagation right in that anchor (after its clicked) by other means.

Thank You for any constructive input!

You cannot stop event propagation from the href attribute because:

  1. When the href code executes, it is not an event. It just executes that code, similar to the "location hack". Like entering javascript:doSomething() in the browser's address bar.

  2. The href code executes after the events fire on the link -- including bubbling.

    You can see that behavior in this jsFiddle . Note that mouseup , mousedown , and click all fire both for the link, and on the container when the link is clicked, before the href code executes.

If there are event listeners that you want to block, you'll have to find another way.


But, if you can append javascript to the document you can block the href using preventDefault() .

For example:

  • 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(); } ); 


You can see this last version live at jsFiddle .

If you cannot alter the link itself (to use onclick) then your only option is to alter the onclick handler of the container.

Can you do something like

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

Well, this is an old question, but in my particular case I did find a hack around it, but it might only apply to a subset of situations. I have a div that has an onclick. But if an inside that div is clicked, I don't want that div's onclick to fire. Here is what I do:

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.

}

I learned about the queryselector trick here: https://stackoverflow.com/a/14800287/2295722

I don't know if there is a way to get the arguments if you write your javascript in href attribute. But you can get it as following in onclick, but as you say this isn't the best practice:

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

in arguments array you'll get your event object.

here is a demo for you:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM