How can I "mouse swipe" with plain Javascript?
I'm new to Javascript and I'm trying to "master" it somehow and in order for me to do so I don't want to use any library [like jQuery] yet.
That being said, I have found several ways to implement a "mouse swipe" with just Javascript like: Simulate swipe with mouse in javascript. But the answers are always very shallow in the posts that I have found.
Even tho, all of the solutions point to: mousedown -> mousemove -> mouseup events. Which is what I'm doing.
I set up an exercise for my self to "master" the bases of Javascript: I would have to create a flat and cross-browser-compatible interface that would allow me to save notes (in local storage) using only Javascript, css3 and html5 (the hard part is the cross browser compatibility).
So I thought of a simple table with 2 columns: to save the title of the note (first column) and the note (second column). i.e.
What matters is the table at the end. I want to be able to "mouse-swipe" the rows of the table.
This is what I have come up to (I'm not going to put all the code, just the basics of what I got):
First: the table is a set of classes through CSS;
/*CSS*/
div.table {
display: table;
}
div.table .row{
display: table-row;
}
div.table .row .col, div.table .row .col-2{
display: table-cell;
}
Second: the html;
<div id="savedNotesTable" class="table">
<div class="row">
<div class="col">Testing</div>
<div class="col-2">This is a test</div>
</div>
<div class="row">
<div class="col">Testing</div>
<div class="col-2">This is a test</div>
</div>
<div class="row">
<div class="col">Testing</div>
<div class="col-2">This is a test</div>
</div>
</div>
Last but not least: the Javascript
function addEvent(element, type, fn){
// custom add event function that cares about compatibility
// returns fn
}
function removeEvent(element, type, fn){ /*custom remove event function that cares about compatibility and removes only the specific handler*/ }
function addSwipe(element, parent){
addEvent(element, "mousedown", function(e){
var mouseupHandler = addEvent(document, "mouseup", mouseUpHandler);
var mousemoveHandler = addEvent(document, "mousemove", function(e){
// element.style.position = "static";
// parent.style.left = e.pageX + 'px';
// add transition and blur to the element
// mouseSwipe = absolute value of(originalPosition of mouse - e.pageX)
});
function mouseUpHandler(e){
// pseudocode:
// if mouseSwipe >= 50%(div size) = delete from the parent which is the "table"
// transition and blur OUT to 100% and delete
// if mouseSwipe < 50%(div size) = don't delete
// transition back to 0% and unblur.
removeEvent(document, "mousemove", mousemoveHandler);
removeEvent(document, "mouseup", mouseupHandler);
};
});
};
// this is just to add them to the test notes on the html
// The real thing is going to add the swipe when I save the new element
var table = document.getElementById("savedNotesTable");
var notes = table ? table.childNodes : undefined;
for(var prop in notes){
if(prop != "length" && notes.hasOwnProperty(prop)){
if(notes[prop].nodeName != "#text"){
addSwipe(notes[prop], table);
};
};
};
Am I doing it right? Or is there another way I'm not seeing? I was able to get somewhere messing with the position of the divs like position="absolute" inside the onmousedown event but that messed with the width and length of the table row.
I'm looking for best practices also.
Solution 1:
Just a remark about event handlers dynamic attribution
As long as your element is not destroyed, there is no need to remove the event handlers attached to it (unless you want to change the element's behaviour completely, but that's rather uncommon).
Adding and removing event handlers is relatively costly, and can lead to small memory leaks in some cases. It's usually simpler and safer to leave the handlers in place and modify them (slightly) to work in all cases.
I also think it makes the code more readable, by putting all the event binding in one place, and forcing the handlers to behave properly in all cases. But that's a matter of personal taste.
Here the problem is with mousemove, that will fire even when you're not dragging (i.e. when the mouse button is not depressed).
You can handle that like so (simplified code just to demonstrate the principle) :
function onMouseDown () {
dragging = true;
}
function onMouseMove () {
if (!dragging) return; // skip dragging action if mouse button not depressed
// do your dragging stuff
}
function onMouseUp () {
dragging = false;
// do your end of dragging stuff
}
// handlers bound to the element only once
addEvent (element, 'mousedown', onMouseDown);
addEvent (element, 'mousemove', onMouseMove);
addEvent (element, 'mouseup' , onMouseUp);