stop a previous function from continuing to be excuted with jquery - javascript

I have the following function to create a slider. It works (almost perfectly)... The problem I'm having now is that once you click down on the slider it moves around like it should, but I can't figure out how to stop it from moving when I release the mouse?
Suggestions?
Thanks!
var moveSlider = function(){
//sets the current position and offset variables
var currentPosition;
var offset;
//looks for the mousedown event on the slider
$("#slider").mousedown(function(e){
//sets the offset = to the mouse coordinate of the page - the offset of the slider
offset = e.pageX - this.offsetLeft;
console.log("offset: " + offset);
//tracks the mosemovement in the document
$(document).mousemove(function(e){
currentPosition = e.pageX - offset;
//takes the mouse current position (minues the offset) and sets an absolute position
$('#slider').css('left', currentPosition + "px");
console.log("CURRENT POSITION: " + currentPosition);
//checks to make sure it's within the box
if(currentPosition <= 0){
$('#slider').css('left', 0 + "px");
}else if(currentPosition >= 400){
$('#slider').css('left', 400-20 + "px");
}
});
});
$("#slider").mouseup(function(){
$('#slider').css('left', currentPosition + "px")
console.log("Fixed");
});
};
EDIT:
MVCHR, I went off your example, and came up with the following. The mouse move still works, but when you release the mouse it keeps moving. Im sure I"m missing something stupid
Edit, again: Silly mistake, I still had the mouse move in there. Took it out and it works perfectly now! Thanks :)
Thanks again
var moveSlider = function(){
//sets the current position and offset variables
var currentPosition;
var offset;
var rightOffset
//looks for the mousedown event on the slider
$("#slider").mousedown(function(e){
//sets the offset = to the mouse coordinate of the page - the offset of the slider
offset = e.pageX - this.offsetLeft;
console.log("offset: " + offset);
$(document).bind('mousemove', mmHandler);
});
var mmHandler = function (e) {
//tracks the mosemovement in the document
$(document).mousemove(function(e){
currentPosition = e.pageX - offset;
//takes the mouse current position (minues the offset) and sets an absolute position
$('#slider').css('left', currentPosition + "px");
console.log("CURRENT POSITION: " + currentPosition);
//checks to make sure it's within the box
if(currentPosition <= 0){
$('#slider').css('left', 0 + "px");
}else if(currentPosition >= 400){
$('#slider').css('left', 400-20 + "px");
}
});
};
$(document).mouseup(function(e) {
// some code then
$(document).unbind('mousemove', mmHandler);
});
};

In your mouse up event handler add in:
$(document).unbind('mousemove');
You should probably put the function for handling the bound mouse move into something you can pass to the unbind because the code above will affect all mousemove handlers on the document that may be set.
unbind api docs

In case you have other functions bound to mousemove that you don't want to remove, move your mousemove function to a named function that you bind on mousedown and unbind on mouseup. Note that you'll also want to put the mouseup on document and not #slider assuming your slider doesn't move vertically.
Something like this:
var mmHandler = function (e) {
// mousemove code here
};
$("#slider").mousedown(function(e) {
// some code then
$(document).bind('mousemove', mmHandler);
});
$(document).mouseup(function(e) {
// some code then
$(document).unbind('mousemove', mmHandler);
});

Related

Mousemove issue [jQuery]

I've just created #element and #box which detect if it's out of the viewport. If so, it should go above the cursor but here's my issue. When #box is out of the viewport it starts acting weird by flashing over and over. Hope you guys can help me. Cheers.
var box = $("#box");
var element = $("#element");
var PAGEX;
var PAGEY;
var elementTop;
var elementBottom;
var windowHeight;
element.bind({
mousemove: function (e) {
box.show();
PAGEX = e.pageX;
PAGEY = e.pageY;
elementTop = box.offset().top;
elementBottom = elementTop + box.outerHeight();
windowHeight = $(window).height();
if(elementBottom > windowHeight)
{
box.css({
top: PAGEY - 65,
left: PAGEX + 15
})
}
else
{
box.css({
top: PAGEY + 15,
left: PAGEX + 15
})
}
},
mouseleave: function () {
box.hide();
}
})
JSFiddle
The problem here is that you are doing your out-of-viewport check against the actual box location, rather than the location based on the mousemove. So, this works the first time the box would move out of the viewport - you adjust it back inside. But, the next time the mouse moves, your box is safely inside the viewport. So your check adjusts it based on the mouse position, and it gets put outside the viewport. The next time the mouse moves, the calculation works, and it gets adjusted back inside, and so on.
The fix is to change this:
if(elementBottom > windowHeight)
To this:
if(PAGEY + 15 + box.outerHeight() > windowHeight)
So that it is always calculating the out-of-viewport based on where the target location would be, and not where its current location is.

Applying transform with JavaScript on mousemove doesn't update on the fly

trying to make a div draggable, but only along the x-axis, the way a timestamp thumb on a video control can be dragged left and right to seek through a video or audio presentation.
Here's my code
thumb.addEventListener('mousemove', updateThumbPosition, false)
function updateThumbPosition (event) {
var thumbRect = thumb.getBoundingClientRect()
var startX = seekbar.getBoundingClientRect().left
var mouseX = event.clientX
console.log(mouseX - startX + thumbRect.width / 2)
thumb.style.transform = 'translateX(' + mouseX - startX + thumbRect.width / 2 + 'px)'
}
The div doesn't move. The values change rapidly as the mouse moves. I can see that when I log to the console, but the div itself does not translate along the X axis. Thoughts?
Here's a jsfiddle: https://jsfiddle.net/btjLqa8u/1/
You're only missing parentheses: https://jsfiddle.net/rjzLtunb/
div.style.transform = 'translateX(' + (mouseX - startX) + 'px)'
By the way, for drag and drop code, you probably want to listen for mouse moves on the div parent instead of the div itself.
I updated you fiddle with better mouse handling.
jsfiddle
s4mj3ch9
var div = document.getElementById('div')
div.addEventListener('mousedown', mouseDown, false);
window.addEventListener('mouseup', mouseUp, false);
function updateDivPosition (event) {
var divRect = div.getBoundingClientRect()
var startX = seekbar.getBoundingClientRect().left
var mouseX = event.clientX
div.style.transform = 'translateX(' + (mouseX - startX) + 'px)'
}
function mouseUp(){
window.removeEventListener('mousemove', updateDivPosition, true);
}
function mouseDown(){
window.addEventListener('mousemove', updateDivPosition, true);
}

moving a div according to mouse position

I am trying to create and effect where you have a vertical list, and when you hover it with your mouse, a separate "cursor" div should travel up and down vertically along this list, horizontally aligned with your pointer.
I am using this code:
$(document).mousemove( function(e) {
mouseY = e.pageY;
mouseX = e.pageX;
translateY = 'translateY(' + mouseY + 'px)';
translateX = 'translateX(' + mouseX + 'px)';
});
Then with jQuery:
$(".sidebarnav").mouseover(function(){
$('.sidebarnav .cursor').css({'transform': translateY});
});
All this kind of work, but the cursor div does not perfectly align with my mouse pointer. It does if you move real slow and with precision, but it doesn't if you move a bit faster. Is there any technical reason to this lack of precision, or is my code just wrong?
Here is a jsfiddle
http://jsfiddle.net/txks3wtj/
A fiddle would definitely help. But if I understand your code correctly I believe you can't just update the .cursor's position on mouseover of the .sidebarnav - instead you need to update its position on mousemove ie all the time.
Since you don't want the cursor to move when not hovering the sidebar you'd need to keep track of whether or not it is hovered. Something like:
var isOver = false;
$('.sidebarnav').mouseover(function () {
isOver = true;
}).mouseout(function () {
isOver = false;
});
$(document).mousemove( function(e) {
mouseY = e.pageY;
mouseX = e.pageX;
translateY = 'translateY(' + mouseY + 'px)';
translateX = 'translateX(' + mouseX + 'px)';
if (isOver) {
$('.sidebarnav .cursor').css({'transform': translateY});
}
});
Untested.
Edit: It would increase performance if you cached your queries as well;
var sidebar = $('.sidebarnav');
var cursor = sidebar.find('.cursor');
Edit2: You may have better results with mouseenter and mouseleave too I think. I think over/out triggers as soon as you hover a child of the element as well.

Make a div follow the mouse just when the mouse is on mousedown

I'm trying to make a jquery function to follow the mouse coursor with a div, when it is on mousedown and when it is on mouseup it stay in the last position it was.
any sugestion.
Why not simply use drag and drop by jquery:
<script>
$(function() {
$( "#draggable" ).draggable();
});
</script>
Jquery draggable
I've put together a simple working example that defines a Draggable object. You specify the drag item (the element that you're moving around), as well as a drag boundary (the space—or element—that you are moving the item inside of). The concept of a boundary is important if you ever want to restrict a draggable item to a certain space on the page (such as a container), or define a relative coordinate system on which to base your math.
My solution isn't the fastest, but it demonstrates the concept:
$(function() {
window.mousedown = 0;
$(window).on('mousedown mouseup', function(e) {
if(e.type == 'mousedown') { this.mousedown++; }
else { this.mousedown--; }
});
var Draggable = function(dragItem, dragBoundary) {
this.item = $(dragItem).css('position', 'absolute');
this.item.on('mousemove', $.proxy(this.handleDragEvent, this));
this.boundary = $(dragBoundary).css('position', 'relative');
};
Draggable.prototype.handleDragEvent = function(e) {
if(window.mousedown) {
var mousePosition = this.mapToBoundary([e.clientX, e.clientY]);
var mouseX = mousePosition[0],
mouseY = mousePosition[1];
if(typeof this.prevMouseX == "undefined") this.prevMouseX = mouseX;
if(typeof this.prevMouseY == "undefined") this.prevMouseY = mouseY;
this.itemX = this.item.offset().left - this.boundary.offset().left;
this.itemY = this.item.offset().top - this.boundary.offset().top;
var deltaX = mouseX - this.prevMouseX,
deltaY = mouseY - this.prevMouseY;
this.item.css({
'left': this.itemX + deltaX,
'top': this.itemY + deltaY
});
this.prevMouseX = mouseX;
this.prevMouseY = mouseY;
}
};
Draggable.prototype.mapToBoundary = function(coord) {
var x = coord[0] - this.boundary.offset().left;
var y = coord[1] - this.boundary.offset().top;
return [x,y];
};
var draggable = new Draggable($('.draggable'), $('.container'));
});
Notice that we are maintaining a mousedown value on global, allowing us to determine when it would be appropriate to drag around our element (we only add a mousemove listener to the drag item itself). I've also included a spacer div above the boundary div to demonstrate how you can move the boundary anywhere around the page and the coordinate system is still accurate. The code to actually restrict a draggable item within its assigned boundary could be written using simple math.
Here is the fiddle: http://jsfiddle.net/bTh9s/3/
EDIT:
Here is the start to some code for restricting a Draggable item within its container.
Draggable.prototype.restrictItemToBoundary = function() {
var position = this.item.position();
position.right = position.left + this.item.outerWidth();
position.bottom = position.top + this.item.outerHeight();
if(position.left <= 0) {
this.item.css('left', 1);
} else if(position.right >= this.boundary.outerWidth()) {
this.item.css('left', this.boundary.outerWidth() - this.item.outerWidth());
}
if(position.top <= 0) {
this.item.css('top', 1);
} else if(position.bottom >= this.boundary.outerHeight()) {
this.item.css('top', this.boundary.outerHeight() - this.item.outerHeight());
}
};
This method should be called inside of Draggable.handleDragEvent just after you update the CSS positioning of the drag item. It seems this solution is glitchy, but it's a start.

how to get mouse coordinate after transform

How do I get the x and y pixel value of the mouse click on the image after a canvas translate & scale? What's the needed calculation from the event x and y?
I am using panning & zooming code from this answer:
var zoom = function(clicks) {
var pt = ctx.transformedPoint(lastX,lastY);
ctx.translate(pt.x,pt.y);
var factor = Math.pow(scaleFactor,clicks);
ctx.scale(factor,factor);
ctx.translate(-pt.x,-pt.y);
redraw();
}
var handleScroll = function(evt) {
var delta = evt.wheelDelta ? evt.wheelDelta/40 : evt.detail ? -evt.detail : 0;
if (delta) zoom(delta);
return evt.preventDefault() && false;
};
Example website
If you're just trying to get the mouse X and Y position after a click, then you should attach a function to the mousedown event in Javascript. This is called event binding. In short, while in the DOM you can bind events to elements within the page. Here's an example I made which shows an event bound to the #box element.
document.getElementById("box").onmousedown = function() {
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
alert("Mouse x: " + posx + "\nMouse y: " + posy);
};​
This code finds an element with an ID of box and tells the code in the function to run every time after the mouse is depressed. In this example we also fall back for older system to ensure that it works cross-platform and cross-browser. If you wanted to bind this event to the whole webpage rather than just an element then you can replace document.getElementById("box") with window.
This however does not compute the relative position within a DOM element. There's multiple ways to do that which I won't go into detail on here, but I'll include a few methods below. Best of luck!
RESOURCES
More on handling mouseclicks in Javascript
Relative position of mouse clicks within an element
jQuery solution for the previous link

Categories

Resources