Detect which scrollbar was moved with the wheel event - javascript

Let's say we have a simple HTML page with div container that has vertical scrollbar. The whole page also contains vertical scrollbar:
I would like to disable the main body scrollbar feature (but it should be visible as it is) and allow user to scroll only the container's content.
I know that the only option to disable scrolling is catching the wheel event and calling preventDefault on it. However it disables all scrollbars.
Is it possible to obtain, which scroll will be affected with the event (container's or global one) and conditionally call the preventDefault method?

The solution below is written in jQuery, but it can be done in plain Javascript equivalent code as well:
$(document).on('DOMMouseScroll mousewheel', context, function(ev) {
//Do some stuff
ev.stopPropagation(); //Prevents ancestors of context of handling the event
});

Related

applying scroll events on table body

So I have a table on which I want to capture its scroll event as we capture scroll event on window. I want to capture scroll event when its body scrolls as it as some fixed height and overflow:scroll will be preset:
Fiddle here
Below is what I've tried but with no success:
$('tbody').on('scroll',function(){
alert('hellow');
});
I am not sure the above code is correct or not. I mean not sure whether there is any event like this for table.
Are there any alternatives to capture scroll events of table body. The main reason being here is fixed table header which works fine in chrome and other browsers but not in IE8 as it jumps and takes time to get fixed again!
Try this, that have to work in IE8:
$('tbody').bind('mousewheel DOMMouseScroll', onWheel);
function onWheel (e){
console.log(e);
}
jsFiddle
There is another way to trigger this event.
The table from which you want to apply this event, from there itself you can call a JavaScript function.
For example:
<table onscroll="yourFunction()"></table>
and then you can write your code in the yourFunction() function in the script tags.

prevent iPAD scrolling while allowing list scrolling

I need to disable the default iPAD scrolling (via capturing touchmove on the body) but still allow a list on my page to scroll.
I tried:
$('body').on('touchmove', function(e) { e.preventDefault(); });
$('itemList').on('touchmove', function(e) { alert('hi'); e.stopPropagation(); });
But it seems that itemList's touchmove is not being called at all. on the iPAD nothing gets scrolled.
see http://jsfiddle.net/e8dcJ
Any ideas how to solve this ?
Thanks!
maybe don't apply the event to the body, which covers everything. Instead, apply the event to a the various elements you want to prevent scrolling. Alternately, wrap everything in a DIV except the list and then set the position to fixed and add the event.

In client side JavaScript, can any element besides window get a resize event?

I get multiple pages saying that the resize event can be on a body or div element:
http://www.w3schools.com/jsref/event_onresize.asp
http://v3.javascriptmvc.com/docs/jQuery.event.special.resize.html#&who=jQuery.event.special.resize
but then I tried it in jsfiddle or in a standalone page and never can get a resize event on an element:
http://jsfiddle.net/sgHck/1/
http://jsfiddle.net/sgHck/8/
Can body or div get a resize event at all? If not, what if we need to shrink a section down in the page, and part of the page relies on the scroll event to properly place another element, and the resize event for the document, not the window, will also be needed as well?
After digging around a bit it appears that they can have resize events just not quite in the way you want.
You can add a resize event like this
$('#content').resize( function(){
//stuff to do
}
or
$('#content').on('resize', function(){
//stuff to do
}
which you are already doing, but these just don't fire when the elements are resized by javascript code or anything like that. the only way to trigger it this way is with
$('#content').trigger('resize');
which you can really do with any string. This does propagate up through the dom tree. Say you had the #content inside of a body with a 'resize' event on both of them. If you trigger the #content it will also trigger the body. However, if you trigger the event with body it will not trigger the #content.
However it seems you can get the type of functionality you want with the jquery-ui resizable method http://jqueryui.com/resizable/. After you make something resizable with
$('#content').resizable({options});
it should trigger the resize event if they are changed.

Cross-browser method to capture scroll events (or an easier way to temporarily disable scrolling)

I'm trying to execute a Javascript function whenever a user scrolls a page.
I've tried:
<body onscroll="myScrollFunction()">
and this works fine in Firefox but not IE.
I also tried:
window.onscroll = "myScrollFunction()";
but this seems to only perform the function once, similar to an onload event, but further scrolls do not fire the event. My doctype is set to strict; not sure if this makes a difference or not.
How can I get this to work across all browsers?
What I'm trying to accomplish is a way to prevent users from scrolling once a modal is displayed. I'd rather not use
overflow:hidden
because the document shifts slightly when the modal is displayed (to compensate for the scrollbar), so I figured I could capture the scroll function and lock it to the top of the page whenever the modal is displayed. If there is an easier way to do this, please let me know.
Instead of
window.onscroll = myScrollFunction();
which assigns the result of the myScrollFunction() to the onscroll handler, you want
window.onscroll = myScrollFunction;
which assigns the function itself, and will therefore be called on each scroll.
I suggest that instead of doing that, you just give your modal dialog position: fixed; which will fix it to the viewport instead of the page.
Set the <body>'s overflow to hidden while your lightbox is open.
$('body').css('overflow','hidden');
...then return to normal when it closes:
$('body').css('overflow','auto');

Mobile Safari Event Issue

I have designed a website with a menu that is initially invisible. When the user clicks on a button, the menu becomes visible. There are two ways for the user to hide the now visible menu:
Click the button that caused the menu to become visible
Click anywhere on the web page that isn't the menu
The way I have coded the second option is to tie an onclick event to the window element, and have it compare where the user clicked to the menu's position to determine if the menu should be hidden. This works great in Firefox and Safari, but it fails in Mobile Safari.
I noticed that the window onclick event only fires when I click on another element with an onclick event already assigned. If I click on an element with no event(s) assigned, the window's onclick event never fires. If I click on the button which displays the menu, it fires along with the event tied to the button.
Is it possible to assign events to the window element in Mobile Safari?
I'v been encountering this same problem. Here is what worked for me. (Note: I am working within a Modernizr and jQuery context)
First, I add a custom Modernizr class using Modernizr's addTest Plugin API to test for iOS, which will add the class appleios or no-appleios accordingly.
Because in my research the body seems to fire events on it's own agenda, I am taking a little precaution by wrapping all the document's content with an element in an iOS context. Then I add an event handler to this element.
$(".appleios body").wrapInner('<div id="appleios-helper" />');
$("#appleios-helper").bind("mouseup", function(){return;});
What was suggested earlier in this thread is using void(0). I did some quick testing, and found that void(0) as the event just wasn't causing touches on the body to be recognized. When I plugged in my own "empty" function in the form of function(){return;} things started working.
This all hinges on the fact that no events are fired in Mobile Safari unless the element explicitly has events to fire (Safari Web Content Guide.) By inserting this empty event on the wrapper, things will bubble up to the body.
If you're doing strait JavaScript with none of these libraries, the same effect could be achieved in the HTML markup
<html>
...
<body>
<div id="appleios-helper" onmouseup="function(){return;}">
...
</div>
</body>
</html>
This worked for me to hide tooltips when touching anywhere on the document's body. Your mileage may vary.
Simply adding the dummy onclick handler to the html body works for me:
<body onclick="void(0)">
Note that I am using usual live event handlers as shown below:
function liveHandler( event ) {
var target = event.target; ...}
window.addEventListener(evtype, liveHandler, true);
// evtype such as 'mousedown' or 'click'
// we use the capturing mode here (third parameter true)
This is an old question, but I struggled with the same thing today.
I found that using touchstart event works.
I solved it like this:
var isTouchDevice = 'ontouchstart' in document.documentElement;
if (isTouchDevice) {
// Do touch related stuff
$(document).on('touchstart', function (event) {
// Do stuff
});
} else {
// Do non-touch related stuff
$(document).on('click', function () {
// Do stuff
});
}
You could just add onclick="void(0);" to some <div> that covers the whole page so that no matter what, you are always clicking on an element that has an onclick event. Not a great solution, though.
I'd prefer not having the onclick event be tied to the window. Why don't you create a container <div> that has that event on it. Then handle it just like you currently are.
You can also:
$('body').css('cursor', 'pointer');
No idea what those "engineers" at Apple are doing. LOL.
This has problems though. You wouldn't want to do this on every touch device. Only touch devices that don't also have a pointing device (Laptops with Touch Screens, for example).
Source: http://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
The conclusion of the article is this:
So I don’t understand why all this is the case, but it most certainly is the case. If you’re having bubbling problems, just add an empty-function event handler anywhere between the body and the element, and you’re set to go. But it shouldn’t be necessary.

Categories

Resources