I have a div on which I listen for swipe events using jQuery mobile.
I was wondering how I could get the div to follow and move with the finger from the time that the swipe starts until the time that the swipe ends?
Almost like draggable only while the swipe is happening.
Although I would prefer to not use jQuery UI.
How can I do this properly and in the best way possible?
My method of doing this was on mouse down, set the offset of the div to the x location of the mouse. But that fires every pixel and seem inefficient. Also it happens on mouse-down, not on swipe.
Here is my code that listens for the swipe, in this case swipe right:
$('#main').on('swiperight', '.dataCard', function(event){
event.preventDefault();
// what happens on swipe here
});
Now, how can I get .dataCard to follow the finger as it swipes until the finger is picked up?
Well, you can inspect the event in a breaking in a debugger. Also, you cannot change positions of a "relative" element, it will always be in document flow position (hence why I asked if you had made the element absolute).
Related
I'm trying for numerous days to solve the following issue.
I have a menu located on the top of the page which needed to be open using swipedown event (I'm using Hammer.js jQuery version).
Problem is, every time I try to interact using swipes I either scroll the page (swipeup) or pulling the page down same as described in the following question.
Here is what I've tried so far:
overflow: hidden; on the body element with an inner container with overflow: auto, swipe on top element still triggered document scroll.
Setting preventDefault on the document also disabled lower elements events in the DOM hierarchy and by that I had no swipe events working in the page.
Also tried using stopPropagation on the actual element when the event occurs, to prevent the bubbling up the chain for the event, the result cause the object to not respond to the events (swipes) and document scroll worked with no problems.
Any ideas how can I still keep page scroll but also when using common gestures, such as swipedown/swipeup, on specific elements that the element only will be affected?
Here is an example using JSFiddle, to better demonstrate the issue.
Would appreciate ideas/thoughts
I don't know if this will help, but I've always liked to use drag more than swipe. Using Hammer on my projects, swipes were a bit finicky. And from a UX standpoint, drag feels instantaneous vs a swipe. Much like, mousedown vs mouseup/click. So in instances where it's appropriate, and I believe in the case of showing swipey menu it is, I'd opt for drag.
Replacing your example with drag rather than swipe, and also using CSS transition, -webkit-transition, rather than jQuery's animate (drag will trigger like a mousemove, vs a click or a mouseup) seemed to make it work.
Hammer('.nav').on('dragdown', function(e){
e.gesture.preventDefault()
$(".blue").html("down")
$('.nav').css({"top":"0px"});
})
.on('dragup', function(e){
e.gesture.preventDefault()
$(".blue").html("dragup")
$('.nav').css({"top":"-150px"});
});
//Added in CSS, for .nav
.nav {-webkit-transition:0.5s top;}
Example
This does still have the page overscroll. A preventDefault() on document.ontouchstart would could fix that but that breaks scrolling. You might be able to do a selective preventDefault() by checking the scrollOffset perhaps. But I guess in the long run, I'd recommend something like iScroll.
Example
Also maybe tweak the hitbox for the drag to be a bit larger. Which I did in the last example. I attached the dragdown event on the document instead of the "menu" so the menu doesn't have to be visibly bigger.
Hammer(document).on("dragdown",function(e){
//calculate ratio of first touch from top
var pos=e.gesture.startEvent.center.pageY/window.innerHeight
if(pos<0.2){ //drag occurs in the first 20% of the screen
menu.style.marginTop="0px" //or animate here
e.gesture.preventDefault()
e.gesture.stopPropagation();
}
})
You should use the preventDefault function of the orginal gesture, to stop the browsers default behaviour, see here: https://github.com/EightMedia/hammer.js/wiki/Event-delegation-and-how-to-stopPropagation---preventDefaults
When you have a div element, on which you want to register swipe events, you would do the following:
$('#swipeDiv').hammer().on("swipe", function(ev) { ev.gesture.preventDefault(); });
That should prevent the scrolling of the page, but only if the swipe happens on the div element.
I want to build a classical gallery where with the finger is possible to move the photo to left or right to see the next or previous photo.
I use jQuery binding the event touchstart, touchmove, touchend for calculate the positions of photos using the property event.pageX.
The problem is when moving finger the page begin to scroll. Immediatly the listener of touchmove stop to be invoked.
To fix the problem I had put in the touchmove listener the call event.preventDefault() and the listener was invoked regulary and the page stopped to scroll.
I want that the finger can move the photo and at the same time can scroll the page.
I see in the apple website this happen regulary (see this page http://www.apple.com/osx/)
and even this script do the same http://iosscripts.com/iosslider-jquery-horizontal-slider-for-iphone-ipad-safari/
I want to know the concept behind the scene. I can't understand what I have to do to fix that.
I even try to use preventDefault and set the $(window).scrollTop by hand calculated by the pageY but the effects was very ugly.
I have several pages that are all very similar. They have some javascript rollover links (images are preloaded, then there is a onMouseOver event that calls an image swap function and finally, there is a onMouseOut event that restores the original image).
When the user clicks on a rollover link that points to another page that has a rollover link on the exact same position, the image on the new page would be expected to load on the "over" state. This is not the case in Chrome and Safari (IE and Firefox work as expected).
So... On page load, is there a way to check if the mouse is already hovering the image to swap it right away? Something like "OnMouseAlreadyOver"?
Thank you.
If you using jQuery, it works without any problems!
http://jsfiddle.net/beuae
(not only for buttons, for divs also)
Actually, jQuery is a very good framework which assures everything goes as you expect, and cross-browser. This example confirms it.
The W3C standard says
onmouseover = script [CT]
The onmouseover event occurs when the pointing device is moved onto an element. This attribute may be used with most elements.
onmousemove = script [CT]
The onmousemove event occurs when the pointing device is moved while it is over an element. This attribute may be used with most elements.
mouseover is fired on moving over the boundary of the object. mousemove happens when the mouse is already over the element.
You may need to use onmousemove (or even both).
You may need to actually do the calculation based on the element position and the mouse cursor position.
//Get Mouse Position
document.onmousemove=getMouseCoordinates;
function getMouseCoordinates(event){
ev = event || window.event;
mouseX = ev.pageX;
mouseY = ev.pageY;
}
You can't without passing a variable to the other page or using cookies to track which was hovered (and that will fail over if people do change their mouse position)
In theory you could check the mouse position and the button position however there is no way to get the mouse position unless an event is triggered, so the mouse has to move and if it move the CSS :hover should get triggered.
It's a minor issue tho, I doubt most people are going to click a link, wait for the next page and then expect that link to be hovered and ready to click again (why wouldn't anyone one to keep clicking the same button unless it does different things)
From a UX point of view I wonder if webkit doesn't have the best approach here, why port the action of one page to another.
You can use document.getElementFromPoint(mouseX, mouseY) to get the element, but the only way to get the cursor's position is via an event. The problem is, the only events are clicks and mouse movements, which require user input from the beginning, which is what you're trying to avoid.
In short, no, it's not possible to do with JavaScript. You're left with using CSS.
I'm searching for a script like Photoswipe that works on desktop on mouse events, simulating swipe gestures.
Photoswipe without thumbnails is perfect - only I want to animate not only images but a whole div!
The first good-looking result was a jQuery plugin called jQuery mouseSwipe.
But this script only moves around a parent div which contains the items visually moved around.
If that is not enough, you should consider writing something for yourself.
Listen to mousedown and mouseup events and check the distance from the startpoint to the endpoint. If it is higher than a threshold you defined, let's say 100 Pixel, go to the next or previous element, based on the direction of the movement.
If you want it to be animated, you should also listen to the mousemove event and move the element around.
I have a div in which I have implemented iPad like swiping.
Check out what I mean on JSFiddle (Just click and drag your mouse in the div.)
I want to prevent the swiping from happening when someone is using the scroll bar (click on the scrollbar, then move from left to right, swiping still occurs).
In short, what I need is if(!event.wasTriggeredFromScrollbar) that I can use in any event trigger (in this case mousedown/move/up).
jQuery and regular 'ol Javascript answers welcomed.
Edited: To make a lot more sense.
Here's how I got around this, as it doesn't seem to actually be possible.
Step 1: Capture the MouseDown event. Store the current position of scrollLeft and scrollTop into variables.
Step 2: On the MouseMove event, check the current position of scrollLeft and scrollTop and compare them against your variables. If they're different, then cancel whatever operation you were going to perform. If they're the same, the MouseDown event wasn't triggered by a scrollbar (or anything else that would change scrollLeft and scrollTop such as another animation), and you're free to do what you wish!
Happy coding!