最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Prevent horizontal scroll in iOS WebApp - Stack Overflow

programmeradmin9浏览0评论

I've encountered similar problems before and could never really understand the workarounds, and so I ended up relying on plugins like iScroll. This is such simple task that I refuse to include a plugin for it - what I want is to prevent horizontal scroll in iOS. This includes the rubber band effect for any content that might be on the page but that isn't visible.

From what I understand I need to disable the rubber band altogether first and then apply the touch scroll to a container element (which I've given the id "touch"). Not sure if this is the right approach?

$(document).bind('touchmove', function(e) {
  if (!e.target == '#touch') {
    e.preventDefault();
  }
});

Style for #touch

-webkit-overflow-scrolling: touch;
overflow: hidden;
height: 100%;
@media only screen and (max-width: 768px) {
  width: 768px;
}

This doesn't prevent the horizontal width from staying at 728px however, the user is still able to scroll and see the hidden content. Ideas?

I've encountered similar problems before and could never really understand the workarounds, and so I ended up relying on plugins like iScroll. This is such simple task that I refuse to include a plugin for it - what I want is to prevent horizontal scroll in iOS. This includes the rubber band effect for any content that might be on the page but that isn't visible.

From what I understand I need to disable the rubber band altogether first and then apply the touch scroll to a container element (which I've given the id "touch"). Not sure if this is the right approach?

$(document).bind('touchmove', function(e) {
  if (!e.target == '#touch') {
    e.preventDefault();
  }
});

Style for #touch

-webkit-overflow-scrolling: touch;
overflow: hidden;
height: 100%;
@media only screen and (max-width: 768px) {
  width: 768px;
}

This doesn't prevent the horizontal width from staying at 728px however, the user is still able to scroll and see the hidden content. Ideas?

Share Improve this question edited Dec 2, 2014 at 13:38 Ian Clark 9,3474 gold badges34 silver badges49 bronze badges asked Oct 14, 2012 at 19:15 Staffan EstbergStaffan Estberg 7,03517 gold badges75 silver badges108 bronze badges 4
  • You can use a media query for this -> <meta name="viewport" content="width=device-width" /> This will lock the width of the page to the same width as the device in turn preventing horizontal scrolling. Does this work for you? – Ohgodwhy Commented Oct 14, 2012 at 19:30
  • Sorry, but I can't use viewport since it would zoom out too much (using media queries to specifically style size of contents for iOS devices). – Staffan Estberg Commented Oct 14, 2012 at 19:46
  • Dang. Then i'm out of ideas. Sorry :( – Ohgodwhy Commented Oct 14, 2012 at 19:48
  • Np, thanks for looking into it. Why should this be so hard? I keep getting surprised on how many issues there are with developing for iOS patibility. – Staffan Estberg Commented Oct 14, 2012 at 20:28
Add a ment  | 

4 Answers 4

Reset to default 15 +100

Well, the above metas are useful as such:

<meta content="yes" name="apple-mobile-web-app-capable" />
 <meta content="minimum-scale=1.0, width=device-width, maximum-scale=1, user-scalable=no" name="viewport" />

They prevent that bug in Safari that happens when the user rotates the screen. However, the most proper way to acplish the desired functionality is:

  • Use a parent div with overflow hidden and make sure the height of this div is limited according to the viewport and a child div with overflow:auto or the css 3 overflow-y:scroll. So basically if the size of the content inside the child div exceeds the default size of the child, you can vertically/horizontally scroll through it. Because the parent has overflow:hidden, the content outside of the child will not be displayed, so you get a proper scroll effect. ** Also, if you use overflow: hidden and prevent default for all touchEvents, there will be no scrolling or weird browser behavior**

  • With the help of JavaScript, make sure that every element in the DOM is scaled according to the viewport, so avoid using static sizes for as many elements as possible.

  • Bind the touchStart, touchMove and touchEnd events. Safari doesn't always fire a touchEnd event unless a touchMove event is listened for as well. Even if it's just a placeholder, put it there to avoid the inconsistent behavior in Safari.

  • Horizontal sliding is possible in two ways: load new content in the same div after you detect the slide direction or populate that child div with all the elements and you are good to go and actually shifting the margins/position of the child inside it's parent to 'scroll'. Animation can be used for a slicker interface.

  • Bind your touch event listeners. I don't know what library or event management system you are using, but it doesn't matter. Just call the respective function for the respective task.

  • Get the slide direction(left/right):
var slideBeginX; 
function touchStart(event){event.preventDefault();//always prevent default Safari actions
    slideBeginX = event.targetTouches[0].pageX;
};

function touchMove(event) {
event.preventDefault();
// whatever you want to add here
};

function touchEnd(event) {
event.preventDefault();
var slideEndX = event.changedTouches[0].pageX;

// Now add a minimum slide distance so that the links on the page are still clickable
if (Math.abs(slideEndX - slideBeginX) > 200) {
if (slideEndX - slideBeginX > 0) {
// It means the user has scrolled from left to right
} else {
// It means the user has scrolled from right to left.
};
};
};

This work for me on Android, iPhone and iPad.

<!doctype html>
<html>
    <head>
        <meta content="yes" name="apple-mobile-web-app-capable" />
        <meta content="minimum-scale=1.0, width=device-width, maximum-scale=1, user-scalable=no" name="viewport" />
        <title>Main</title>
    </head>
    <body>
...
    </body>
</html>

Following link might be useful to you, here vertical is disabled and horizontal enabled, you just need to tweak the code a little for your purpose.

jquery-tools-touch-horizontal-only-disable-vertical-touch

In case you aren't concerned about vertical sliding, you can try the following code also -

document.ontouchmove = function(e){
     e.preventDefault();
}

Hope it helps.

If you dont use the meta you will always get a rubber band effect.

<meta name="viewport" content="width=device-width" />

Even if the page fitted exactly the user would still be able to stretch the page wider than it should be able to go, you must use the view port to prevent this, there is no other way...

发布评论

评论列表(0)

  1. 暂无评论