Right click stop propagation - javascript

How do I stop the propagation for right click events in javascript, so parent elements do not detect them at all?
When I click the link in the following html, left clicks are not detected, but right clicks are detected by the document element as 'click' events instead of 'contextmenu' events. I've tried to attach event listeners to mousedown, contextmenu, but to no success.
[EDIT] Changing the code to contextmenu works on chrome but not firefox (v23.0.1), this is probably a firefox bug.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="application/javascript;version=1.8">
function log(s){
document.getElementById('log').innerHTML+=s+'<br/>';
}
window.onload=function(){
document.addEventListener('click',function(e){
log('click detected');
},false);
let link=document.querySelector('a#link');
//click only cares about left clicks
link.addEventListener('click',function(e){
e.stopPropagation();
return false;
},false);
};
</script>
</head>
<body>
<a id="link" href="javascript:void(0);">Link</a>
<div id="log"></div>
</body>
</html>

The 'right click' event is called the 'contextmenu' event.
http://www.quirksmode.org/dom/events/contextmenu.html
Example:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script>
function log(s){
document.getElementById('log').innerHTML+=s+'<br/>';
}
window.onload=function(){
document.addEventListener('click',function(e){
log('click detected');
},false);
document.addEventListener('contextmenu', function(e){
log('right-click detected');
}, false);
var link=document.querySelector('a#link');
link.addEventListener('click',function(e){
e.stopPropagation();
return false;
},false);
link.addEventListener('contextmenu',function(e){
e.stopPropagation();
return false;
},false);
};
</script>
</head>
<body>
<a id="link" href="javascript:void(0);">Link</a>
<div id="log"></div>
</body>
</html>

Chrome won't execute script tags, including a version , for some reason, so i replaced let with var...
Stopping the propagation of a contextmenu event triggered from a#Link to document works fine for me, in Chrome and Firefeox, here is the example i used.
Edit
the contextmenu events are detected by the document element as click events instead.
In this case you can use a mousedown event, and add the condition event.which === 3
I updated the example, and added an example on JSBin
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<a id="link" href="javascript:void(0);">Link</a>
<div id="log"></div>
<script type="application/javascript">
window.onload = function () {
var link = document.querySelector('a#link');
function log(s) {
document.getElementById('log').innerHTML += s + '<br/>';
}
document.addEventListener('mousedown', function (e) {
if (e.which === 3) {
var src = e.target || e.srcElement;
log((src.nodeName === 'A' ? 'bubbled' : 'direct') + ' contextmenu on document detected');
}
}, false);
link.addEventListener("mousedown", propagate);
function propagate(e) {
if (e.which === 3) {
log("contextmenu on link, propagating");
link.removeEventListener("mousedown", propagate);
link.addEventListener("mousedown", nopropagate);
}
}
function nopropagate(e) {
if (e.which === 3) {
log("contextmenu on link, nopropagating");
e.stopPropagation();
}
}
}
</script>
</body>
</html>
Now rightclicking in the following order gives us these outputs.
rightclick on document
rightclick on link (propagates on first click)
rightclick on link (doesn't propagate)
Screenshots are from Firefox 20.0

Related

How to deactivate beforeunload event listener in JavaScript

I'm trying to activate a page reloader preventer, and be able to deactivate the reloader preventer. In other words, I was able to show a dialog when user was about to unload/reload their page, but I'm currently looking for a way to let the user to unload/reload their page without any dialogs or warnings after a certain function has been called.
Maybe removing the event listener will help?
This is the code that I'm working with:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button onclick="activateReloader()">activate</button>
<button onclick="deactivateReloader()">deactivate</button>
<script>
function activateReloader() {
window.addEventListener('beforeunload', function (e) {
// Cancel the event
e.preventDefault();
// Chrome requires returnValue to be set
e.returnValue = '';
});
}
function deactivateReloader() {
window.removeEventListener('beforeunload', function (e) {});
}
</script>
</body>
</html>
removeEventListener works by checking the reference of the function you've passed to it, and seeing if it's been previously added by addEventListener. This means that if you want to remove a listener at a later time, you can't add it as an anonymous function - you need to have a reference to it:
function onBeforeUnload(e) {
// Cancel the event
e.preventDefault();
// Chrome requires returnValue to be set
e.returnValue = '';
}
function activateReloader() {
window.addEventListener('beforeunload', onBeforeUnload);
}
function deactivateReloader() {
window.removeEventListener('beforeunload', onBeforeUnload);
}

Cloned content editable div not retaining keydown event

I'm very new to Jquery and looking to solve the reason a keydown event on a content editable div isn't cloning. I thought I had solved things when I discovered clone(true), but no my code still isn't working. The code below is a simplified version of what I'm trying to achieve.
Basically I'm attaching a keydown event to a content editable div then cloning it. However the cloned div isn't working like the original div.
I've been searching for a solution for a good while now and was hope someone could give me an answer so I can move on - many thanks.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>untitled</title>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var mymax1 = 10;
$('#List_1').keydown(function(e){ check_charcount(mymax1, e); });
function check_charcount(mymax1, e)
{
<!--prevent line breaks, that is the enter key from working-->
if(e.keyCode==13){
e.preventDefault();
}
if(e.which != 8 && $('#List_1').text().length > mymax1{
$("#List_1").css("background-color","yellow");
e.preventDefault();
}
}
<!---->
var $cloned = $('#hope').clone(true);
$('#placeHere').append($cloned.html());
});
</script>
</head>
<body>
<div id="hope">
<div id="List_1" contentEditable="true">TEXT</div>
</div>
</br>
<div id="placeHere"></div>
</body>
</html>
Some things were not correct in your code as pointed Ian.
In your keydown function you are using $('list_1'), you should use reference to element.
BTW, clone keep id attr which mean that your cloned element get same id as original, which is not valid. See working code:
$(document).ready(function () {
var mymax1 = 10;
$('#List_1').keydown(function (e) {
check_charcount(mymax1, e);
});
function check_charcount(mymax, e) {
if (e.keyCode == 13) {
e.preventDefault();
}
if (e.which != 8 && $(e.target).text().length > mymax) {
$(e.target).css("background-color", "yellow");
e.preventDefault();
}
}
var $cloned = $('#hope').clone(true);
$('#placeHere').append($cloned.contents().removeAttr('id'));
});
SEE DEMO

Javascript: Eventhandler not functioning, works in JSFiddle

So this is an answer to another question I posted and I think it is the correct solution. However, while it works wonderfully in jsfiddle it does not function whatsoever outside of that environment. I have tried multiple combinations and I cannot get this thing to work right.
I've tried onLoad in the body, Window.onload both in the header wrapping around the function and separately calling it at the base of the page after all the elements have loaded. Nothing works.
I always get this issue:
Uncaught TypeError: Cannot call method 'addEventListener' of null
Which is frustrating, because all other solutions to this error I have seen revolve around ensuring you do in fact have the specified ID the handler triggers off of in your HTML. Which I do.
I know its probably overkill to make a post here on this but I'm yanking my hair out.
Here's the JSfiddle: http://jsfiddle.net/fFW5r/1/
Here's a mockup page I made to test the concept (which never works):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript">
var link_container = document.getElementById('links');
function myFunction(){ link_container.addEventListener('click', function(e){
if(e.target.nodeName === "A"){
var href = e.target.getAttribute('href'),
selfhost = window.location.hostname;
if(href.indexOf(selfhost) !== -1){
alert('Inbound link clicked');
} else {
alert('Outbound link clicked');
}
}
}, false);
}
</script>
</head>
<body onload="myFunction()">
<div id="links">
Inbound Link
Outbout Link
</div>
<script>window.onload=myFunction()</script>
</body>
</html>
This particular iteration I was trying to test it with the onload call at the bottom of the page after everything had loaded.
var link_container = document.getElementById('links'); need to be executed on document.onload so it has to be inside myFunction
In jsfiddle, the code is executed on load by default. in the fiddle at the left side panel > second select box if you select no wrap - in head you can recreate the problem.
Demo: Fiddle
<script type="text/javascript">
function myFunction(){
var link_container = document.getElementById('links'); // <<-- Move it inside `myFunction()`
link_container.addEventListener('click', function(e){
if(e.target.nodeName === "A"){
var href = e.target.getAttribute('href'),
selfhost = window.location.hostname;
if(href.indexOf(selfhost) !== -1){
alert('Inbound link clicked');
} else {
alert('Outbound link clicked');
}
}
}, false);
}
</script>
The reason it doesn't work is that you are initializing link_container before the DOM is ready. Then when myFunction() runs, link_container has been initialized to undefined. Which causes it to fail. Initializing it in the function (after the DOM has loaded) should fix the issue
Put declare link_container inside the function.
var link_container = document.getElementById('links');
function myFunction(){
link_container.addEventListener('click', function(e){
if(e.target.nodeName === "A"){
var href = e.target.getAttribute('href'),
selfhost = window.location.hostname;
if(href.indexOf(selfhost) !== -1){
alert('Inbound link clicked');
} else {
alert('Outbound link clicked');
}
}
}, false);
}

Add event handler to HTML element using javascript

I want to add an event handler to a paragraph for when any user clicks on it. For example, I have a paragraph which would show an alert when a user clicks it, but without using "onclick" on HTML.
<p id="p1">This is paragraph Click here..</p>
<a href="http://www.google.com" id="link1" >test</a>
document.getElementById('p1').onmouseover = paragraphHTML;
You can add event listener.
Smth. like this:
var el = document.getElementById("p1");
if (el.addEventListener) {
el.addEventListener("click", yourFunction, false);
} else {
el.attachEvent('onclick', yourFunction);
}
(thanks #Reorx)
Explanation Here
Complete code (tested in Chrome&IE7):
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1255">
<script type="text/javascript">
window.onload =function (){
var el = document.getElementById("p1");
if (el.addEventListener) {
el.addEventListener("click", yourFunction, false);
} else {
el.attachEvent('onclick', yourFunction);
}
};
function yourFunction(){
alert("test");
}
</script>
</head>
<body>
<p id="p1">test</p>
</body>
</html>
To suit most situations, you can write a function to handle this:
var bindEvent = function(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else {
element.attachEvent('on'+type, handler);
}
}
Add a tabIndex attribute to your p element, then you can use the onfocus function.
demo: http://jsfiddle.net/9y7CL/

Add event listener to all objects except for a few selected?

I'm trying to add event listener to all objects except for a few selected (the selected also have arbitrary child elements in arbitrary levels)?
I have asked this question before, but I didn't really got an answer to it. I have came close to solve it. Could you please help me with debugging it?
I'm adding an event listener to the body element called bodylistener and an event listener to the few selected elements called selectedElementsMarkTrue. The few selected elements that I don't want to execute some code, the listener selectedElementsMarkTrue performs prior to bodylistener with setTimeout function. selectedElementsMarkTrueset the variable selectedElements to true and bodylistenerchecks if selectedElements is true before execute some code. There is still something wrong with my code:
var selectedElements = false;
var bodylistener = function(){
window.setTimeout(function(){//Setting timeout so that the other handler, selectedElementsMarkTrue, always performs first
(function(){
if(selectedElements == false){
//Do some stuff
}else{
selectedElements = false;
}
});
}, 10);//Could be 0, but te be sure I set 10
};
var selectedElementsMarkTrue = function(){
selectedElements = true;
};
$('#dontAddEventListener1, #dontAddEventListener2').each(function(){
this.addEventListener('click', selectedElementsMarkTrue, false);
});
document.body.addEventListener('click', bodylistener, false);
I can't get the setTimeout function to execute the underlying code?
Sounds like you want behavior something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
window.addEventListener("DOMContentLoaded", function() {
document.body.addEventListener("click", function(e) {
var el = e.target;
do {
if (el.hasAttribute && el.hasAttribute("data-nofire")) {
return;
}
} while (el = el.parentNode);
alert('do stuff');
}, true);
}, false);
</script>
</head>
<body>
<p><span>click me</span></p>
<p data-nofire><span>click me</span></p>
<p data-nofire>click me</p>
<p>click me</p>
</body>
</html>
Or, you could do it something like Naren suggested:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
window.addEventListener("DOMContentLoaded", function() {
var nofire = document.getElementsByClassName("nofire");
for (var i = 0; i < nofire.length; ++i) {
nofire[i].addEventListener("click", function(e) {
e.stopPropagation();
}, true);
}
document.body.addEventListener("click", function(e) {
alert('do stuff');
}, false);
}, false);
</script>
</head>
<body>
<p><span>click me</span></p>
<p class="nofire"><span>click me</span></p>
<p class="nofire">click me</p>
<p>click me</p>
</body>
</html>
prevent event propagation by handling elements click event
$('#dontAddEventListener1, #dontAddEventListener2').click( function(event){ event.preventDefault(); return false; });

Categories