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.
Related
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
});
My web app has keyboard shortcuts that involve holding the space bar. The problem is that the mouse cursor disappears when the space bar is held. I think what's happening is that the browser is trying to scroll down (even though in my case there's never anything to scroll down to). If the user moves the mouse cursor while holding the space bar, the cursor flickers into view, only to disappear again when the mouse has stopped moving. Once the user releases the space bar, the mouse cursor stay hidden, until the mouse is moved again, after which the cursor stays visible. This happens in Chrome, Safari, Opera (webkit/blink).
Among many things, I've tried the canonical solution of preventDefault() on the event, which doesn't work, regardless of where I listen. Clearly, this is possible, because I've used apps before that employ the space bar to do something other than scroll down.
var html = document.documentElement;
var body = document.getElementsByTagName('body')[0];
document.addEventListener("keydown", function(e) {
console.log("document keydown");
e.preventDefault();
e.stopPropagation();
});
window.addEventListener("keydown", function(e) {
console.log("window keydown");
e.preventDefault();
e.stopPropagation();
});
html.addEventListener("keydown", function(e) {
console.log("html keydown");
e.preventDefault();
e.stopPropagation();
});
body.addEventListener("keydown", function(e) {
console.log("body keydown");
e.preventDefault();
e.stopPropagation();
});
document.addEventListener("keypress", function(e) {
console.log("document keypress");
e.preventDefault();
e.stopPropagation();
});
window.addEventListener("keypress", function(e) {
console.log("window keypress");
e.preventDefault();
e.stopPropagation();
});
html.addEventListener("keypress", function(e) {
console.log("html keypress");
e.preventDefault();
e.stopPropagation();
});
body.addEventListener("keypress", function(e) {
console.log("body keypress");
e.preventDefault();
e.stopPropagation();
});
Note: My app is always exactly 100% of the viewport. There is never any reason to scroll, which is why I am comfortable with the idea of overriding the convention.
Any help very appreciated.
TL/DR: apply overflow: hidden style on document.body.
I just found this unanswered (!!) question here after same problem, but in 5 min found my solution.
Several years of no answer so I'll explain my own situation too since it must be a rare context.
My scenario: Developing full-page graphic app using PIXI, along with overlaid HTML DOM elements. Using Safari on MacBook Pro.
Interest: press spacebar to interact with PIXI content
Approach: use a state tracking variable using keydown and keyup listeners. Press spacebar, in keydown update the cursor style when the event target is the document.body. Likewise revert cursor style in keyup.
Problem: the browser wants to scroll. Even when using event.preventDefault.
I never use spacebar to scroll a page, so I was entirely blind to the existing browser behaviour.
Discovery: Experimenting on other pages, including here on the SO question, I found the cursor ceases to be hidden on spacebar press when at bottom of the page. So I know the browser is considering the body length...
Solution: apply overflow: hidden style on document.body.
Now I know for various applications this may not suffice, but it DOES SOLVE THIS PROBLEM for me. The browser knows there is zero overflow processing on the body, so spacebar is inert for scrolling.
After applying this, overflow elsewhere still works: other divs of the web app can still scroll, with assigned dimensions.
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.
I have a web application running on iPad. This application contains a Kendo UI Accordion inside it.
When the content of the page is more than the size of the screen and when I want to scroll, normal page scrolling happens (as expected). But when try to scroll the Kendo Accordion, the page scrolling happens instead of accordion scrolling (unexpected).
I was able partly handle this issue by applying solution given by Chris Barr.
After applying this solution the accordion is getting scrolled instead of the whole page which I wanted.
But the problem is when I click the items on the Accordion, the accordion item doesn't get expanded. How can I get to work this.
function touchScroll(id){
if(isTouchDevice()){ //if touch events exist...
var el=document.getElementById(id);
var scrollStartPos=0;
document.getElementById(id).addEventListener("touchstart", function(event) {
scrollStartPos=this.scrollTop+event.touches[0].pageY;
event.preventDefault();
},false);
document.getElementById(id).addEventListener("touchmove", function(event) {
this.scrollTop=scrollStartPos-event.touches[0].pageY;
event.preventDefault();
},false);
}}
Remove event.preventDefault() in touchstart event listener. It will allow you to click on links inside the scrollable area.
Let's say I have a box/table with multiple rows.. These rows are draggable.
Now I have a JS where I have implemented event handlers for touchstart,touchmove, touchend for the iPad....Basically they just map these events to corresponding mouse events like mouseover, mousedown, mouseup, etc
Now here is my issue;
While I am able to drag any of the rows from the table, I also want to be able to scroll it. When I press any finger on screen and drag down, it does the drag action for that row (since I am using event.preventDefault() for touchmove to prevent the default scrolling region).
Now I understand that I cannot have both the actions (drag/scroll) using a single finger..
So I want to implement/have a scroll action when 2-fingers are used.. (The other case i.e. for single finger, it should do the drag action)
Now I am aware that event.touches.length/event.targetTouches.length gives no of fingers on screen, I am not sure how to use that to do the scrolling action... Just as an FYI, this scrolling would be similar to what we get on the iPad for fixed height div scrolling (overflow:auto), which iPad provides out-of-the-box..
You could fire preventDefault later, and optionally.
Figuring out if you want the custom / drag behavior first.
something like this: ( i have no idea if this exact code will work since i cannot test it right now, this assumes you use jQuery, and i don't know the event properties for the number of fingers but just to give you an idea:)
$('#SomeElement').TouchMove(
function(e)
{
if( /* number of fingers equals one */ )
{
e.preventDefault()
//more element-drag code could go here
return;
}
}
);