How to trap right-click event? - javascript

What is the way to trap a right-click event on a document element? I could not find any event handlers anywhere.

Right-click is special on many browsers, triggering the contextmenu event rather than a click event. Some browsers let you prevent the default behavior, some (Opera, for instance) do not. More here: http://unixpapa.com/js/mouse.html
EDIT: Rereading that page (it'd been a while), it looks like mousedown and mouseup are even more reliable than contextmenu (although all major browsers trigger contextmenu). click, on the other hand, doesn't appear to happen at all, on any significant browser.

I think there is event "oncontextmenu", you can hook it.
Here is the jQuery based contextmenu handler,
http://www.trendskitchens.co.nz/jquery/contextmenu/
PS:It doesn't work in My Opera though.

You can use the
window.oncontextmenu
An event handler property for
right-click events on the window.
If you need to disable the right click in a page then you can use something like this
window.oncontextmenu = function () {
return false;
}
or if you need to give your own custom context menu then also you can code inside the function.

You probably want the click or mousedown/up event. From quirksmode:
function doSomething(e) {
var rightclick;
if (!e) var e = window.event;
if (e.which) rightclick = (e.which == 3);
else if (e.button) rightclick = (e.button == 2);
alert('Rightclick: ' + rightclick); // true or false
}

The event has a "button" attrubute
so lmb is 0
mmb is 1
rmb is 2
http://www.w3schools.com/jsref/event_button.asp

Related

Calling an Onclick() function without clicking?

A websites Button isn't rendering on my browser. I know it's there, when I'm in the view source I still see the button, and the onclick function. Can I still call this function by passing the url the function? Or in the console?
Even if it's not an onclick, is it possible to call functions by either URL or Console?
You can click any DOM element by selecting it and calling the click() function.
document.getElementById("yourElementId").click();
Works with Jquery as well.
$(selector).click();
To accomplish this, you can use the following line:
document.getElementById("element_id").click()
According to MDN, this simulates a full click on the element, including all it entails:
When click is used with elements that support it (e.g. one of the types listed above), it also fires the element's click event which will bubble up to elements higher up the document tree (or event chain) and fire their click events too. However, bubbling of a click event will not cause an element to initiate navigation as if a real mouse-click had been received.
Alternatively, you can use jQuery to accomplish the same thing:
$("#trigger").click();
Here is the simplest way:
function fireClick(node){
if ( document.createEvent ) {
var evt = document.createEvent('MouseEvents');
evt.initEvent('click', true, false);
node.dispatchEvent(evt);
} else if( document.createEventObject ) {
node.fireEvent('onclick') ;
} else if (typeof node.onclick == 'function' ) {
node.onclick();
}
}
So you can trigger the click event for an element like below:
fireClick(document.getElementById('id'));
Reference from here.

Stop propagation doesn't work

I have the below JQuery eventhandler. I want to stop all navigations on a web page.
$(document).click(function(event) {
event.stopPropagation();
event.preventDefault();
event.cancelBubble = true;
event.stopImmediatePropagation();
$(document).css('border-color','');
$(document).css('background-color','');
$(event.target).css('border-color','yellow');
$(event.target).css('background-color','#6BFF70');
return false;
});
When I use this on Facebook Login page, it stops all navigations. But in Google home page, "I'm Feeling Lucky" button still navigates to next page. How do I avoid it?
I'm using JavaFX browser by the way. It is similar to Safari browser.
If I load the Google search page, and execute this at the console:
document.body.addEventListener(
"click",
function (ev) { ev.stopPropagation(); ev.preventDefault(); },
true);
then I cannot click the "I'm Feeling Lucky" button anymore. The key is to use the third parameter and set it to true. Here is what MDN [says] about it:
useCapture Optional
If true, useCapture indicates that the user wishes to initiate capture. After initiating capture, all events of the specified type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree.
(Emphasis added.)
What you tried to do does not work because your event handler is on document, and thus will be called after any event handlers on the children of the document. So your handler cannot prevent anything.
With useCapture set to true, you can operate on the event before it gets a chance to be passed to the child element. I do not know of a way to have jQuery's event handlers work in the way you get with useCapture. Barmar's answer here says you can't use jQuery to set such handler. I'm inclined to believe him.
99.99% of webpages won't be able to have their navigation stopped by stopping event propagation for the reason I commented (you can't stop the event before it triggers all handlers for the initial target of the event). If preventing navigation is all you are interested in, I recommend using the window.onbeforeunload event, which is made for this exact situation.
Here is an example: http://jsfiddle.net/ejreseuu/
HTML:
google
JS:
window.onbeforeunload = function() {
return "Are you sure?"
}
There is no way to not have a confirmation box that I know of, as code that locks the user out of navigating away no matter what they do is generally malicious.
preventDefault() should not work in this case, cause Google relied on custom event listeners to handle click events on this button. While preventDefault()
prevents browser's default behavior.
For example, if this button was of type="submit", preventing default on click event would prevent browser's default behavior, which is submitting a form. But in this case click is handled by eventListeners added to the button itself. preventDefault() won't affect catching an event by them. Nor stopPropagation(), because it stops propagation of event to higher levels of DOM, while other eventListeners on the same level (button in our case) still get the event. stopImmediatePropagation() could work in theory, but only if your eventListener was added before google's.
So the easiest way to stop propagation is to stop an event before it reaches button node, and that's on capture phase, because button is the lowest element in the hierarchy. This can be done by passing true argument while adding eventListener
document.body.addEventListener("click", function (event) {
event.stopPropagation();
}, true);
This way event will be stopped before bubble phase, and so before it reaches eventListeners added to the button. More on capture and bubble phases here
Note that preventDefault() is not needed in this case. Actually, this button's event listeners are to prevent default themselves. Here are those eventListeners, for click and keyup respectively:
d = function(a) {
c.Xa.search(c.yc(), b);
return s_1vb(a)
}
function(a) {
13 != a.keyCode && 32 != a.keyCode || d(a)
}
note call to s_1vb, here is its sourse:
s_1vb.toString();
/*"function (a){
a&&(a.preventDefault&&a.preventDefault(),a.returnValue=!1);
return!1
}"*/
Basically its a function that take an event and do everything possible to prevent browser's default behavior
By the way, default behavior can be canceled on any stage of event flow (se Events Specification), including the very last stage, when it reached document. Only after it passed "through" all eventListeners uncanceled, browser should execute its default behavior. So attaching your listener to document was not the reason preventDefault() didn't work, it was because it was the wrong guy for the job :)
Try this:
$('body').click(function(event) {
event.stopPropagation();
event.preventDefault();
event.cancelBubble = true;
event.stopImmediatePropagation();
$(document).css('border-color','');
$(document).css('background-color','');
$(event.target).css('border-color','yellow');
$(event.target).css('background-color','#6BFF70');
return false;
});
Try to bind not only to click event, but as well on mousedown event.
Try this css:
body * {
pointer-events: none;
}
or in jQuery:
$("body *").css("pointer-events", "none");
Try declaring a new window event and then stopping the propagation from there:
var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation)
{
e.stopPropagation();
}
Note that Google uses jsaction="..." instead of onclick="...". Try to use it's unbind method on the specified button.
Also you can use dynamic attachment, like:
$(document).on('click', '*', function
Or throw new Error()(just as a dirty hack)

Jquery different data trapped from direct mousedown event and simulation via $(this).trigger('mousedown');

I need to trap some data in my webpage then user make a mousedown event or simulate it when user press TAB key on a page element.
For mousedown i use standard code like:
$('*').on('mousedown', function (e) {
// make sure the event isn't bubbling
if (e.target != this) {
return;
}
//...my code
});
and all work done, for TAB key pressure i use this code for simulate mousedown event
$(':input').keydown(function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
$(this).trigger('mousedown');
}
});
and all seems to be done, but then i look at the e data with
console.dir(e)
there are many difference and in second case many missed data:
SAME ELEMENT CLICK AND TAB EVENTS
CLICK
mousedown event:
TAB
and with $(this).trigger('mousedown');
There are far fewer data!! For example i need e.pageX and e.pageY parameters but if i trigger event there aren't.
How can i have the same e data on both case??
Thanks in advance
In your first print, you could see the "OriginalEvent: MouseEvent" which is the one that provides the pageX/pageY...when you simulate "mousedown" you don't have the original event. Depending on which event type triggered the handler you can't access the original event. Maybe this is the case.

Why doesn't preventDefault() stop focus change after a Tab-keypress?

I was fiddling with preventDefault() and must be doing something wrong.
$("#input").bind("keypress", function(event) {
if(event.which == 9) {
event.preventDefault();
alert("You pressed tab.");
}
});
The tab functionality isn't prevented. What's wrong with this?
Try this FIDDLE. The input loses focus when you tab. Binding to the body fixes this.
$("body").on("keydown", function(event) {
if(event.which == 9) {
event.preventDefault();
alert("You pressed tab.");
}
});
The keypress event is simply not fired when the Tab is pressed - this also explains why there is no alert, independent of what preventing the default may do.
Changing the code to use keydown allows the Tab to be caught and prevents the default focus-change (in Chrome1, anyway).
$("#input").bind("keydown", function(event) {
if(event.which == 9) {
event.preventDefault();
}
});
1 I tested the above in Chrome 35 with jQuery 1.6-2.1; it does not work under the KO 3.0 library.
From the documentation on JQuery,
Note: as the keypress event isn't covered by any official specification, the actual behavior encountered when using it may differ across browsers, browser versions, and platforms.
This method is a shortcut for .on( "keypress", handler ) in the first two variations, and .trigger( "keypress" ) in the third.
The keypress event is sent to an element when the browser registers keyboard input. This is similar to the keydown event, except that modifier and non-printing keys such as Shift, Esc, and delete trigger keydown events but not keypress events. Other differences between the two events may arise depending on platform and browser.
So in this case you are using the wrong event. Also it might have browser compatibility issues.

Why can't a mouseup event prevent a click event

jsfiddle
<div class='wrapper'>
<button class='child'>Click me</button>
</div>
function h(e) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
alert(e.type);
return false;
}
document.querySelector('.wrapper').addEventListener('mouseup', h, false);
document.querySelector('.child').addEventListener('click', h, false);
I expect this to prevent the 'click' event from firing, but it doesn't. However, changing mouseup to mousedown does in fact prevent the click event.
I've also tried setting the useCapture argument to true, and that also doesn't produce the desired behavior with mouseup. I've tested this on Chrome and Firefox. Before I file bugs, I figured I'd ask here.
Is this a bug in current browsers, or is it documented behavior?
I've reviewed the W3C standard (DOM level 2), and I wasn't able to find anything that could explain this behavior, but I could have missed something.
In my particular case, I'm trying to decouple two pieces of code that listen to events on the same element, and I figured using capture events on the part that has priority would be the most elegant way to solve this, but then I ran into this problem. FWIW, I only have to support officially supported versions of FF and Chrome (includes ESR for FF).
Check out this quirksmode article
The click event:
Fires when a mousedown and mouseup event occur on the same element.
So when the mouse click is released, both the mouseup and click events are fired, click doesn't wait for the mouseup callback to finish. Almost always, mouseup and click can be used synonymously.
In order to cancel the click, like you demonstrated, you can return false in the mousedown event callback which prevents the click event from ever completing.
I just want to provide my work around for this issue:
let click_works = true
this.addEventListener('mousedown', e => {
click_works = // condition why the click may work or not
})
this.addEventListener('click', e => {
if (click_works) // Do your stuff
})
Hopefully, it will help someone.
Finally found a way to prevent click event from firing. Tested on latest Chromium and Firefox. It may be some bug or implementation details.
Solution
Handle onpointerdown or onpointerup event, remove the element and insert it in the same position.
<span>
<button onpointerdown="let parent = this.parentElement; this.remove(); parent.appendChild(this);" onclick="alert();">TEST</button>
</span>
Result
onpointerdown
onmousedown
onpointerup
onmouseup
<-- no click event occures

Categories