I'm developing for a site that does something a bit strange with some links.
When the user clicks on a link, an indicator GIF that looks kinda like this appears next to the link, and the link itself is disabled. It then navigates to the page. This is because of concerns that impatient users might repeatedly click the link if it doesn't load immediately, putting an extra load on our server.
Here's how we do this:
<a id="link1" href="/target_page"
onclick="var link = document.getElementById('link1');
var loc = link.href;
link.removeAttribute('href');
link.setAttribute('onclick', 'return false;');
document.getElementById('link1_img').style.display='';
window.location = loc;">
Link Text
<img id="link1_img" src="/images/indicator.gif" style="display:none;" />
</a>
Here's the problem. While this has the expected behavior if the user clicks on the link normally, or right-clicks it and opens it in a new window or tab from the context menu, it doesn't always work properly if the user middle-clicks or Ctrl+clicks on the link.
The desired behavior in that case would be to skip all the JavaScript stuff and simply open the link in a new tab. I did a quick test on Windows with the latest version of each major browser, and IE, Firefox, and Opera all do this. Chrome and Safari, however, display the indicator and open the link in the current tab.
Any suggestions on how to make it behave consistently on all browsers?
You can use the code here for handling middle clicks, and take a look here for the Ctrl+click. However, I found that I had to use .mousedown for middle clicks instead of clicks (at least in Firefox).
If you use
$('#link').click(function(e) {
if(e.ctrlKey && e.which == 1 || e.which == 2) { // Ctrl + Click
console.log("hi");
$(this).css('color','#aaa');
$(this).click(function(e) { e.preventDefault(); });
}
});
and don't add e.preventDefault(), it should work as expected. Works for me in Firefox, Chrome, and IE9.
Edit: Without jQuery, this is how I would do it. Do take a look at this post about preventDefault() vs return false;, though.
document.querySelector('#link').onclick = function(e) {
this.style.color = '#aaa';
disableLink(this);
}
// middle clicks only captured in mousedown
document.querySelector('#link').onmousedown = function(e) {
this.style.color = '#aaa';
if (e.button == 1) {
disableLink(this);
}
}
function disableLink(elem) {
elem.onclick = function(e) { console.log("HI"); this.href = '#'; return false;}
elem.onmousedown = function(e) { console.log("HI"); this.href = '#'; return false;}
}
Unfortunately, there seems to be a difference in the way Chrome and Firefox handle middle clicks. Firefox only shows middle clicks in onmousedown, and it opens a new tab during the onmousedown. This means that for Firefox, we have to disable the link after onmousedown. However, in Chrome, the middle click shows up in onmousedown and onclick, but the link is only opened after the onclick. Since we disable the link on the mousedown, the onclick never gets a chance to run :(.
Not sure how to fix this...
Related
I have the following link that when clicked, opens a new tab and refreshes the page with the link in.
It works fine in Safari and Chrome but opens duplicate tabs in Firefox.
Run Letters
function openWindowReload(link) {
var href = link.href;
window.open(href,'_blank');
location.href = 'index.php' + "?welcome_letters=export&welcome_letters=export"
}
Any ideas why Firefox is doing this and how to resolve it?
I think it's because you don't stop the default behavior.
Could you call preventDefault on the click event?
As i'm trying to prevent to ctr + click event in all the anchor tags in the html application. So can suggest me how to make an effective way to do in all the browsers using javascript or Jquery. Thanks in Advance
<a href="myapplication1.html" >myapplication1.html</a>
<a href="myapplication2.html" >myapplication2.html</a>
<a href="myapplication3.html" >myapplication3.html</a>
I question the wisdom of doing this and some of the comments below support this. FireFox is being very protective when it comes to opening a new tab, and in my opinion rightly so. You need a VERY good excuse to break expected browser behavior.
That being said here is a jQuery Approach, that currently works with IE, Edge and Chrome, but not Firefox.
//Apply to all a tags
$("a").on("mousedown", function(event){
//If middle mouse buton or normal click with ctrl
if(event.which == 2 || (event.which == 1 && event.ctrlKey)) {
console.log("Block");
//Stop default behavior
event.preventDefault();
//Let the user know what is happening and give them options
if(confirm("Please don't open links in new tabs. Click 'OK' to open the link in this window")){
//change location of current tab
window.location.href = $(this).attr("href");
}
return false;
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="https://www.google.com" >Google</a>
<a href="https://www.bing.com" >Bing</a>
<a href="https://stackoverflow.com" >Stack Overflow</a>
Add action listener on all achors detecting the ctrl press
On your template
<a onclick="blockCtrl()">Click Me</a>
JS to detect ctrl key press and prevent the action from happening.
function blockCtrl(e){
if (window.event.ctrlKey) {
//ctrl was held down during the click
return false;
}
return true;
}
I do not think it is a complicated thing to solve. Small research will get you to answer this question.
However, you can prevent any user action on your page using javascript.
You just have to access the event object. Do as shown below,
function blockClick(e){
if(e.ctrlKey && e.type == "click")
{
console.log("ctrl + mouse clicked !")
e.preventDefault();
}
}
<a href="myapplication1.html" onclick="blockClick(event)" >myapplication1.html</a>
myapplication2.html
myapplication3.html
This should work. Happy coding.
Update
User Quentin helped me solve it. The lightbox had a event.stopPropagation(); in the function which prevented the eventlistener from bubbling up. After removing it the links worked properly.
I used this comment with honyovk's addition to replace the stopPropagation with a more elegant function: https://stackoverflow.com/a/1089622/3461722
Question
I have a webapp for iOS in which I use an EventListener to prevent links from opening in Safari. This works flawless for 99% of the links, but a few specific links still open in Safari for some reason unknown to me.
This is my Javascript:
// Mobile Safari in standalone mode
if(("standalone" in window.navigator) && window.navigator.standalone){
// If you want to prevent remote links in standalone web apps opening Mobile Safari, change 'remotes' to true
var noddy, remotes = false;
document.addEventListener('click', function(event) {
noddy = event.target;
// Bubble up until we hit link or top HTML element. Warning: BODY element is not compulsory so better to stop on HTML
while(noddy.nodeName !== "A" && noddy.nodeName !== "HTML") {
noddy = noddy.parentNode;
}
if('href' in noddy && noddy.href.indexOf('http') !== -1 && (noddy.href.indexOf(document.location.host) !== -1 || remotes))
{
event.preventDefault();
document.location.href = noddy.href;
}
},false);
}
The links that fail to open in the webapp are nothing special, and other links on the page work without problem. An example of a not properly working link:
Buy
This link is opened in a lightbox, but on other pages I have similar links also in a lightbox and they work fine. I have several popups with roughly the same link, only the "green" is different and some have an extra "&time=1", they all fail to open in the webapp.
Is there someone who can find fault with this code?
I want to show a confirmation dialog(Are you sure?) with 2 button "Yes" and "Cancel" before exit when the user press the native back button on the home(first) screen. And based on the buttons the decision should be made.
My question is where do I write the confirm dialog(/popup) code. I tried inside onExit(), but its not working.
Thanks.
You have to attach on the right browser resp. native events. Here are the best guesses I found:
How to prevent Android from closing web-application when backbutton is pressed?
detect back button click in browser
http://www.irt.org/script/311.htm
window.onbeforeunload = function (e) {
var e = e || window.event;
var msg = "Do you really want to leave this page?"
// For IE and Firefox
if (e) {
e.returnValue = msg;
}
// For Safari / chrome
return msg; };
That piece of code appears not to work on iOS, not sure about Android.
Another possibility would be to make your page open in a new window or use a redirect. This way your application would be the first page in window.history stack and there will be no back beyond your start page.
GL
Chris
I am working on a site that provides the user with quotes and reservations for rental equipment. If the user gets more than a few steps into the processes and chooses to close the browser or navigate away before finishing then the client would like to offer then a special deal. The client would like to prevent the window from closing and ask them for their phone number so they can call them with a better rate if one becomes available.
I can prevent the window from closing and the prevent the browser from navigating away. When this happens, a div is displayed with a little for for the user to submit and an option to go ahead and close the window. This all works fine. The problem is that if the user refreshes the page or hits the back or forward buttons then the action is being blocked just as if the user was closing the browser. But I don't care if they go forward or back or refresh the page because that means they are still in the reservation process. Unfortunately, I cannot distinguish between the two types of events.
I am attaching a function to the onbeforeunload event to trigger the message to the user. The site I am working on is an ASP.NET site, if that is helpful to anyone.
Here is the code I am using. The elements divSecondClose and divThankYou are both set to display:none when the page first loads. <%=DisplayThankYou%> is set to 'true' after the form has been submitted so that a thank you message appears.
var showSecondCloseOnExit = true;
var displayThankyou = '<%=DisplayThankYou %>';
if (displayThankyou == true)
{
var divSecondClose = document.getElementById('divSecondClose');
divSecondClose.style.display = '';
var divThankYou = document.getElementById('divThankYou');
divThankYou.style.display = '';
showSecondCloseOnExit = false;
}
else
{
addListener(window, 'beforeunload', CloseWindowEvent, false);
var allLinks = document.getElementsByTagName('a');
for (var linkIndex = 0; linkIndex < allLinks.length; linkIndex++)
{
addListener(allLinks[linkIndex], 'click', function(){showSecondCloseOnExit = false;}, false);
}
}
function CloseWindowEvent(e) {
if(!e) e = window.event;
if (showSecondCloseOnExit)
{
var divSecondClose = document.getElementById('divSecondClose');
divSecondClose.style.display = '';
showSecondCloseOnExit = false;
//e.cancelBubble is supported by IE - this will kill the bubbling process.
e.cancelBubble = true;
e.returnValue = 'RATE CHANGE NOTIFICATION\nWould you take a moment before you leave to help us serve you better?';
//e.stopPropagation works in Firefox.
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
}
}
Have you attempted to sniff the various different values of the event:
*type
*target element
*mouse position
Here is a link with instructive information on accessing each of these. You may be able to figure out what you want through a combination of the above, although the checking all the cases across many browsers seems quite brutal.
http://www.quirksmode.org/js/events_properties.html#type
Also, see these articles for attaching to an event when the window closes and that is all:
How to create popup window when browser close
However, you may also advise the product owner of what you are doing that the cost on doing the functionality you are describing is getting rather high.
NOTE: See Slak's comment here: How to capture the browser window close event? . It may be what you're after.