prevent link click event except open in new window hotkey is pressed - javascript

So I have my website, a website without reload between site switches.
For SEO reasons, my links look like this:
View more
<script>
// code is strongly simplified, for more clarity
document.getElementById("viewmore").addEventListener("click",function(e) {
e.preventDefault();
myHandler.goTo(e.currentTarget.href);
});
</script>
myHandler is the site handler in this case.
If I click the hotkey for opening a link in a new tab (on Mac it is CMD+Click), it does not work, as the event is prevented.
How to check if the link should open in a new tab or not? (Check if the hotkey is pressed or not)

Not sure I understood it, but try this
document.getElementById("viewmore").addEventListener("click", (e) => {
// ctrlKey / altKey / shiftKey
if (e.ctrlKey) myHandler.goTo(e.currentTarget.href);
else e.preventDefault();
});

You can store the state of the CMD key in a variable and check it when the link is clicked.
let isCmdPressed = false;
document.addEventListener("keydown",(e)=>{
if (e.key == "Meta"){
isCmdPressed = true;
}
});
document.addEventListener("keyup",(e)=>{
if (e.key == "Meta"){
isCmdPressed = false;
}
});
document.getElementById("viewmore").addEventListener("click",function(e) {
if (!isCmdPressed){
e.preventDefault();
myHandler.goTo(e.currentTarget.href);
}
});

Related

Distinguish between different types of beforeunload events

In JavaScript, is it possible to distinguish between beforeunload events that were triggered by the user closing a browser tab vs clicking a mailto link?
Basically, I would like to do this:
window.addEventListener("beforeunload", function (e) {
if(browserTabClosed) {
// Do one thing
}
else if (mailtoLinkClicked) {
// Do a different thing
}
}
Found a solution by looking at the event (e below) that gets passed in:
window.addEventListener("beforeunload", function (e) {
// We can use `e.target.activeElement.nodeName`
// to check what triggered the passed-in event.
// - If triggered by closing a browser tab: The value is "BODY"
// - If triggered by clicking a link: The value is "A"
const isLinkClicked = (e.target.activeElement.nodeName === "A");
// If triggered by clicking a link
if (isLinkClicked) {
// Do one thing
}
// If triggered by closing the browser tab
else {
// Do a different thing
}
}
The beforeunload method has an unstable behaviour between browsers, the reason is that browser implementations try to avoid popups and other malicious code runned inside this handler.
There is actually no general (cross-browser) way to detect what triggered the beforeunload event.
Said that, in your case you could just detect a click on the window to discriminate between the two required behaviours:
window.__exit_with_link = false;
window.addEventListener('click', function (e) {
// user clicked a link
var isLink = e.target.tagName.toLowerCase() === 'a';
// check if the link has this page as target:
// if is targeting a popup/iframe/blank page
// the beforeunload on this page
// would not be triggered anyway
var isSelf = !a.target.target || a.target.target.toLowerCase() === '_self';
if (isLink && isSelf) {
window.__exit_with_link = true;
// ensure reset after a little time
setTimeout(function(){ window.__exit_with_link = false; }, 50);
}
else { window.__exit_with_link = false; }
});
window.addEventListener('beforeunload', function (e) {
if (window.__exit_with_link) {
// the user exited the page by clicking a link
}
else {
// the user exited the page for any other reason
}
}
Obviously it is not the proper way, but still working.
At the same way, you could add other handlers to check other reasons the user left the page (eg. keyboard CTRL-R for refresh, etc.)

Detecting Alt key in Chrome

In my app I need to handle Alt key press/release to toggle additional information on tooltips. However, the first time Alt is pressed, document loses keyboard focus, because it goes to Chrome's menu. If I click any part of the document, it works again (once).
I can avoid this by calling preventDefault, but that also disables keyboard shortcuts such as Alt+Left/Right, which is undesirable.
I can also handle mousemove and check altKey flag, but it looks very awkward when things only update when mouse is moved.
Is there any way to reliably detect current Alt key state in my situation? I would really rather not switch to a different key.
Update: I suppose the best solution would be to call preventDefault only when a tooltip is active.
document.addEventListener("keydown", (e) => {
if (this.curComponent) e.preventDefault();
if (e.which === 18) {
this.outer.classList.add("AltKey");
}
});
document.addEventListener("keyup", (e) => {
if (this.curComponent) e.preventDefault();
if (e.which === 18) {
this.outer.classList.remove("AltKey");
}
});
I had the same issue and I solved thanks to this answer:
document.addEventListener("keyup", (e) => {
if (e.key === "Alt") {
return true; // Instead of e.preventDefault();
});
return true restores normal behavior of Alt+Left/Right chrome keyboard shortcuts.
Keyboard value both left/ right side ALT = 18
jQuery:
$(document).keyup(function(e){
if(e.which == 18){
alert("Alt key press");
}
});
JavaScript
document.keyup = function(e){
if(e.which == 18){
alert("Alt key press");
}
}

How To Disable All Clicks in Iframe

I'm Showing Html Content In Iframe Using following code
var d = $(prentElem).find('#previewEmailTemplateIframe')[0].contentWindow.document;
d.open(); d.close();
$("body", d).append(htmlPopUpContent);
now can i disable all the click events in this iframe. there is no change in domain.
after some workaround i got this to work
x = $(prentElem).find('#' + Iframe).contents();
$(x).find('body').attr('oncontextmenu', 'return false');
for MAC machines force touch
$(x).on('webkitmouseforcedown', function (event) {
event.preventDefault();
return false;
})
$(x).on('webkitmouseforcewillbegin', function (event) {
event.preventDefault();
return false;
})
For normal click disable
$(x).click(function (e) {
e.preventDefault();
return false;
});
It does not look good but it solved my issue...so posting this if anybody faces the same !!!!
But still mozilla firefox does not allow the middle mouse button click to be disabled so this wont work there!!

Disable F5 in Silverlight

Some of my users accidentally hit F5 when they are typing, and cause them to lose all the stuff they have typed. I do not need to prevent hitting Refresh button.
I tried to use the following javascript, but it only works when the user does not focus on the Silverlight app (i.e. it works when the user click on somewhere outside of the SL app, but the onkeydown event is not triggered when the user focus on the SL).
document.onkeydown=function(e) {
var event = window.event || e;
if (event.keyCode == 116) {
event.keyCode = 0;
alert("test");
return false;
}
}
Probably the best way of handling this situation would be to use the onbeforeunload event and ask the user for confirmation. This way you can root out the accidental refreshes or closed tabs from the legitimate ones without handling all possible shortcuts.
window.onbeforeunload = function(e) {
return 'Are you sure you want to leave without saving your changes?';
};
You could even display the confirmation dialog only if there are some unsaved changes.
I'd say, something like this?
document.onkeydown = function()
{
switch (event.keyCode)
{
case 116 : //F5 button
event.returnValue = false;
event.keyCode = 0;
return false;
case 82 : //R button
if (event.ctrlKey)
{
event.returnValue = false;
event.keyCode = 0;
return false;
}
}
}
note: ctrl + r is a shortcut to refresh as well

Trying to get Chrome to show a about to leave page using onbeforeunload

I am working on a Javascript that is suppose to do a click feature on an element as well as showing a pop-up asking if you want to really leave the site (close the tab). Now The code works fine on IE and Firefox. But Chrome while it does do the important thing in terms of doing the click(); It will not show a pop-up asking if I want to leave or not. I Don't know if its a feature I need to enable in the Chrome browser or something else. Here is the code I am using. Any help would be much appreciated.
var validNavigation = false;
function wireUpEvents() {
var dont_confirm_leave = 0;
var leave_message = document.getElementById("kioskform:broswerCloseSubmit");
function goodbye(e) {
if (!validNavigation) {
if (dont_confirm_leave!==1) {
if(!e) e = window.event;
//for IE
e.cancelBubble = true;
e.returnValue = leave_message.click();
//e.stopPropagation works in Firefox.
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
//return works for Chrome and Safari
return leave_message.click();
alert("Removing information.");
//add the code to delete the kiosk information here.
// this is what is to be done.
}
}
}
window.onbeforeunload=goodbye;
// Attach the event keypress to exclude the F5 refresh
jQuery('document').bind('keypress', function(e) {
if (e.keyCode == 116){
validNavigation = true;
}
});
// Attach the event click for all links in the page
jQuery("a").bind("click", function() {
validNavigation = true;
});
// Attach the event submit for all forms in the page
jQuery("form").bind("submit", function() {
validNavigation = true;
});
// Attach the event click for all inputs in the page
jQuery("input[type=submit]").bind("click", function() {
validNavigation = true;
});
}
// Wire up the events as soon as the DOM tree is ready
jQuery(document).ready(function() {
wireUpEvents();
});
You have to return a string in the onbeforeunload function to show the message to the user, see also Setting onbeforeunload on body element in Chrome and IE using jQuery

Categories