How do you simulate a drag event (mousemove with a button clicked)? - javascript

I want to be able to trigger the event and have it show that there was actually a button that was down at the time the event was fired.
$('table').on('mousemove', function(e) {
var is_dragging = e.buttons.length > 0;
// is_dragging should === true;
});
$('table').trigger('mousemove'); // is_dragging will be false

Try this out. Creating a custom event and attaching buttons property to it.
$('table').on('mousemove', function(e) {
var is_dragging = e.buttons.length > 0;
// is_dragging should === true;
});
var e = $.Event( 'mousemove' );
e.buttons = ['<set any key you need>'];
$('table').trigger(e);

So based on what i think you are trying to accomplish. You want to have an event handler for onmousemove where you are checking to see if a button is down (doesn't matter which button is down) however you want to manually trigger the event and have the condition is_dragging result in true.
If the event is manually triggered using $('table').trigger('mousemove');the event will not have a buttons property however it will have a .isTrigger property which will == 3.
Try this:
https://jsfiddle.net/SeanWessell/L2z0su3j/
$('table').on('mousemove', function(e) {
var is_dragging = e.buttons > 0 || e.buttons == undefined && e.isTrigger == 3;
// is_dragging should === true;
$('p').html(is_dragging.toString())
});
$('#trigger').click(function(){
$('table').trigger('mousemove');
})

::UPDATE::
look into ondragstart
http://www.w3schools.com/jsref/event_ondragstart.asp
=======
*.buttons is for what button you have clicked. At the time of mousemove you have not clicked a button.
Meaning your e.buttons === 0
Documentation on MouseEvent.button:
http://www.w3schools.com/jsref/event_button.asp
You can verify this by throwing a debugger in your function and inspecting your e variable
JSFiddle:
http://jsfiddle.net/qf3u8m61/

Related

return a function if there was no click event

I have a function that fires only when we press the spacebar or the isJumping event is already happening
If we press any other key, nothing happens.
function onJump(e) {
if (e.code !== "Space" || isJumping) return
yVelocity = JUMP_SPEED
isJumping = true
}
The question is, can I add to this function so that, in addition to the space, the mouse click event also fires?
That is, if we press the spacebar or click on the mouse, then the function works
The mouse click event is not key code, so I'm a little confused on how to do it right
If the function is called when you press a key then that is because somewhere in the code you didn't show us you have some code which registers that function (or another function which calls the first) as an event handler that triggers when a key is pressed (e.g. keyup or keypress).
If you want to call it when something is clicked then you also need to register it as an event handler for that kind of event (e.g. click or mousedown).
MDN has a tutorial on event handling.
I assume onJump is attached to a keyboard event handler, presumably on document, something like this:
document.addEventListener("keydown", onJump);
If so, you can also attach it to click:
document.addEventListener("keydown", onJump);
document.addEventListener("click", onJump);
...and then modify the function so it checks which type of event it got and handles it accordingly:
function onJump(e) {
if (isJumping || (e.type === "keydown" && e.code !== "Space")) return;
yVelocity = JUMP_SPEED;
isJumping = true;
}
That will only check e.code if the event is the keydown event, not the click event. (Adjust the event name as necessary).
USE EVENT.TYPE
Use the event.type property when using a single handler for multiple events. In your case, you want the same function to handle keyboard and mouse events. View and run the code snippet below to see how it works.
window.addEventListener("keydown", onJump);
window.addEventListener("mousedown", onJump);
const JUMP_SPEED = 100;
let isJumping = false;
function onJump(e) {
if (e.type === "mousedown") {
// add event handler here
}
else if (e.type === "keydown" && e.code === "Space" && !isJumping) {
yVelocity = JUMP_SPEED
isJumping = true
}
console.log("event: " + e.type + ", isJumping: " + isJumping + ", keycode: " + e.code);
}
<h3>Click the mouse or press spacebar</h3>
<img src="https://cdn.icon-icons.com/icons2/567/PNG/512/packman_icon-icons.com_54382.png" style="height:100px;width:auto"/>
You can use a event listener, like this:
document.body.addEventListener('click', function(){
console.log('hi');
});
<body>
<p>This is supposed to be your elements. Click here!</p>
</body>
In your case, you can make it
document.addEventListener("keydown", onJump);
document.addEventListener("click", onJump);
You can change your function correspondingly, so that it works with the event listeners:
function onJump(e) {
if (isJumping || (e.type == "keydown" && e.code !== "space")) return;
yVelocity = JUMP_SPEED;
isJumping = true;
}

Radio input checked with keyboard shortcut doesn't trigger event change

I have added a keyboard shortcut to my script so that when I press ctrl + 1 the first "source" radio input is checked :
if (e.key == "1" && e.ctrlKey) {
document.getElementsByName("source")[0].checked = true;
}
So far everythin is good. I have added an event listener so that when the state of my radio input are changed, then several things happen. But this event listener isn't triggered when I press ctrl+1 even thought the state of the radio input is changed (I can see the color of the input changing). If click manually on the radio input then the event listener is working:
var radiosource = document.getElementsByName("source");
for (var i = 0; i < radiosource.length; i++) {
radiosource[i].addEventListener('change', function (e) {
var input_changed_id = e.target.id;
if (input_changed_id.includes("en")) {
document.getElementById("fr_target").checked = true;
current_target = "fr";
}
if (input_changed_id.includes("fr")) {
document.getElementById("en_target").checked = true;
current_target = "en";
}
translate();
});
}
Here is the full script (cf lines 119 and lines 49 and 322)
It won't trigger if you change the checked value manually but your event will trigger if you simulate the click on the radio button using .click().
So just update your keyboard shortcut script to this:
if (e.key == "1" && e.ctrlKey) {
document.getElementsByName("source")[0].click();
}

addEventListener on keyup javascript once

I want to run countup(); and random(); function after I hit enter on my keyboard. But I wanna make that it's only work for the first time.I mean when first time i hit enter, it will run that function. But if those function already run and I hit enter again, it'll never effect anything.
Here's my code :
addEventListener("keydown", function(e){
if (e.keyCode === 13) {
countup();
random();
}
});
Anyone can help me? Thanks.
Do something like this
// Create a named function as your event handler
var myFunction = function (e) {
if (e.keyCode === 13) {
// Do your stuff here
countup();
random();
// Remove event listener so that next time it is not triggered
removeEventListener("keydown", myFunction);
}
};
// Bind "keydown" event
addEventListener("keydown", myFunction);
Idea is user a global variable, set it after firing event.
var is_fired = false;
addEventListener("keydown", function(e){
if (e.keyCode === 13 && is_fired == false) {
countup();
random();
is_fired = true
}
});
You can make click event listener work only once after trigger it.you just need to add another argument to addEventListener() which is {once:true}and it will work as expected:
addEventListener("keydown", function(e){
if (e.keyCode === 13) {
countup();
random();
}
},{once: true});
Check my question it's similar to your case.
Also you can just use removeEventListener()method but you should defined your Anonymous function before as external function like myKeyPressed() and then inside if condition remove event Listener from your element:
element.removeEventListener("keydown", myKeyPressed);
var is_clicked = false;
addEventListener("keydown", function(e){
if (e.keyCode === 13 && !is_clicked) {
countup();
random();
is_clicked = true;
}
});
There is a removeEventListener function in javascript but it's tricky to implement that inside the function you are calling on addEventListener.
Try this, it worked in jsfiddle.
addEventListener("keydown", function(e){
if (e.keyCode === 13) {
alert("i did it");
this.removeEventListener('keydown',arguments.callee,false);
}
});
You can add a variable to check the status of your keydown.
The first time you use it, set it up to true. So you will only have this function triggered once.
var n = document.getElementById("txtInput"),
r = document.getElementById("result"),
loadFlag = true;
n.addEventListener("keyup", function(e) {
if (e.keyCode === 13 && loadFlag ) {
countup(r);
random(r);
loadFlag = false;
}
}, false);
To add keydown to an element in your HTML code.
element.addEventListener("keydown", event => {
//check if event is cancelable because not all event can be cancelled
if(event.cancelable)
{
//this prevent element from executing the default event when user click
event.preventDefault()
if(event.keycode === 13){ //write your statement here }
}
}
for more https://www.w3schools.com/jsref/event_preventdefault.asp

on down arrow KeyPress, click event is getting fired

on down arrow keypress , click event is getting fired, event.keycode is undefined
$(".dropdown:not(.li-search) a.dropdown-toggle", ".navbar-collapse").on("click", function(event) {
var target = $(this).attr("target");
if (event.keyCode !== '40'){
if (!$(".li-menu").is(":visible") && target === undefined) {
location.href=this.href;
} else {
window.open(this.href, '_blank');
}
}
});
in this code i am trying to open main menu in new tab , but external link is getting open on down arrow keypress
call preventDefault() function.
$(".dropdown:not(.li-search) a.dropdown-toggle", ".navbar-collapse").on("click", function(event) {
event.preventDefault();
var target = $(this).attr("target");
if(event.keyCode!=='40'){
if (!$(".li-menu").is(":visible") && target===undefined) {
location.href=this.href;
}
else {
window.open(this.href,'_blank');
}
}
});
See the keycode for the reference https://css-tricks.com/snippets/javascript/javascript-keycodes/
in order to configure your app for particular key event
Looking at the classes dropdown-toggle, navbar-collapse, I'm guessing that you are using Bootstrap library.
If that is the case, the behaviour you are seeing is reasonable. Let's break down the issues:
on down arrow keypress , click event is getting fired
Q: You have only bind the handler on click event so why are it is being triggered on keypress?
A: Because this is a feature of bootstrap dropdown. To have better accessibilty, bootstrap triggers click event on the keydown of up, down, esc and space keys.
event.keycode is undefined
Since it is a click event handler and not some keyboard event handler like keydown or keypress, event.keyCode should be undefined
Note: You are using a strict equality in the following condition
if (event.keyCode !== '40')
This will check both the type and value of the operands. Now, event.keyCode always return a Number while '40' is a string, hence the above condtion will yield false even if keyCode is 40. You should correct it to:
if (event.keyCode !== 40)
Now, if you want to stop the redirect on down key, you should check whether the event triggered is an original event or was triggered by some js logic. For this, you may choose jQuery's event.isTrigger or event.originalEvent
Here's a code snippet:
$(".dropdown:not(.li-search) a.dropdown-toggle", ".navbar-collapse").on("click", function(event) {
var target = $(this).attr("target");
// Check if NOT an triggered event
if (!event.isTrigger) {
if (!$(".li-menu").is(":visible") && target === undefined) {
location.href = this.href;
} else {
window.open(this.href, '_blank');
}
}
});
<a> tags will fire the click event when you press enter on them. However you will not have a keyCode on the event because it is not a Key* event. If you want to know the keyCode add a keyDown or keyUp handler as well. You could also handle both by doing something like the following:
$(".dropdown:not(.li-search) a.dropdown-toggle", ".navbar-collapse").on("click keydown", function(event) {
var target = $(this).attr("target");
if(event.type === 'keydown' && event.keyCode!=='40'){
if (!$(".li-menu").is(":visible") && target===undefined) {
location.href=this.href;
}
else {
window.open(this.href,'_blank');
}
}
});
You'll probably also want to add an event.preventDefault(); in there if you wish to prevent default browser behaviour from taking place.

Chrome (maybe Safari?) fires "blur" twice on input fields when browser loses focus

Here is an interesting jsfiddle.
In Firefox:
Run the fiddle
Click in text input
Click somewhere else. Should say "1 blurs".
Click in the text input again.
ALT-TAB to another window. Fiddle should now say "2 blurs".
In Chrome, at step 5, it says "3 blurs". Two separate "blur" events are fired when the whole browser loses focus. This is of interest because it means that it's not safe to assume, in a "blur" handler, that the element actually had focus just before the event was dispatched; that is, that the loss of focus — the transition from "being in focus" to "not being in focus" — is the reason for the event. When two "blur" events are generated, that condition is not satisfied during the handling of the second event, as the element is already not in focus.
So is this just a bug? Is there a way to tell that a "blur" event is bogus?
The reason it is firing twice is because of window.onblur. The window blurring triggers a blur event on all elements in that window as part of the way javascript's capturing/bubbling process. All you need to do is test the event target for being the window.
var blurCount = 0;
var isTargetWindow = false;
$(window).blur(function(e){
console.log(e.target);
isTargetWindow = true;
});
$(window).focus(function(){
isTargetWindow = false;
});
$('input').blur(function(e) {
if(!isTargetWindow){
$('div').text(++blurCount + ' blurs');
}
console.log(e.target);
});
​
http://jsfiddle.net/pDYsM/4/
This is confirmed Chrome bug. See the Chromium Issue Tracker
The workaround is in the accepted answer.
Skip 2nd blur:
var secondBlur = false;
this.onblur = function(){
if(secondBlur)return;
secondBlur = true;
//do whatever
}
this.onfocus = function(){
secondBlur = false;
//do whatever
}
This probably isn't what you want to hear, but the only way to do it seems to be to manually track whether the element is focused or not. For example (fiddle here):
var blurCount = 0;
document.getElementsByTagName('input')[0].onblur = function(e) {
if (!e) e = window.event;
console.log('blur', e);
if (!(e.target || e.srcElement)['data-focused']) return;
(e.target || e.srcElement)['data-focused'] = false;
document.getElementsByTagName('div')[0].innerHTML = (++blurCount + ' blurs');
};
document.getElementsByTagName('input')[0].onfocus = function(e) {
if (!e) e = window.event;
console.log('focus', e);
(e.target || e.srcElement)['data-focused'] = true;
};
Interestingly, I couldn't get this to work in jQuery (fiddle here) ... I really don't use jQuery much, maybe I'm doing something wrong here?
var blurCount = 0;
$('input').blur(function(e) {
console.log('blur', e);
if (!(e.target || e.srcElement)['data-focused']) return;
(e.target || e.srcElement)['data-focused'] = false;
$('div').innerHTML = (++blurCount + ' blurs');
});
$('input').focus(function(e) {
console.log('focus', e);
(e.target || e.srcElement)['data-focused'] = true;
});
You could also try comparing the event's target with document.activeElement. This example will ignore the alt+tab blur events, and the blur events resulting from clicking on Chrome's... chrome. This could be useful depending on the situation. If the user alt+tabs back into Chrome, it's as if the box never lost focus (fiddle).
var blurCount = 0;
document.getElementsByTagName('input')[0].onblur = function(e) {
if (!e) e = window.event;
console.log('blur', e, document.activeElement, (e.target || e.srcElement));
if ((e.target || e.srcElement) == document.activeElement) return;
document.getElementsByTagName('div')[0].innerHTML = (++blurCount + ' blurs');
};​
​
I'm on Chrome Version 30.0.1599.101 m on Windows 7 and this issue appears to have been fixed.
I am experiencing the same and the above posts make sense as to why. In my case I just wanted to know if at least one blur event had occurred. As a result I found that just returning from my blur function solved my issue and prevented the subsequent event from firing.
function handleEditGroup(id) {
var groupLabelObject = $('#' + id);
var originalText = groupLabelObject.text();
groupLabelObject.attr('contenteditable', true)
.focus().blur(function () {
$(this).removeAttr('contenteditable');
$(this).text($(this).text().substr(0, 60));
if ($(this).text() != originalText) {
alert("Change Found");
return; //<--- Added this Return.
}
});
}
Looks like an oddity of angularjs gives a simpler solution when using ng-blur; the $event object is only defined if you pass it in:
ng-blur="onBlur($event)"
so (if you aren't using ng-blur on the window) you can check for:
$scope.onBlur = function( $event ) {
if (event != undefined) {
//this is the blur on the element
}
}

Categories

Resources