How to determine if event was fired from scrollbar - javascript

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!

Related

Preventing iPad top page drag

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.

is there a way to find mouse current position on the screen without an event?

i am making a bookmarklet in the bookmarklet i am adding a iframe to the page's body.
i need to find the current mouse position to position the iframe accordingly.
The issue is. i cannot bind on click for the bookmarklet because by the time the script within the href="javascript:" runs the click was already done. so i cannot get the event there.
i thought of binding mousemove, but that's a ugly workaround.
so is there a way to get mouse's current x/y ? without an event firing ?
Thanks.
Javascript is a language to add client side functionality on user interaction. Therefore, a javascript code snippet is always run as response to an event.
I would suggest using the onmousemove event. The event would be raised each time the cursor mouse would change. Therefore, you will know the mouse position at all times.
Hope I helped!
Have you tried something like setTimeOut()?
As far as I can tell you, there is no way to see the mouse position without using an Event object to do that.
Please, take a look at this thread:
Javascript - Track mouse position

Have html element follow finger on jQuery mobile swipe

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).

On a webpage can I hijack the vertical scrolling action and make it horizontal?

On a webpage can I hijack the vertical scrolling action and make it horizontal?
Please try and ignore the potential usability issues.
On a webpage can I hijack the vertical scrolling action and make it horizontal?
Not as far as I know (except maybe by rotating the element - but that is probably not what you want).
You would have to re-arrange the contents to make the vertical scroll bar go away, and force a horizontal one instead.
Whether that is possible will strongly depend on the nature of the HTML elements inside the page.
Here's a jQuery Plugin that does this, and you can specify it to only work when the mouse is over the target element:
http://flowplayer.org/tools/scrollable/index.html
Yes you can do this.
Vertical scrolling is set to element.scrollTop
You could simply add a loop that catches scrollTop when it changes, sets it back to zero and then sets the scrollLeft to be = to the changed position.
More so, an even better solution is to overwrite the onscroll event.
window.onscroll = function(event){
event.preventDefault() // Stops the page from scrolling vertically.
window.scrollLeft = event.scrollTop // This is not the correct event attribute, youll have to locate it yourself.
}
You could hook into the scroll event, check which plane is being scrolled, if it was the vertical then set the difference as the horizontal scroll and set the vertical scroll to it's previous value. Though I can imagine that would be incredibly expensive.

Html scroll: how to avoid it to "cut" my inner elements

this question is for an autocomplete drop down list I have to do that will fire while you're writing in an html textbox.
It basically consists of a div containing the suggestion elements, each of them being a div as well.
I got to the point where it's begining to work properly but now I added a vertical scroll to the containing div so you can limit the height of the drop down list, and I got the following behaviour:
If you use the scroll, it scrolls up or down in "pixels", so it cuts my elements making it all look anything but sleek.
I'd like to override the behaviour to go up and down one whole div element when you use the scroll. I don't even know how to google for this...
Anybody knows any useful resource about this or can give any tip as to where to start, if it's possible to override the scroll movement events or I should look into another direction?
Thanks a lot in advance
Note: I cannot use jquery autocomplete plugin.
You could implement your own scrollbar, using mouse events and updating positions manually.
Could you not tap into a 'scroll' event for that element (DOM 3 Events provides a scroll event for an element, not sure how supported it is), such that whenever the scroll position is changed, it calls a little routine of your own that adjusts the scroll position by rounding it to the nearest 'notch'?
Or, you could regularly poll for the scroll position and adjust it when it has moved. This scroll position seems fairly cross-browser.
First:
Using your own scroll bar, make a scroll event handler. Here you could use an animation by delta ( it is found in evt ) on which you can set the scrollTop of the element yourself by the offsetHeight of your top or bottom visible element. Also if the div height does cut off an element just make the previous or next element a bit "higher" aka set it's height to push the cut off element up or down.
Second:
You could "patch" the div so only a few elements would be visible. and while you scroll you hide the top one and display the bottom one in a animation, without using scrollTop or scrollHeight.
Watch out for scroll event in Firefox. It has another name, but you can test it like this:
eventName = eventName === 'mousewheel' ? ((/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : eventName) : eventName;
Good Luck. If you need any help in about 2 days i will have it implemented, because i need one too.
This simply cannot be done, there is no solution, period. One must live with this limitation.
Why is there no solution?
Because even if you implement your own scroll bar, you would still have to rely on scroll events, and these can be neither canceled nor prevented from bubbling to the body element. Really, they can't, you can call preventDefault() and stopPropagation() on them till the cows come home and they still bubble. This is a deliberate decision on the part of the standardizing body and browser implementors.
If scroll events were cancellable, EхpеrtEхchangе could prevent you from scrolling to the bottom of the page to see the answer ;) (don't worry, I used some Cyrillic letters in "EхpеrtEхchangе" so they don't get an indexable mention).

Categories

Resources