问题
I have a slider that I built that changes the width of it to slide the element into view. On a desktop there are buttons to do this. I want to be able to make the slider work with a touch and drag event and for it to be smooth like iosslider. I have found a way that works but it is choppy and does not always respond.
My code...
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script>
<script type="text/javascript">$(document).bind("mobileinit", function(){$.extend($.mobile , {autoInitializePage: false})});</script>
<script src="scripts/jquery.mobile-1.3.2.min.js"></script>
<script>
function clickNDrag(){
var mousePosition = event.pageX;
$(this).bind('vmousemove',function(){
var mouseCurrentPosition = event.pageX;
var positionNumber = mouseCurrentPosition - mousePosition;
if(positionNumber > 0){
var widthAppend = 20;
} else {
var widthAppend = -20;
}
$(this).css({width: '+=' + widthAppend});
});
$(this).vmouseup(function(){
$(this).unbind('mousemove');
});
$(this).vmouseleave(function(){
$(this).unbind('mousemove');
});
}
$(document).ready(function(){
$('.slider').bind('vmousedown',clickNDrag);
});
</script>
What I have done is I loaded jQuery Mobile and only loaded the touch events of it.
The script checks to see where the virtual mouse is and then when it moves checks to see if it moved right or left and then adds 20px or subtracts 20px from the slider.
How would I do this in a more natural feeling and smooth way?
回答1:
What I had before was just not working so I started with a script that detected the x position of the mouse and change the width accordingly.
var oldXPos = 0;
var isDragging = false;
$(document).mousemove(function(event) {
if (isDragging)
{
var difference = event.pageX - oldXPos;
$('#changeMe').css({width: '+='+ difference});
}
oldXPos = event.pageX;
$('#changeMe').mousedown(function(){isDragging = true;})
$('#changeMe').mouseup(function(){isDragging = false;})
});
But I also wanted to have it work on a touch device. So I bond the events to touchmove, touchstart and touchend. I also had to change the listener for the mouse position.
oldXPos = event.originalEvent.targetTouches[0].pageX;
This allow me to get the current position of the touch event. This worked ok but you had to tap and the tap and drag to get it to work. So I bond an event listener to the element itself, after the dom was ready. So that every time there was a touchstart event it would find the position of that event.
$(document).ready(function(){
$('#changeMe').bind('touchstart', function(event){
oldXPos = event.originalEvent.targetTouches[0].pageX;
});
});
This worked perfectly except that you had to keep your finger on a straight line or else the screen would "scroll". So I had to prevent the touchmove defaults when you were in the element and the "re-enable" default when you stopped.
$(document).ready(function(){
$('#changeMe').bind('touchstart', function(event){
oldXPos = event.originalEvent.targetTouches[0].pageX;
$('body').bind('touchmove', function(e){e.preventDefault()});
});
});
The final code...
<style>
.outer{width:500px; height:200px; overflow:hidden; }
#changeMe {width:1000px; height: 200px;}
</style>
<div class="outer">
<div id="changeMe">
Some Content
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script>
<script>
$(document).bind('touchmove' ,function(event) {
if (isDragging)
{
var difference = event.originalEvent.targetTouches[0].pageX - oldXPos;
$('#changeMe').css({width: '+='+ difference});
}
oldXPos = event.originalEvent.targetTouches[0].pageX;
$('#changeMe').bind('touchstart', function(){isDragging = true;})
$('#changeMe').bind('touchend', function(){isDragging = false;})
});
$(document).ready(function(){
$('#changeMe').bind('touchstart', function(event){
oldXPos = event.originalEvent.targetTouches[0].pageX;
$('body').bind('touchmove', function(e){e.preventDefault()});
});
});
</script>
来源:https://stackoverflow.com/questions/18283649/how-do-i-make-the-width-of-and-element-change-when-a-touch-and-drag-is-detected