If mousedown then trigger mousemove else do nothing - javascript

I have a technical issue and I am not sure what the best way is to solve it.
Basically im working on an audio progress bar where the user can change the position of the song. This should be done by either clicking or by keeping the mousedown and moving it.
elem.addEventListener("mouseup", function(event){
elem.removeEventListener("mousemove", fn);
});
elem.addEventListener("mousedown", function(event){
elem.addEventListener("mousemove", function(event){
// Stuff to do
}, fn);
});
So essentially:
If mouse is held down and then moved do something. If mouse is released prevent the trigger of mousemove.
I know if I continue with this it might work but it looks like a horrible mess to me. I dont want to pick up bad habits.
My question is: How do I make make this work using best practices?
Note: I also tried the following:
function fn(event) {
if(event.button == 0) {
elem.addEventListener("mousemove", function(event){
// Stuff to do
});
}
}
What i'm missing here !

Don't add/remove the listener, just set a variable at trigger actions accordingly:
var isMousedown = false;
elem.addEventListener("mousedown", function (event) {
isMousedown = true;
}
elem.addEventListener("mouseup", function (event) {
isMousedown = false;
});
elem.addEventListener("mousemove", function (event) {
if (isMousedown) {
// do stuff
} else {
// do different stuff, or nothing
}
});
You may even want to put the mousedown/mouseup listeners on the parent (or even the root element) to avoid scenarios where the mouseup happens outside of the target, if that is a possibility in your case.

Related

HTML5 DragNDrop - Drop event never fires

I'm trying to implement a drag'n'drop upload input for a web app. Detecting drag start and end and appropriate drop target styling works flawlessly, though as soon as I drop an image file on the target, it opens in the browser. I know this has been asked pretty often on Stack Overflow, but I couldn't find a solution anywhere yet.
What I do see is: Listeners for dragenter, dragstart and dragend fire correctly, while drop does not. Please see the code below:
(Note: The app object is just a simple, custom abstraction object, nothing special about it. The app.on method calls addEventListener and attaches the event wrapped in a try-catch block.)
Attaching the events
app.on('drag dragover dragstart', app.elements.pictureDropArea, app.events.startedDragging, true);
app.on('dragenter', app.elements.pictureDropArea, app.events.isDragging);
app.on('dragleave dragend', app.elements.pictureDropArea, app.events.stoppedDragging);
app.on('drop', app.elements.pictureDropArea, app.events.isDropped);
The individual events
app.events.startedDragging = function(event) {
event.preventDefault();
event.stopPropagation();
return false;
};
app.events.isDragging = function(event) {
event.preventDefault();
event.stopPropagation();
app.elements.pictureDropArea.classList.add('dragged-over');
return false;
};
app.events.stoppedDragging = function(event) {
event.preventDefault();
event.stopPropagation();
app.elements.pictureDropArea.classList.remove('dragged-over');
return false;
};
app.events.isDropped = function(event) {
event.preventDefault();
event.stopPropagation();
console.log('drop event fired.');
var file = event.dataTransfer.files[ 0 ];
console.log(file);
return false;
};
Found it accidentally when I applied the same events to the body. It seems like there needs to a listener for dragover on the document body with the usual preventDefault and stopPropagation stuff:
app.on('dragover', document.body, function(event) {
event.preventDefault();
event.stopPropagation();
return false;
});
God, I hate this API so much...

how do I call the mousedown event in javascript as long as mouse is held down

I am implementing a joystick control where I want to call the mousedown function after every 100msec as long as mouse click is held on by the user. How can I trigger this?
var hammer = Hammer(document.getElementById('joystick'));
hammer.on("mousemove", onMouseMove);
hammer.on("mousedown", onMouseDown);
the above code only calls mousedown once initially. To trigger it again I have to release mouse button and click again.
Something like this in jQuery (ripped from code I already had)
var longClickTimer;
$('#thing_to_click').on('mousedown', function(e) {
var $$ = $(this);
longClickTimer = setInterval(function(){
$$.trigger('click');
}, 350);
});
$('#thing_to_click').on('mouseup', function(e) {
clearInterval(longClickTimer);
});
$('#thing_to_click').on('click', function(e) {
e.preventDefault();
// do something
});
in my case the animation takes 350ms to move, so I trigger it every 350ms, you might need something different.
This isn't the 'best' code as you might get duplication of clicks, so your //do something might need to handle that.

Prevent keydown() from being captured by document binding

I'm not exactly sure how to phrase this, so I couldn't search it. Basically, I have a keydown() bind on $(document). I'd like to show() another div, and have all keydown events be rerouted to this div and prevented from firing off in the document handler. Is this even possible, or would I have to put all my main keybindings on another div and work from there?
e.stopPropagation, or
e.preventDefault (depending on the situation)
Where e is the event.
Ex:
function onKeyDown(e) {
doStuff();
e.preventDefault();
}
e.preventDefault() will prevent the default behaviour of an event. What you need is to use
e.stopPropagation(), so that the event does not bubble up the DOM structure.
$(element).keydown(function(e) {
// do the task
// allow the default behaviour also
e.stopPropagation();
//^. BUT stop the even bubbling up right here
});
e.stopProgation(), can be bit confusing to grasp on the first but I created a demo with click event to explain it.
Hope it helps!!
Try:
​$(document).on('keydown', function (evt) {
$('#foo').show().trigger(evt);
});​​​​​
$('#foo').on('keydown', function (evt) {
console.log(evt);
return false; // this is very important. Without it, you'll get an endless loop.
});
​
demo: http://jsfiddle.net/Z7vYK/
The only way I can think of to even have a keydown event run on something other than an input or document, is to manually trigger it. You could have a global variable keep track of whether or not your div is showing, then trigger the event on your div accordingly.
Here's one such solution
HTML
Show div
<div id="hiddendiv"></div>​
Javascript
var showing = false;
function showdiv()
{
showing = true;
$('#hiddendiv').show(200);
}
// Set up events on page ready
$(function() {
$(document).keydown(function(e) {
// If the div is showing, trigger it's keydown
// event and return
if(showing)
{
$('#hiddendiv').data('keydown_event', e).keydown();
return true;
}
alert('Document keydown! Keycode: ' + e.keyCode);
// Otherwise do the normal keydown stuff...
});
// Keydown for the hidden div
$('#hiddendiv').keydown(function() {
e = $(this).data('keydown_event');
alert('Hiddendiv keydown! Keycode: ' + e.keyCode);
// Make sure to stop propagation, or the events
// will loop for ever
e.stopPropagation();
return false;
});
});
​
As you can see, the #hiddendiv keydown event is being triggered by the document keydown event. I've also included a slight hack to get the event object to the hidden div using the jQuery data function.
Here's a demonstration of the code: http://jsfiddle.net/Codemonkey/DZecX/1/

How to simulate onclickout event with JavaScript

I'd like to somehow be able to define with JavaScript an onclickout event. That is something that happens when the user clicks anywhere else that the element in question.
I tried with onblur but it just don't seem to work :/
Is there any other way?
This uses the jQuery help, but the logic is the same if you prefer without it.
$(document).mouseup(function(event) {
var condition = $(event.target).parents(/* element_in_question */).length;
if (condition == 0) { // 0 means the event is not originated from the element in question
// Do what you need to do
}
}
});
document.getElementById('click').onclick = function(event) {
event.stopPropagation();
}
document.onclick = function() {
alert('click somewhere else');
}
jsFiddle.
This will send a click anywhere (except on #click) to the document.onclick handler, which will fire the alert().
You can set a variable, clickedin, on an element's click handler, and then have a click handler for the document that is checking if clickedin is true, and if it is, handle appropriately.
There may be a better way to accomplish the same end, though.

Handling clicks outside an element without jquery

I would like to implement the solution like this
How do I detect a click outside an element?
but I'm using another javascript library with $() function already defined
Any suggestions?
This is easy to accomplish. Would be a shame to load the jQuery library just for one feature.
If the other library you're using handles event binding, you could do the same thing in that library. Since you didn't indicate what that other library is, here's a native solution:
Example: http://jsfiddle.net/patrick_dw/wWkJR/1/
window.onload = function() {
// For clicks inside the element
document.getElementById('myElement').onclick = function(e) {
// Make sure the event doesn't bubble from your element
if (e) { e.stopPropagation(); }
else { window.event.cancelBubble = true; }
// Place the code for this element here
alert('this was a click inside');
};
// For clicks elsewhere on the page
document.onclick = function() {
alert('this was a click outside');
};
};
If the $ conflict is your only hold-up, there are ways around that:
http://docs.jquery.com/Using_jQuery_with_Other_Libraries
I also add here the code that stops event bubbling up. Found on quircksmode.org
function doSomething(e) {
if (!e) var e = window.event
// handle event
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
}

Categories

Resources