I want to do this: when you click a link on a page, it will open the link normally, but when you double click the link, it will alert the link's 'href' attribute.
However, when I try to double click a link, it will always open the link. Any idea?
The link opens after the first click of a double click, so you will need to add a time delay to determine which is which. Here's some code (using the jQuery JavaScript library for brevity) that works on all the browsers except Internet Explorer (try it out). If you can figure out why it doesn't, I'd like to know.
$('a').click(function(event) {
var elem = $(this),
clickTimeout = elem.data('clickTimeout');
if(clickTimeout) {
// Double click; cancel the single click timeout
clearTimeout(clickTimeout);
elem.data('clickTimeout', null);
alert(elem.attr('href'));
} else {
// Might be a single click; wait and see
elem.data('clickTimeout', setTimeout(function() {
// Single click; timeout was not cancelled
elem.data('clickTimeout', null);
// Navigate to the link's URL
window.location.href = elem.attr('href');
}, 500));
}
// Stops propagation and prevents default action
return false;
});
maybe it's just a typo: the event you're looking for is named ondblclick, not ondbclick.
To avoid the link being opened, you may want to work with right-clicks instead.
Because the onclick event gets fired before the ondbclick event.
That is the reson why ondblclick does not get executed -> the link gets loaded first.
This is tricky because the order of event is not the same in all browsers. Check out this article: http://unixpapa.com/js/mouse.html under the section for double clicks.
You could cancel the default action of clicking the link and write your own handler for the click event.
A double click is two clicks. Thus, it fires the click event.
Related
I have a simple div with a link with in:
<div class="mhButton">
<span class="icon-checkmark"></span> Register Animal
</div>
I've have a function that is triggered whenever the 'div.mhButton' is clicked. This function should find 'div.mhButton' child 'a' and click it.
$(".mhButton").on('click', function () {
var a = $(this).find("a").text();
console.log(a);
$(this).find("a").click();
});
This works, however, I get stuck in a loop that runs like 639 times.
I can't comprehend why this runs X amount of times, then continues without error.
Does anyone have a solution on how to prevent this? Along with an explanation on why this happens?
Note* The console is logging the same button, again and again.
Because the a tag is embedded in the button, you are continuously re-firing the event. Events will bubble up, so the anchor will get clicked, and then its parent. It is running until the browser gets tired of running it and then it just stops. The method doesn't actually do anything which is likely why you aren't seeing any issues. You can accomplish your goal a couple of ways:
$(".mhButton").click(function () {
$(this).off('click'); // turn the click handler off in the handler itself.
var a = $(this).find("a").text();
console.log(a);
$(this).find("a").click();
});
If you do this, then you will end up only being able to fire the event once.
Alternatively:
$(".mhButton").click(function (e) {
a = $(this).find("a").text();
console.log(a);
$(this).find("a").click();
});
$("#RegisterAnimal").click(function (e) {
e.stopPropagation(); // prevent the anchor from re-firing the button click
});
Altenatively, you can just style the link to look like a button and avoid the unnecessary click handlers all together.
When you call $(this).find("a").click(); the event will bubble up to the div.mhButton tag and cause your handler to be called again. The reason it runs around 500 times is because it stops with a stack overflow, it does not continue
You can prevent it by checking if the click was the <a> tag itself and not calling click() in that case
Working example: http://jsfiddle.net/mendesjuan/zdkrhh42/
Note Regarding the accepted answer
Bic's second answer almost works, mine is a different approach with fewer side effects. The main problem with calling stopPropagation is that there may be handlers on the whole document that wouldn't get fired in that case. A commmon case is when you have a menu or a dialog that is supposed to hide when you click anywhere else on the page. The stopPropagation approach will prevent the menu from being hidden when they click your button.
$(".mhButton").click(function (e) {
// Only run this handler if the click was on the div, not the link itself
if ( $(e.target).is('a, a *') ) {
return;
}
var a = $(this).find("a").text();
$(this).find("a").click();
});
i have:
<input type="text" />
and
$('input').blur(function(){
alert('stay focused!');
});
I want to prevent the blur function running when I'm "blurring" by clicking on an anchor element.
I.E. if i tab to another input, click somewhere on the page etc i want the blur to fire, but if i click a link, I don't want it to fire.
Is this easily achievable, or do i need to hack about with delegates and semaphores?
Thanks
I had to solve this problem myself today, too. I found that the mousedown event fires before the blur event, so all you need to do is set a variable that indicates that a mousedown event occurred first, and then manage your blur event appropriately if so.
var mousedownHappened = false;
$('input').blur(function() {
if(mousedownHappened) // cancel the blur event
{
alert('stay focused!');
$('input').focus();
mousedownHappened = false;
}
else // blur event is okay
{
// Do stuff...
}
});
$('a').mousedown(function() {
mousedownHappened = true;
});
Hope this helps you!!
If you want to keep the cursor at its position in a contenteditable element, simply:
$('button').mousedown(function(){return false;});
Delay the blur a bit. If the viewer clicks a link to another page, the page should change before this code gets a chance to run:
$('input').blur(function(){
setTimeout(function() {alert('stay focused!');}, 1000);
});
You can experiment with what delay value for the timeout seems appropriate.
You can get this behavior by calling preventDefault() in the mousedown event of the control being clicked (that would otherwise take focus). For example:
btn.addEventListener('mousedown', function (event) {
event.preventDefault()
})
btn.addEventListener('click', function(ev) {
input.value += '#'
input.setSelectionRange(ta.value.length, ta.value.length)
})
See live example here.
Some clarification that was too long to put in a comment.
The click event represents both pressing the mouse button down, AND releasing it on a particular element.
The blur event fires when an element loses focus, and an element can lose focus when the user "clicks" off of the element. But notice the behavior. An element gets blurred as soon as you press your mouse DOWN. You don't have to release.
That is the reason why blur gets fired before click.
A solution, depending on your circumstances, is to call preventDefault on mousedown and touchstart events. These events always (I can't find concrete documentation on this, but articles/SO posts/testing seem to confirm this) fire before blur.
This is the basis of Jens Jensen's answer.
I have an onbeforeunload event :
$().ready(function() {
window.onbeforeunload=function() { return "haha" };
});
And my links are like this (ajax web site) :
<a href="#pageX" />
But the onbeforeunload is never called. What can i do ?
Thanks
I'm guessing since you're trying to bind to the onbeforeunload and return a string, that you're looking to provide the user with an "Are you sure you want to leave this page" dialog on an AJAX site.
In which case you probably need to go about this a little differently by binding a click handler onto the links. So you can prevent the hash change until the confirmation is made.
Something like:
$('a[href^="#"]').live('click',function(e){
if( //should we be confirming first? ) {
//put your confirmation code here either using default JS windows or your own CSS/jQueryUI dialog boxes
// this code should either cache the url of the link that was clicked and manually update the location with it when the user confirms the dialog box (if you're using JQUI windows) or simply use JS confirmation boxes and based on the response, all you need to do is return; and the link click will handle normally
e.preventDefault(); //prevent the link from changing the hash tag just yet
e.stopImmediatePropagation(); //prevent any parent elements from firing any events for this click
}
} );
Don't get me wrong, but are you serious ?
That link just refers a hash-tag, hence, it will not leave the current site and there will be no call to onbeforeunload nor unload.
If there is any *click event handlerbound to that anchor aswell, there must be something in the event handler code which really forces the current site to get unloaded (location.href` for instance).
If you just switch HTML via Ajax, there is no onbeforeunload aswell.
You could bind a handler to the onhashchange event (check browser compatibilty) but that would fire for any change that happens in your url/hash.
You're probably looking for the onhashchange event:
https://developer.mozilla.org/en/DOM/window.onhashchange
I want to change the standard browser behavior in a web app where a mousedown click would cause the click action to happen before the button is released. I want this for all the hyperlinks in an app.
Is there a simple way to accomplish this in jQuery?
I am not looking for a solution to change every link individually. It should be a global event handler which works in current and future links.
Example:
in Yahoo Mail, as soon as you click on a tab, that tab gets focus. It happens before the button is released.
There's a requirement to mimic this behavior for hyper links
If I'm understanding you correctly and you want to override the default link behavior, something like this should work:
$(function(){
$("a").bind({
click: function(e){
e.preventDefault();
},
mouseenter: function(){
window.location.href = $(this).attr("href");
}
});
});
Here's a jsFiddle: http://jsfiddle.net/H2L4D/1/
You need http://api.jquery.com/mousedown/
$('a').mousedown(function() {
alert('Handler for .mousedown() called.');
});
$('a').unbind('click');
$('a').bind('mousedown', function() {
//alert('mousedown happened');
});
If you'd like it to apply to all hyperlinks over the lifetime of the page, even dynamically-created ones, you'll want something like this:
$('a').live('mousedown', function(evt)
{
// this stops the default behaviour of the event
evt.preventDefault()
// This changes the location of the page to the href value of the element you clicked
window.location.href = $(this).attr("href");
});
Many times I've seen links like these in HTML pages:
<a href='#' onclick='someFunc(3.1415926); return false;'>Click here !</a>
What's the effect of the return false in there?
Also, I don't usually see that in buttons.
Is this specified anywhere? In some spec in w3.org?
The return value of an event handler determines whether or not the default browser behaviour should take place as well. In the case of clicking on links, this would be following the link, but the difference is most noticeable in form submit handlers, where you can cancel a form submission if the user has made a mistake entering the information.
I don't believe there is a W3C specification for this. All the ancient JavaScript interfaces like this have been given the nickname "DOM 0", and are mostly unspecified. You may have some luck reading old Netscape 2 documentation.
The modern way of achieving this effect is to call event.preventDefault(), and this is specified in the DOM 2 Events specification.
You can see the difference with the following example:
Google
Clicking "Okay" returns true, and the link is followed. Clicking "Cancel" returns false and doesn't follow the link. If javascript is disabled the link is followed normally.
WHAT "return false" IS REALLY DOING?
return false is actually doing three very separate things when you call it:
event.preventDefault();
event.stopPropagation();
Stops callback execution and returns immediately when called.
See jquery-events-stop-misusing-return-false for more information.
For example :
while clicking this link, return false will cancel the default behaviour of the browser.
<a href='#' onclick='someFunc(3.1415926); return false;'>Click here !</a>
Here's a more robust routine to cancel default behavior and event bubbling in all browsers:
// Prevents event bubble up or any usage after this is called.
eventCancel = function (e)
{
if (!e)
if (window.event) e = window.event;
else return;
if (e.cancelBubble != null) e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
if (e.preventDefault) e.preventDefault();
if (window.event) e.returnValue = false;
if (e.cancel != null) e.cancel = true;
}
An example of how this would be used in an event handler:
// Handles the click event for each tab
Tabstrip.tabstripLinkElement_click = function (evt, context)
{
// Find the tabStrip element (we know it's the parent element of this link)
var tabstripElement = this.parentNode;
Tabstrip.showTabByLink(tabstripElement, this);
return eventCancel(evt);
}
Retuning false from a JavaScript event usually cancels the "default" behavior - in the case of links, it tells the browser to not follow the link.
I believe it causes the standard event to not happen.
In your example the browser will not attempt to go to #.
Return false will stop the hyperlink being followed after the javascript has run. This is useful for unobtrusive javascript that degrades gracefully - for example, you could have a thumbnail image that uses javascript to open a pop-up of the full-sized image. When javascript is turned off or the image is middle-clicked (opened in a new tab) this ignores the onClick event and just opens the image as a full-sized image normally.
If return false were not specified, the image would both launch the pop-up and open the image normally. Some people instead of using return false use javascript as the href attribute, but this means that when javascript is disabled the link will do nothing.
using return false in an onclick event stops the browser from processing the rest of the execution stack, which includes following the link in the href attribute.
In other words, adding return false stops the href from working. In your example, this is exactly what you want.
In buttons, it's not necessary because onclick is all it will ever execute -- there is no href to process and go to.
The return false is saying not to take the default action, which in the case of an <a href> is to follow the link. When you return false to the onclick, then the href will be ignored.
Browser hack:
http://jszen.blogspot.com/2007/03/return-false-to-prevent-jumping.html
Return false will prevent navigation. Otherwise, the location would become the return value of someFunc
The return false prevents the page from being navigated and unwanted scrolling of a window to the top or bottom.
onclick="return false"
I am surprised that no one mentioned onmousedown instead of onclick. The
onclick='return false'
does not catch the browser's default behaviour resulting in (sometimes unwanted) text selection occurring for mousedown but
onmousedown='return false'
does.
In other words, when I click on a button, its text sometimes becomes accidentally selected changing the look of the button, that may be unwanted. That is the default behaviour that we are trying to prevent here. However, the mousedown event is registered before click, so if you only prevent that behaviour inside your click handler, it will not affect the unwanted selection arising from the mousedown event. So the text still gets selected. However, preventing default for the mousedown event will do the job.
See also event.preventDefault() vs. return false
I have this link on my HTML-page:
<a href = ""
onclick = "setBodyHtml ('new content'); return false; "
> click here </a>
The function setBodyHtml() is defined as:
function setBodyHtml (s)
{ document.body.innerHTML = s;
}
When I click the link the link disappears and the text shown in the browser
changes to "new content".
But if I remove the "false" from my link, clicking the link does (seemingly) nothing. Why is that?
It is because if I don't return false the default behavior of clicking the link and displaying its target-page happens, is not canceled. BUT, here the href of the hyperlink is "" so it links back to the SAME current page. So the page is effectively just refreshed and seemingly nothing happens.
In the background the function setBodyHtml() still does get executed. It assigns its argument to body.innerHTML. But because the page is immediately refreshed/reloaded the modified body-content does not stay visible for more than a few milliseconds perhaps, so I will not see it.
This example shows why it is sometimes USEFUL to use "return false".
I do want to assign SOME href to the link, so that it shows as a link, as underlined text. But I don't want the click to the link to effectively just reload the page. I want that default navigation=behavior to be canceled and whatever side-effects are caused by calling my function to take and stay in effect. Therefore I must "return false".
The example above is something you would quickly try out during development. For production you would more likely assign a click-handler in JavaScript and call preventDefault() instead. But for a quick try-it-out the "return false" above does the trick.
When using forms,we can use 'return false' to prevent submitting.
function checkForm() {
// return true to submit, return false to prevent submitting
}
<form onsubmit="return checkForm()">
...
</form>
By default, when you click on the button, the form would be sent to server no matter what value you have input.
However, this behavior is not quite appropriate for most cases because we may want to do some checking before sending it to server.
So, when the listener received "false", the submitting would be cancelled. Basically, it is for the purpose to do some checking on front end.