Get horizontal scroll event in js - javascript

What I want to do, is to catch the event when the user is scrolling div horizontally.
For vertical scroll I am using event 'mousewheel' and it's working properly. ( horizontal scroll is performed by a two finger drag on the touchpad - I am testing on Mac OS).

You can handle horizontal scrolling by :
$("#someContainer").on("scroll", function (e) {
horizontal = e.currentTarget.scrollLeft;
vertical = e.currentTarget.scrollTop;
});
In this case this bind all kind of scroll events on this element so you can also handle
Vertical by e.currentTarget.scrollTop
and
Horizontal by e.currentTarget.scrollLeft

I don't have the proper setup to test this, but $.scroll() should do the trick. It's probably preferable to binding the mousewheel event as well. People use all means of scrolling ;)

Related

Is there a way to listening on specific position "from left" in JS?

Hi all I'm working on a slider, and I would that my slide detect when the horizontal scroll reaches for example 1000px from left, hence I could trigger some dynamic event - animation, CSS style, etc.
Some here know how to listen on a specific position from left?
I have tried the while loop but the stack had just overflowed,
so any hint would be great,
thanks
If you want to detect scroll position of the whole page, it should be sufficient to attach an event handler to scroll event of window element, and inside check for the value of window.pageXOffset. I have made a small demo in this codepen. The html markup and css is just for example purposes (to have enoght content so that the whole page overflows in horizontal direction), so the important code is in js:
var scrollhandler = function(){
if(window.pageXOffset > 1000){
alert("over 1000");
window.removeEventListener("scroll",scrollhandler)
}
}
window.addEventListener("scroll", scrollhandler);

HammerJS vertical swipe and VERTICAL scroll simultaneously

I have a fullpage web site on angular 5, which do pagination by vertical swipe down and up (on desctop version is listening for wheel events). On mobile I met a serious problem with non-hiding address bar because of no scrolling happens on page (page have a size of viewport). So my structure looks like this:
<div (swipeup)="fnc()" (swipedown)="fnc()">
Container handling vertical swipes and has touch-action: pan-y property
and 100vh height
<component>Container handles horizontal swipes inside components</component>
</div>
My current Hammer config:
mc.get('pinch').set({enable: false});
mc.get('rotate').set({enable: false});
mc.get('swipe').set({direction: Hammer.DIRECTION_ALL});
mc.get('pan').set({direction: Hammer.DIRECTION_ALL});
And { "touchAction": "pan-y" } seted to container which handles vertical swipes.
With this config I'm able to scroll with hiding of address bar but vertical swipe doesn't work (or it fires super rare in strange circumstances). But I want vertical swipe to fire every time when scrolling is over and not possible (when I scroll to the bottom and my address bar became hidden it should fire next swipe in the same direction).
I will be grateful for any help or advice on how to do this in different way.
new Hammer(element, {
inputClass: Hammer.TouchInput,
});
this try

How to disable canvas elements from hijacking mouse wheel when scrolling through a page?

In HTML5 (I think?), Canvas elements on the page will interrupt scrolling when the mouse is hovering over them.
I have generated a page using Chart.js, which has many graphs on it, all of which are rendered inside a element.
Since the page is very long (vertically), the user will often scroll up / down the page to look at the various graphs. Each time they scroll onto a , they have to mouse out to continue scrolling, which is inconvenient.
Is there any way to override the canvas element's control of the mouse wheel event? I have no functionality tied to the mouse wheel. In the interim I've advised users to use keyboard shortcuts.
Thanks, as always, to this incredibly helpful community. If I find a work-around or solution I will post it here.
If you are just using Chart.js, I don't think Chart.js will hijack the wheel event. But if you use chartjs-plugin-zoom together, the wheel event will be hijacked.
(chartjs-plugin-zoom is a zoom and pan plugin for Chart.js)
chartjs-plugin-zoom hijacks mouse wheel when scrolling. If you would like the user to use mouse wheel to scroll up or down the page, instead of zooming in or out a chart, you can un-register the wheel event from the chart, as below:
var myChart = new Chart(ctx, {...});
myChart.ctx.canvas.removeEventListener('wheel', myChart._wheelHandler);
You can re-add the event handler whenever needed:
myChart.ctx.canvas.addEventListener('wheel', myChart._wheelHandler);
Check out this example on jsfiddle.
This is an example canvas:
canvas
{
background-color: red;
}
<canvas></canvas>
Run the snippet and test it. You will see there is no scroll suppression at all.
What you experience is something Chart.js adds on purpose.
To remove it do, with jQuery, as follows:
$(function () {
$("*").off("scroll");
});
This will remove all scroll handlers from all elements on the page, or a less aggressive way:
$("canvas").off("scroll");
This last way is less aggressive and keeps non-canvases alone, but it may not suffice. The scroll handler may be attached to an ancestor of the canvas, such as a an invisible div.
To exclusively capture the event you could directly change the onmousewheel method of the element.
this.canvas.onmousewheel = function(evt){
//perform your own Event dispatching here
return false;
};
```
Config option in setup. This will disable the zoom plugin.
options: {
plugins: {
zoom: false
}
}

Capturing horizontal swipe and blocking horizontal scrolling

I am trying to implement a slide-in menu for a responsive page, which appears when the device size is small. I used Bootstrap Simple Sidebar and added a top toolbar that appears when the screen width is small, which has a button to slide-in or slide-out the menu. All works well.
I am now trying to also trigger the event to slide in or out the menu using swipe left and swipe right gestures. I added JQuery Mobile (custom build with only events included).
The event triggers fine, my code looks something like this.
<script>
$(document).on("swiperight",function(e){
if ($('.smallscreen-toolbar').is(':visible')) {
e.preventDefault();
if (!$("#wrapper").hasClass("toggled"))
{
$("#wrapper").addClass("toggled");
}
}
});
$(document).on("swipeleft",function(e){
if ($('.smallscreen-toolbar').is(':visible')) {
e.preventDefault();
if ($("#wrapper").hasClass("toggled"))
{
$("#wrapper").removeClass("toggled");
}
}
});
</script>
The problem I have is that during the swipe left gesture (to close the menu), the page (which would be offset to the right) performs horizontal scrolling. When I tested it using Chrome's emulator I also got this error message: Ignored attempt to cancel a touchmove event with cancelable=false, for example because scrolling is in progress and cannot be interrupted., which I presume is related.
I am trying to cancel the event using e.preventDefault(). Isn't this the right way?
How do I block horizontal scrolling events (without blocking vertical scrolling)?
I also tried to put overflow-x: hidden on the html, body and the <div> wrapping my content but when its margin is offset to the right (when the menu is visible) I can still drag it and move it around. If I bind an event to touchmove and do e.preventDefault() during it I block everything, including swipes.

Event that gets fired before (not after!) DOM elements are scrolled in javascript

Basically, I would like to do some pre-processing before the DOM elements are scrolled. The problem is that the scroll event is fired AFTER the DOM elements are scrolled. I know that when you use the mousewheel to scroll, the mousewheel scroll event gets fired before DOM elements are scrolled although it does not provide you with the anticipated scroll position and it is only one type of scroll. I am wondering if there is any event that gets fired for every scroll method(eg. mousewheel, dragging the scroll bar, pushing the down arrow etc.) BEFORE the DOM elements are scrolled. It does not have to be an event. I am not trying to scroll to a certain position so scrollTo would not be applicable.
The chain of event with on scroll:
User scrolls -> DOM elements physically scroll -> fires onScroll event -> handle stuff
The desired chain of event:
User scrolls -> some event is captured and do what I want to do -> DOM elements physically scroll -> fires onScroll event -> handle stuff
Heres something you might want to try.
Give your page overflow:hidden so that no scroll bars appear, then place an absolutely positioned div with the correct width & height over the content. When this div is scrolled, you can then update any underlying content before re-triggering the event.
You would need to pass through clicks etc as well, so this is really a hack. Something like jQuery would help with the triggering of the events and measuring the height of the content.
EDIT: css pointer-events:none may help here depending on the browser. See https://developer.mozilla.org/en/css/pointer-events
The best you can do is when onScroll fires, if scrollTop > thingToStick's distance from the top, then set position: fixed on thingToStick otherwise, set position to whatever it was originally. It'll flicker when changing from not-sticking to sticking, but besides that, you won't get any flickering.
in sudo-ish code:
onScroll = function()
{
if(scrollTop > thingToStick.y)
thingToStick.position = "fixed";
else
thingToStick.position = "relative";
}
In browsers that don't support fixed positioning, you're stuck with the flicker...
Never tryed this before, but to break the chain of event it would be possible to :
Capture the scroll event
Do your stuff
Use preventDefault() and stopPropagation to inhibit the event
Fake a new scroll event using the original one (this should be feasible I think)
Hope this will help.

Categories

Resources