Temporarily allow scrolling vertically with TouchSwipe plugin - javascript

I'm using SwipeTouch plugin to hide and show #child element by swiping.
I have #parent element that holds the #child element.
This #child will not always have enough content to create scrollbar, but the problem will arise when there is.The #parent constrains #child element, forcing a scrollbar if #child element is taller than the #parent
<div id="parent">
<div id="child">
<!-- Lots of content -->
</div>
</div>​
I'd like to allow swiping at any direction to show and hide the #child...
Swiping to show #child element will be referred to as swipeIN.
Swiping to hide #child element will be referred to as swipeOUT.
...problem with that is, if and when the scrollbars exist and the #child is visible, I can't scroll vertically because that would register as swiping attempt and trigger swipeOUT.
So, I had a plan:
No scrollbar: swipe at all directions to trigger swipeIN and swipeOUT.
Scrollbars: Swipe all directions to trigger swipeIN. 'Swipe' up or down to scroll, swipe left or right to trigger swipeOUT.
This was a good plan, except that it doesn't work. I guess if I was able to disable swipe top and swipe down temporarily, it would work...
Link to my attempt ( the problem is only apparent on a touch device ).
Link that is better for testing in a touch device
Any ideas on how I could get this to work?

Setting the option 'allowPageScroll' from 'auto' (default) to 'vertical' (in some cases if you want) should do the trick

I started thinking about the long term plan of my own project and some time ago finally got myself to contact the developer of the plugin via github( Link the github issue page ).
He updated the plugin so that you can now change all plugin options on the fly. That also enables the behavior I was looking for. The documentation for this can be found here ( The method is called: option ).
http://jsfiddle.net/lollero/yATmM/
http://jsfiddle.net/lollero/yATmM/show
My Code:
$(function() {
$(".parent").each(function() {
var obj = $(this),
objD = obj.data(),
objChild = obj.find('.child'),
scrollbars = obj.height() < objChild.height();
obj
.data({ "swipe": "in" })
.swipe({
fallbackToMouseEvents: true,
swipe:function( event, direction ) {
// swipeIN = swipe that shows #child
// ( Swiping is allowed for all directions ).
if ( objD.swipe === 'in' ) {
obj.data({ "swipe": "out" });
objChild.show();
// If scrollbar exists, set allowPageScroll data
// to 'vertical', so that next time when you swipe
// up or down, you can scroll vertically.
scrollbars && obj.swipe('option', 'allowPageScroll', 'vertical');
}
// swipeOUT = swipe that hides#child
// If scrollbars don't exist, swipe at any direction to hide.
// If scrollbars exits, swipe left or right to hide ( Up and Down is reserved for scrolling ).
else if (
objD.swipe === 'out' && scrollbars && ( direction === 'left' || direction === 'right' ) ||
objD.swipe === 'out' && !scrollbars
) {
obj.data({ "swipe": "in" });
objChild.hide();
// If scrollbar exists, set allowPageScroll data to
// false, so that next time when you swipe up or down,
// you actually trigger a swipe.
scrollbars && obj.swipe('option', 'allowPageScroll', false );
}
}
});
});
});

Related

Detecting jQuery scroll event from inside mousewheel event

$(".elem").on("wheel mousewheel", function(){
// if( $(this).scrollHappens ){
// do something
// } else {
// do something else
// }
//
// how to do this?
});
I'm making a fullscreen vertical content slider, which slides on mousewheel event. now, each slide might have scrollable content. in that case i don't want the silder to slide unless user has reached the bottom or top of the scrollable content (when scroll won't fire).
Or is there are any better way to do this?
Use event.target to detect if you're inside the scrolling panel, if true, then use .scrollTop() with the heights of the scrolling panels, along with the direction of scroll to detect if you're at the bottom or the top.
Here's a JSFiddle to demonstrate: https://jsfiddle.net/g6e4fj97/2/

How to restrict scrolling to the div that mouse is currently hovering?

I have a div name scrollable and whenever I hover mouse over it I want scrolling limited to this div only so that after reaching top/bottom of the div, scrolling will be stuck to the div. I've used the following code:
<div class="scrollable" style="overflow-y: scroll; height: 2px;"
onmouseover="document.body.style.overflow='hidden'"
onmouseout="document.body.style.overflow='auto'" >
Some text<br>sometext<br>sometext
</div>
Doing this gets the job done, but only problem as main scrollbar is hidden the webpage looks weird everytime I hover over '.scrollable'
Also using window.onwheel=function(){return false;} doesnt help as it prevents scrolling of anyelement.
Is there a way to enable scrolling only on hovered div and not on others while keeping main page scrollbar visible?
Thank you
You can disable scrolling without hiding the scrollbar, check this post.
Using jQuery, this would lead to:
$(".scroll").hover(function() {
var oldScrollPos = $(window).scrollTop();
$(window).on('scroll.scrolldisabler', function(event) {
$(window).scrollTop(oldScrollPos);
event.preventDefault();
});
}, function() {
$(window).off('scroll.scrolldisabler');
});
Check it out.
For me, hopefully can work
$('body').on('mousewheel', '.someDIVClass', (e: any) => {
if (e.originalEvent.wheelDelta / 120 > 0) {
// You can get scroll value here to do other things
}
else {
// You can get scroll value here to do other things
}
// This will prevent window to scroll
e.preventDefault();
e.stopPropagation();
});

Hover state Pointer events:none Javascript fallback

I have an image with behind a transparent part of it a list-element that can be hovered. The image has to be on top of the list-element. This can be achieved with
pointer-events:none;
on the image.
However IE Versions under 11 do not support this rule. I have managed to find multiple javascript solutions for on-click events, but none that also work when just hovering over the list element.
JsFiddle:http://jsfiddle.net/9Y9TH/2/
Hovering NAV 3 will give a pop-up sub-menu. When you move with your cursor to the image area, which is on top of it, the sub-menu will dissapear in IE as IE does not support pointer-events:none;
The best way is probably to invoke the getClientBoundingRects method of your DOM element, which returns the top, right, bottom and left of the element in question relative to the viewport, and then compare that to the mouse's position. This code will run whenever the user moves the mouse (often!), so I'd advise running a Modernizr test for pointer-events before executing it, as it could slow things down a fair bit unnecessarily:
$( 'body' ).on( 'mousemove', function isPositionedOnElement( mouseEvent ){
var elementBox = yourElement.getBoundingClientRects();
if (
elementBox.top <= mouseEvent.screenY &&
elementBox.bottom >= mouseEvent.screenY &&
elementBox.left <= mouseEvent.screenX &&
elementBox.right >= mouseEvent.screenX
){
// Your element is being hovered over!
}
} );

Can I tell whether a mousewheel event has already been handled by a scroll bar?

Here's what I'm trying to accomplish:
I have a page that has an area with horizontal scroll on it, and I want the user to be able to scroll left and right by using a mousewheel event (https://github.com/brandonaaron/jquery-mousewheel/blob/master/jquery.mousewheel.js) -- so I am listening for a mousewheel event on my horizontal scroll area and scrolling it if I see that there's any deltaY.
However, If there's a component inside the horizontal scrollbar, I want it to scroll vertically, and NOT bubble up and cause a scroll on the horizontal scroller.
So assuming the simplified markup looks like this - where .horizontal provides a thin horizontal content and #vertical is vertically scrollable:
<div class="horizontal">
<div id="noscroll"></div>
<div id="vertical"></div>
</div>
And there's some javascript that looks something like this:
$('body').on('.horizontal', 'mousewheel', function(e){
// check whether e has already triggered a scroll on an element
if(hasAlreadyScrolledSomething(e)){ // how can I implement hasAlreadyScrolledSomething
e.stopPropagation();
} else {
// scroll the horizontal scroll bar using deltaY
// this part is already implemented
}
});
Is there anything in the event for mousewheel that I could look at to figure it out? Keep in mind that there can be stuff inside of #vertical, so e.target might not be #vertical, but something on the inside.
Edit: here's the code some sample code to see the concept. http://jsfiddle.net/jTskZ/
Consider this:
$( '.horizontal' ).on( 'mousewheel', function ( e, delta, deltaX, deltaY ) {
if ( deltaY && !$( e.target ).closest( '#vertical' )[0] ) {
this.scrollLeft -= ( deltaY * 30 );
}
});
Live demo: http://jsfiddle.net/jTskZ/1/
So, from within the handler, you check if the mouse cursor is located over the #vertical element. If it isn't, you do the horizontal scroll.

prevent window for scrolling after div box scrolling

I have a small div box that has a vertical scroll bar and sits within an html page that also has a vertical scroll bar.
My problem is when the user reaches the end of the small DIV box scrolling, the ENTIRE html page that contains the div box then begins to scroll (assuming the user is scrolling via the mouse scroll and NOT by actually clicking the DIV box scroll buttons themselves)
is there a way to prevent the entire html page from scrolling once a user reaches in end of my small DIV box scroll? Any help would be much appreciated! Thank you!
I have tried this (but it cancels scrolling for even the div box):
if (window.addEventListener)
/** DOMMouseScroll is for mozilla. */
window.addEventListener('DOMMouseScroll', handleWheelEvent, false);
/** IE/Opera. */
window.onmousewheel = document.onmousewheel = handleWheelEvent;
function handleWheelEvent(e){
e.preventDefault();
}
I didn't look too much into your code and the problem, but I wanted to throw out a suggestion before I move on :P.
window.addEventListener
and
document.onmousewheel = handleWheelEvent;
are normally good ways to apply what you want to do the ENTIRE document, whereas if you want to apply a specific value (in this case scroll = false) to a specific element, then you need to set the reference to that specific reference (i.e. getElementById() and then it applies only to the element of the document).
Idk - maybe that helps, maybe it doesn't :P good luck.
-J
You would need to modify the handleWheelEvent function and check the srcElement property of the e event and call preventDefault() when it's not scrolling the DIV box. Here's a link with some code examples:
http://www.webdeveloper.com/forum/archive/index.php/t-158824.html
I had a similar problem. Google led me here. Over 1700 views, in 4 years, of an incomplete answer. I figured once I had coded a solution, I'd pop it in a JSFiddle and share it. Better late than never.
Tested on MacOSX / Chrome.
http://jsfiddle.net/mF8Pr/
My problem involved being able to scroll inside a textarea, within a lightbox, and disabling scrolling on the rest of the page beneath the overlay.
bind mouse wheel event to document
when event fires (optional: test to make sure overlay is visible)
check target is obj we want to have scrolling enabled
make sure 0 < obj.scrollTop < (obj.scrollHeight - obj.clientHeight)
check direction of attempted scroll event.originalEvent.deltaY
UP == negative
DOWN == positive
event.preventDefault()
$(document).bind('mousewheel', function(e){
//if($overlay.is(':visible'))
{
if(e.target != null && e.target.type != 'textarea')
{
e.preventDefault();
}
else
{
if(e.originalEvent.deltaY < 0 && e.target.scrollTop == 0)
{
e.preventDefault(); // already at top
}
else if(e.originalEvent.deltaY > 0 && e.target.scrollTop >=
(e.target.scrollHeight - e.target.clientHeight))
{
// must use greater than because sometimes
// the math is wrong by 1px
e.preventDefault(); // already at bottom
}
}
}
});
-Amanda

Categories