Trigger javascript in href attribute with jQuery .click() (or similar) - javascript

Unfortunately, I'm working with some 3rd party javascript, which inserts links into my pages. Rather than just use these links as is, I want to use proxy elements, which, when clicked, trigger the click event on the 3rd party links.
The 3rd party links pack javascript into the href attribute, like this:
<a id="horribleLink" href="javascript:doSomething()">Click me</a>
My proxy element looks like this:
<button rel="horribleLink" class="linkProxy">No, click me</button>
And a bit of jQuery'd javascript to link them together:
$('button.linkProxy').click(function(){
$('#' + $(this).attr('rel')).click();
});
Now, this works perfectly if the 3rd party link is just a standard link (<a id="horribleLink" href="http://www.google.com">Click</a>), or a slightly less horrible onclick (Click), but when the javascript is inside the href attribute, triggering 'click' does nothing at all.
Can anyone tell me why, and if there's a reasonable workaround?
Updated As Millimetric said, the root cause looks to be that browsers prevent 'faking clicks' on anchors - I've removed my 'standard link' example, as that's another situation that doesn't work. The onclick handler does work, though, as you'd expect.

The accepted answer here goes into a little depth as to "why this is happening": Can I call jquery click() to follow an <a> link if I haven't bound an event handler to it with bind or click already?. Basically, it seems you can't do a click() on a link because the browser doesn't support fake clicking.
One Work-around:
If you set location.href for those cases, it works:
$('button.linkProxy').click(function(){
location.href = $('#' + $(this).attr('rel')).attr('href');
});
Working fiddle: http://jsfiddle.net/uv29x/3/
Two Work-around:
You could just get the href of those links and do an eval() on them, right?

Set window.location to the href value.
$('button.linkProxy').click(function(){
window.location = $('#'+$(this).attr('rel')).attr('href');
});
DEMO: http://jsfiddle.net/dmSUm/

I'd just finished typing this up when I saw Milimetric's answer . Here's the code anyway for what it's worth -
eval($('#horribleLink').attr('href').replace('javascript:',''));

Use the native Javascript click method and you've got yourself a working click!
$('button.linkProxy').click(function(){
$('#' + $(this).attr('rel')).click()[0].click();
});
I kept the jQuery click assuming that Javascript click will bypass jQuery triggers in which case you'll want to keep both. Otherwise, if I'm wrong (or you don't need to account for trigger) you can reduce it to:
$('button.linkProxy').click(function(){
$('#' + $(this).attr('rel'))[0].click();
});

If I understand correctly the question, the issue is that you have something like this:
Test
And you claim that when the javascript is on the href, the onclick event is not fired. Correct? If so, what I am seeing is that both get fired, first onclick and then the javascript inside href.

Related

How to disable e.preventDefault for some elements

I am using a OnePage template of bootstrap, I can not click a link, or can not switch a radio button, someone says I am using e.preventDefault()
Open this page http://abi.maxinrui.com/, you will see what I mean when you click "Click me" on that page.
I check the js file, there are lots of e.preventDefault() and I don't know how to modify them.
Is there a way to disable e.preventDefault()?
I want to have some hyperlink to another websites in my OnePage templete, so here is what I am think: I give some particular elements an ID or class, then I write some js, to disable e.perventDefault() only for these elements.
Does anybody know how to do that?
Thanks!
If you're using jQuery to handle your events, then it's possible!
First, a fiddle (shell for full effect): http://fiddle.jshell.net/UN5WE/show/
Here's the actual fiddle to edit: http://jsfiddle.net/UN5WE/
Basically, we're modifying jQuery's Event object, and specifically, the preventDefault method found on the prototype. We maintain a reference to re-enable preventDefault.
EDIT
For your specific use case, here's a way to disable preventDefault (based on a class). Just run this script after jQuery has loaded:
jQuery.Event.prototype.preventDefault = (function(){
var originalFunc = jQuery.Event.prototype.preventDefault;
return function(){
if($(this.target).hasClass('disableDefault')) {return;}
originalFunc.call(this);
}
}())
Prior to calling preventDefault, this will check to see if the target has a disableDefault class. If it does, it returns immediately (allowing the default to happen). To test your page, copy that code into your console and then run: $('h1').addClass('disableDefault').
I don't think is possible, or at least not on an easy way that i can think of, you can unbind the handlers if they were setted using bind, but that will also remove any behavior that they have, but you can use a workaround, add a new event handler for your links, i recommend that you add a special class to external anchors and then get the href attribute from it and open a new tab using window.open like this:
http://jsfiddle.net/yV78E/2/
The html
Hey
The js
// Similar behavior that might be on your site
$('a').click(function(e){
e.preventDefault();
// some code
});
// Use the code below as a workaround
$('.externalLink').click(function(e){
var targetLink = $(this).attr('href');
window.open(targetLink, '_blank');
});
You only need the second part of the script above, since the first one is just to emulate your problem.

Prevent a standard a href/jquery click combo from appending # to the url?

I have a standard link setup that fires an event via jquery when clicked
Click Me
All that works great, except that when the pseudo URL is clicked, it appends a hashtag (#) to the url. This hashtag affects how my page reloads if the user decides to refresh the page later on, so i'd like to not have the hashtag appended to the url.
is this possible while still allowing my normal jquery to fire?
Thanks!
You should either return false; from the event handler of A tag
Or, use
Click Me
For those who thinks javascript: void(0) is bad practice
If you use href='#', you must take care of two things
// one
function fn() {
// code
return false;
}
// two
click
And if you forget and just write onclick="fn();" it won't work
Another thing why I used javascript: void(0); is, if the function encounters/throws an error, it wont return false
So if you're a lone developer then you can clearly make your own choice, but if you work as a team you have to either state:
Use href="#", make sure onclick always contains return false; at the end, that any called function does not throw an error and if you attach a function dynamically to the onclick property make sure that as well as not throwing an error it returns false.
OR
Use href="javascript:void(0)"
Which "href" value should I use for JavaScript links, "#" or "javascript:void(0)"?
In end of the you click function, use:
return false;
smartass anwser: use a button.
alternative: you must make sure to trigger the preventDefault in youre jQuery event handler
$("dosomthing").click(function(e){
//make magic happen
e.preventDefault()
})
this works on html forms thats submitting and such.
note on the button thing
it is best pratice to only use a tags for link (somthing that changes the url) and buttons for other sorts of interactions.
search bots and other web crawlers expect a tags to link to a other html document (hyperlink) and up to and including html 4. or to a other point in the current document.
Does it need to be an href at all? you could do:
<span class="dosomething">Click me</span>
.
.dosomething{cursor:pointer}

How to prevent a click on a '#' link from jumping to top of page?

I'm currently using <a> tags with jQuery to initiate things like click events, etc.
Example is Text
But I hate how the '#' makes the page jump to the top of the page. What can I do instead?
So this is old but... just in case someone finds this in a search.
Just use "#/" instead of "#" and the page won't jump.
In jQuery, when you handle the click event, return false to stop the link from responding the usual way prevent the default action, which is to visit the href attribute, from taking place (per PoweRoy's comment and Erik's answer):
$('a.someclass').click(function(e)
{
// Special stuff to do when this link is clicked...
// Cancel the default action
e.preventDefault();
});
you can even write it just like this:
im not sure its a better way but it is a way :)
Solution #1: (plain)
Text
Solution #2: (needed javascript)
Text
Solution #3: (needed jQuery)
Text
<script>
$('a.someclass').click(function(e) {
e.preventDefault();
});
</script>
You can use event.preventDefault() to avoid this. Read more here: http://api.jquery.com/event.preventDefault/.
Just use <input type="button" /> instead of <a> and use CSS to style it to look like a link if you wish.
Buttons are made specifically for clicking, and they don't need any href attributes.
The best way is to use onload action to create the button and append it where you need via javascript, so with javascript disabled, they will not show at all and do not confuse the user.
When you use href="#" you get tons of different links pointing to the same location, which won't work when the agent does not support JavaScript.
If you want to use a anchor you can use http://api.jquery.com/event.preventDefault/ like the other answers suggested.
You can also use any other element like a span and attach the click event to that.
$("span.clickable").click(function(){
alert('Yeah I was clicked');
});
$('a[href="#"]').click(function(e) {e.preventDefault(); });
You can use #0 as href, since 0 isn't allowed as an id, the page won't jump.
Text
There are 4 similar ways to prevent the page from jumping to the top without any JavaScript:
Option 1:
Link
Option 2:
Link
Option 3:
Link
Option 4 (Not recommended):
Link
But it's better to use event.preventDefault() if you are handing the click event in jQuery.
Just use
Text
JQUERY
$('.someclass').click(function(e) { alert("action here"); }
If the element doesn't have a meaningful href value, then it isn't really a link, so why not use some other element instead?
As suggested by Neothor, a span is just as appropriate and, if styled correctly, will be visibly obvious as an item that can be clicked on. You could even attach an hover event, to make the elemnt 'light up' as the user's mouse moves over it.
However, having said this, you may want to rethink the design of your site so that it functions without javascript, but is enhanced by javascript when it is available.
Links with href="#" should almost always be replaced with a button element:
<button class="someclass">Text</button>
Using links with href="#" is also an accessibility concern as these links will be visible to screen readers, which will read out "Link - Text" but if the user clicks it won't go anywhere.
You could just pass an anchor tag without an href property, and use jQuery to do the required action:
<a class="foo">bar</a>
I have used:
Text
I've always used:
Some text
when trying to prevent the page jump. Not sure if this is the best, but it seems to have been working well for years.
The #/ trick works, but adds a history event to the browser. So, clicking back doesn't work as the user may want/expect it to.
$('body').on('click', 'a[href="#"]', function(e) {e.preventDefault() }); is the way I went, as it works for already existing content, and any elements added to the DOM after load.
Specifically, I needed to do this in a bootstrap dropdown-menu inside of a .btn-group(Reference), so I did:
$('body').on('click', '.dropdown-menu li a[href="#"]', function(e) {e.preventDefault() });
This way it was targeted, and didn't affect anything thing else on the page.
You can also return false after processing your jquery.
Eg.
$(".clickableAnchor").live(
"click",
function(){
//your code
return false; //<- prevents redirect to href address
}
);
I use something like this:
Text
To prevent the page from jumping, you need to call e.stopPropagation(); after calling e.preventDefault();:
stopPropagation prevents the event from going up the DOM tree. More info here: https://api.jquery.com/event.stoppropagation/
If you want to migrate to an Anchor Section on the same page without page jumping up use:
Just use "#/" instead of "#"
e.g
Home
About
contact page will not jump up on click..
Adding something after # sets the focus of page to the element with that ID. Simplest solution is to use #/ even if you are using jQuery. However if you are handling the event in jQuery, event.preventDefault() is the way to go.
The Link and Link does not work if one has to click on the same input more than once.. it only takes in 1 event click for each on multiple inputs.
still the best way to go is with Link
then,
event.preventDefault();
The simplest one for me was to do this.
Some text
The reason for using JS is that most modern sites rely on it.

jQuery's click() is not clicking?

I thought jQuery's click() can let us add a handler or just click on an element?
However, I tried:
$(function() {
setTimeout(function() {
$('a').first().trigger('click'); // or click(), the same
}, 3000);
});
and waited 3 seconds and it won't click on the first <a> element in the page... how come?
Update: this is related to What is the best way to make the Yahoo media player autostart, jQuery? and so there should already be event handler for clicking on a media, so how come .click(), which is the same as trigger('click'), not firing off that event handler?
Calling the click() method does not simulate clicking the link. It calls any click() handlers on the affected element(s). That's a subtle yet important difference. If you want to simulate clicking the link, there is no realiable cross-browser way of doing this.
I very recently ran into a similar problem. The reason nothing happens is because anchor tags don't have a "click" method for jquery to call. If you change the anchor tag to a <button></button> tag for instance, the .click() will simulate a user clicking as expected.
There are a few "hacky" workarounds for this, but it would depend how the event handler for the anchor tag is set up. For instance, if there was some javascript inside the anchor tags href attribute, this would work (which happened to be the solution to my problem):
var lnk = $('a.mylink');
window.location = lnk.attr('href');
I'm not sure, if .first() is a possible way to use this function. Have you tried
$('a:first').click();
instead? If .first() doesn't exist, it throws an error, the .click() is never reached, and since it lives in an anonymous function, you even might not see the error at all (failing silently).
Here's what you could do to simulate a click on a link (as long as these are normal links):
location.href = $('a').first().get(0).href;
If you already have an event-handler for the link, you can use the trigger() method:
$('a:first').trigger('click');
What exactly do you want to do? A link is usually used to redirect to a new page. So if you need a redirection, use something like this:
$(function() {
setTimeout(function() {
window.location.replace("linkToNewPage.html");
}, 3000);
});
"There is an option for this. Plz check
at this page
http://mediaplayer.yahoo.com/api/#example_usage
If u set autoplay=true, the first song
will be started automatically.."
-Kai
In Relation to:
What is the best way to make the Yahoo media player autostart, jQuery?
Else for a click attach a click handler to what you want e.g:
$('#MyElementID').click(function() {
//How you want it to behave when you click it.
});
window.setTimeout(YourFunction, 3000);
function YourFunction {
//Your function that runs. Maybe fire the onclick handler?
}
?
You're trying to use click() method for something else than its purpose. click() is used so you can catch the click on a specific element, not for simulate it.
Read more here

JQuery .click() event troubles

Here's a snippet of my code:
$(".item").click(function () {
alert("clicked!");
});
And I have (hypothetically; in actuality it's far more complicated) the following on my page:
<img src="1.jpg" />
However, when I click the image, I do not get an alert.
What is my mistake?
Is your selector actually matching anything? Try using the jQuery debug plugin (http://jquery.glyphix.com/) and doing this:
$(".item").debug().click(function() {
alert("clicked!");
});
.debug() will log whatever is matched to the Firebug console (you are using firebug, right? :-) ) without "breaking the chain" so you can use it inline like this.
If that turns out correctly, there may be some issue with the browser navigating to "#" before it can show your alert. Try using the .preventDefault() method on the event object to prevent this behavior:
$(".item").click(function(evt) {
evt.preventDefault();
alert("clicked!");
});
First question - are you adding the element to be clicked dynamically? If it is,
you should use the live event since that will take care dynamically created elements.
http://docs.jquery.com/Events/live#typefn
Use bind.
$(".item").bind("click", function(e) { ... });
modifying the selector?
$(".item > img")
I had this problem recently after adding a context menu jquery plugin. The pluging was binding to the click event of the body and then unbinding click event - it seemed to remove all bindings to click event for all elements. Maybe a suggestion to turn off plugins or check you're not unbinding click for a parent element yourself.
The code you have posted is correct, so I suspect there's something else going on that you haven't considered.
Firstly, if there was an error somewhere (even not in that exact bit of code) that might cause it to stop working. Put an alert just after this line to check that it runs.
Check that no other elements are catching the event and stopping it from propagating. This has bitten me before in the past... If there's anything else handling a click which has stopPropagation() or return false in it, that might be the problem.
One thing I've found (though only with links going elsewhere) is that adding return false; in may help, if it's just firing the anchor off instead of evaluating the alert. I can't really say why this would be the case, but that's a solution I found to a similar problem recently.

Categories

Resources