I was asked to implement ctrl+mousewheel event for our page site in order to change image offset on user zoom in or zoom out. I found this old answer Override browsers CTRL+(WHEEL)SCROLL with javascript and I`ve tried to do the same.
I downloaded the jQuery Mouse Wheel Plugin for the implementation and here is my code:
var isCtrl = false;
$(document).on('keydown keyup', function(e) {
if (e.which === 17) {
isCtrl = e.type === 'keydown' ? true : false;
}
}).on('mousewheel', function(e, delta) { // `delta` will be the distance that the page would have scrolled;
// might be useful for increasing the SVG size, might not
if (isCtrl) {
e.preventDefault();
alert('wheel');
}
});
The events works fine separately, but if I hold the CTRL button and wheel the mouse the wheel event does not fire.
Does any one have better solution for this or may be I did something wrong?
Fiddle, In order for it to work you have to click in the result box first before trying.
$(window).bind('mousewheel DOMMouseScroll', function(event)
{
if(event.ctrlKey == true)
{
event.preventDefault();
if(event.originalEvent.detail > 0) {
console.log('Down');
}else {
console.log('Up');
}
}
});
To check if the ctrl key is clicked, the event already provides a way to do that. Try this:
.on('mousewheel', function(e) {
if (e.ctrlKey) {
e.preventDefault();
alert('wheel');
}
});
This also works for e.shiftKey, e.altKey etc. I would only listen for the scroll event and there I would check if the ctrlKey is down.
This can be achieved with the wheel event, which is the standard wheel event interface to use.
document.getElementById('id_of_element')
.addEventListener('wheel', (e) => {
if(e.ctrlKey)
alert("Control + mouse wheel detected!");
})
Related
I have set up drag and drop on a list of items so that the user can drag and drop an item into a preview pane and see its content. As expected the cursor changes to the expected "ghost" image and everything works as expected.
Previously, in the same application, I created custom scrollbars that work by nesting mousemove and mouseup within a mousedown on the scrollbar. As the mouse moves the page scrolls. This still works as expected.
However after scrolling, the preview system's drag and drop cursor is messed up: it no longer changes to the expected cursor(s) & attached ghost image.
I suspect that the act of scrolling (dragging the "scrubber" up and down the scrollbar's "track" is somehow triggering the html5 d&d system. I have tried putting e.preventDefault pretty much everywhere in the scrollbar to no effect.
I'm guessing that somehow the html5 d&d needs to be disabled while scrolling, or fooled into thinking that the scrollbar, while not a real drag and drop, has actually completed or reset whatever flags, or fulfilled whatever expectations, the d&d system has for a completed operation.
As a test I used the html5 d&d for the scrollbar (but due to the cursor changes on dragging just looks weird) and as expected the item preview d&d works correctly with all the expected cursor behaviors.
Any suggestions on how to reset so that the d&d cursor shows correctly would be much appreciated.
The code is in an Edge Animate framework, here are the key fragments:
//scrollbar code
Symbol.bindElementAction(compId, symbolName, "${scrubber}", "mouseenter", function(sym, e) {
sym.$("scrubber").attr("draggable", "false");
return false; ///
});
Symbol.bindElementAction(compId, symbolName, "${scrubber}", "mousedown", function(sym, e) {
e.preventDefault();
e.stopPropagation();
var scrubber = sym.$("scrubber");
var mouseButton = e.button;
if(mouseButton == 2){
return false;
}
var doMoveAtEnd = false;
canDrag = true;
sym.$("Hithilite").show();
var barProp = voodoo.scrollbarCalc("", "vertical", "verticalscroll.scrubber.init");
getStage().getSymbol("Domtop").$("Domtopreduced").mousemove(function(e){
e.preventDefault();
e.stopPropagation();
if(mouseButton !== 2 && canDrag){
isDrag = true;
var pos = 0;
var currOffsetY = scrubber.offset().top;
var possibleY = e.pageY;
if(possibleY > currOffsetY){
scrollDir = "up";
}
else if(possibleY < currOffsetY){
scrollDir = "down";
}
pos = pos + possibleY;
if(pos !== 0){
scrollProp = voodoo.scrollbarCalc(e, "vertical", "verticalscroll.scrubber.2");
voodoo.viewScroll(e, "mousedrag", scrollDir, scrollProp[7]);
}
pos = 0;
}
}
return false;
});
getStage().getSymbol("Domtop").$("Domtopreduced").mouseup(function(e){
e.preventDefault();
e.stopPropagation();
var mouseButton = e.button;
if(mouseButton !== 2){
isDrag = false;
canDrag = false;
setVar("scrubber", "");
}
return false;
});
return false;
});
//Preview drag & drop
//drag source
sym.$("hotspotfocus").attr("draggable", "true");
Symbol.bindElementAction(compId, symbolName, "${hotspotfocus}", "dragstart", function(sym, e) {
if(getVar("hardpreview") == "off"){
return false;
}
setVar("dragDropItem", e.target.id);
setVar("isDrag", true);
});
//drag target
Symbol.bindElementAction(compId, symbolName, "${hpvslot1}", "dragover", function(sym, e) {
e.preventDefault();
e.stopPropagation();
if(getVar("hpvslot1") === ""){
sym.$("hpvslot1BG").fadeTo(0, 0.5);
}
else{
sym.$("hpvslot1BG").show();
}
return false; ///
});
Symbol.bindElementAction(compId, symbolName, "${hpvslot1}", "drop", function(sym, e) {
e.preventDefault();
e.stopPropagation();
sym.$("hpvslot1BG").fadeTo(0, 1);
voodoo.hpvDrop("hpvslot1");
return false; ///
});
Symbol.bindElementAction(compId, symbolName, "${hpvslot1}", "dragleave", function(sym, e) {
e.stopPropagation();
e.preventDefault();
if(getVar("hpvslot1") !== ""){
sym.$("hpvslot1BG").hide();
}
else{
sym.$("hpvslot1BG").fadeTo(0, 1);
}
});
Symbol.bindElementAction(compId, symbolName, "${hpvslot1}", "dragend", function(sym, e) {
e.preventDefault();
sym.$("hpvslot1BG").hide();
});
Stumbled on the answer by accident.
It turns out that once the scrollbar's mousemove is activated by the scrubber (ie the first time you scroll by dragging) the scrollbar's mousemove function remains activated and scrolling anywhere in the view triggers mousemove.
This unintentional triggering is defeating the correct cursor response in the html5 drag&drop.
By stopping propagation at a lower level this is prevented (the event is being triggered in the scrollbar even though the mouse button is not "down" on the scrubber).
Unexpected!
In essence the issue here is that even though the offending mousemove handler is nested in a situation where you wouldn't think it would be fired unless the enclosing mousedown is triggered, it is, after being triggered for the first time, always triggered, regardless of whether the mouse is down or not.
The answer is have only one mousemove handler connected to the element...
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");
}
}
Is there any way to handle tap from track pad of mac?
I need to handle 'tap' and 'click' on track-pad, especially on mac.
I tried
$.event.special.tap = {
setup: function(data, namespaces) {
var $elem = $(this);
$elem.bind('touchstart', $.event.special.tap.handler)
.bind('touchmove', $.event.special.tap.handler)
.bind('touchend', $.event.special.tap.handler);
},
teardown: function(namespaces) {
var $elem = $(this);
$elem.unbind('touchstart', $.event.special.tap.handler)
.unbind('touchmove', $.event.special.tap.handler)
.unbind('touchend', $.event.special.tap.handler);
},
handler: function(event) {
event.preventDefault();
var $elem = $(this);
$elem.data(event.type, 1);
if (event.type === 'touchend' && !$elem.data('touchmove')) {
event.type = 'tap';
$.event.handle.apply(this, arguments);
} else if ($elem.data('touchend')) {
$elem.removeData('touchstart touchmove touchend');
}
}
};
$('.thumb img').bind('tap', function() {
//bind tap event to an img tag with the class thumb
}
Which didn't work.
How to capture tap event on the track-pad?
I'm having this same concern. It appears that the trackpad on the MacBook (for example) doesn't fire TouchEvents like an actual touch device would. It is instead converting gestures into MouseEvents.
document.addEventListener('mousewheel', function(e) {
console.log(e.wheelDelta);
});
document.addEventListener('touchstart', function(e) {
console.log(e);
});
In the above example, when I attempt to capture the "pinch/zoom" gesture on a trackpad, I'm actually getting back Delta from a scroll wheel as if I'd held down CTRL and then scrolled up or down, returning a wheelDelta value of 120 or -120. Putting event listeners on for 'touchstart' doesn't not write to the console as I prescribe unless it's on a touch device like a tablet or smart phone.
Obviously, the MackBook can detect when you've touched the trackpad since it's able to then detect your movement, but it does not appear to be available through the document.
Middle button of mouse is paste the value into the input field. I want to override this functionality. It's possible?
I use the following code, but it doesn't prevent the default pasting:
$('input').on('mouseup',function(e){
//middle button is clicked
if (e.which == 2)
{
e.preventDefault();
$(this).val('another value');
}
})
All you need to do is cancel the mousedown event instead of the mouseup.
Here's a live demo : http://jsfiddle.net/77En2/2/
Have things changed - now it's the other way around. Preventing on mousedown or pointerdown does not stop it.
2021 solution:
input.addEventListener('pointerup', (e) => {
if (e.button === 1) {
e.preventDefault();
}
});
or
input.addEventListener('mouseup', (e) => {
if (e.button === 1) {
e.preventDefault();
}
});
This is a change for the better since paste occurs after MMB is released.
By the way, only Linux implements this behavior.
I'm developing a select menu replacement in jquery.
First I've to make the new select menu focusable by just adding tabindex="0" to the container.
Then, I disable focus on the original select menu and give focus to the new one.
When the new one is focused and you press the up and down arrows the options change accordingly but there's a big problem. As you press the arrows the body moves too.
I tried all these solutions so far with no luck:
$(window).unbind('scroll');
$(document).unbind('scroll');
$('body').unbind('scroll');
$(window).unbind('keydown');
$(document).unbind('keydown');
Check the code here http://pastebin.com/pVNMqyui
This code is from the development version of Ideal Forms http://code.google.com/p/idealforms that I'm about to release soon, with keyboard support.
Any ideas why this is not working?
EDIT: Solved!
Found the answer on this post jquery link tag enable disable
var disableScroll = function(e){
if (e.keyCode === 40 || e.keyCode === 38) {
e.preventDefault();
return false;
}
};
// And then...
events.focus: function(){ $(window).on('keydown', disableScroll); }
events.blur: function(){ $(window).off('keydown', disableScroll); }
It works!
In your keydown handler, for up and down keys, return false like this:
'keydown' : function (e) {
if (e.keyCode === 40) { // Down arrow
that.events.moveOne('down');
}
if (e.keyCode === 38) { // Up arrow
that.events.moveOne('up');
}
return false;
}
Also, make sure this return gets propagated to the browser's native onkeydown depending on how/which framework you're using.
Found the answer on this post jquery link tag enable disable
var disableScroll = function(e){
if (e.keyCode === 40 || e.keyCode === 38) {
e.preventDefault();
return false;
}
};
// And then...
events.focus: function(){ $(window).on('keydown', disableScroll); }
events.blur: function(){ $(window).off('keydown', disableScroll); }
You need to cancel the keydown event for arrow keys. Use either e.preventDefault() or return false in your .keydown() handler if an arrow key has been pressed.
Its very simple.you need not even need jQuery for this.
jQuery:
$("body").css("overflow", "hidden");
javascript
<body style="overflow: hidden">
Adding in style:
<style>
body {width:100%; height:100%; overflow:hidden, margin:0}
html {width:100%; height:100%; overflow:hidden}
</style>
if you want to bind the arrow keys,try something like:
$('body').keydown(function(e){
e.preventDefult();
if(e.keyCode == 37) // for left key
{
// implement focus functionality
}
if(e.keyCode == 38) // for up key
{
// implement focus functionality
}
if(e.keyCode == 39) // for right key
{
// implement focus functionality
}
if(e.keyCode == 40) // for doqn key
{
// implement focus functionality
}
});
The Best way to achive the same is to set overflow of the body to hidden
$("body").css("overflow", "hidden");
After the process just do the opposite
`$("body").css("overflow", "hidden");