水平一页式网站:Mobile-Webkit滚动&滑动问题 [英] Horizontal One-Page Site: Mobile-Webkit Scrolling & Swiping Issues

查看:109
本文介绍了水平一页式网站:Mobile-Webkit滚动&滑动问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我正在使用的基本演示: http://jsfiddle.net/3N8wY / 9 /

问题#1



如果您查看来自Android Android浏览器的链接,或者(更重要的是)iOS设备,网站不会滚动。它做这种奇怪的烦躁/脉冲的事情,并没有去哪里。它有时会滚动,如果你选择一个链接方式,但它永远不会结束在正确的位置。



我相信这与JS有关。当我在手机上试用时,我注意到它没有对选定链接的新值进行哈希处理。



JS



(pre> $(document).ready(function(){
$('。main-nav')。on('click',function(e){
e.preventDefault();
var toTarget = $(this).attr('href');
history.pushState(null,null,toTarget);
$(window ).triggerHandler('hashchange');
});
});

$(window).on('hashchange',function(){
if(!window.location.hash)return;
var $ target = $(window。 location.hash);
console.log($ target);
$('html,body')。stop()。animate({
scrollLeft:$ target.offset()。
scrollTop:$ target.offset()。top
},900,'swing');
});

JS的信用 - 水平式一页式网站不会倒退到以前的DIV






问题#2



如果向左或向右轻扫一点,它会移动页面。我不要那个。理想情况下,如果用户向右或向左滑动足够多,它会将页面捕捉到所需的方向,并且然后推送正确的散列值。如果他们没有足够的滑动,它会跳回到当前页面。



话虽如此,如果它不移动,我会很高兴在所有。我曾设想用户可以使用菜单进行导航,只能上下滚动。



有点偏离主题 / p>

有人对iOS设备中的浏览器进行模拟的桌面浏览器有什么建议吗?我相信推动股票Android浏览器的webkit是非常相似的,所以我认为如果我能够拿到测试的话,我会杀死两只鸟。在另一个项目中,我注意到我的桌面版Safari似乎提供了与我在iOS设备上发现的截然不同的结果(绝对定位的元素在各个浏览器中的top / margin-top方面表现不同)。

非常感谢您的阅读和贡献!

解决方案

问题#1



事实证明,我没有正确安装Modernizr(没有在html标签中包含no-js类),一旦纠正,就解决了我在某些Android浏览器上遇到的哈希问题。

b
$ b

之后,我仍然遇到了奇怪的滚动行为。通常,页面会滚动到所需的位置,但会跳转回去。经过进一步的研究,我发现了这个:
Jquery Animate ScrollLeft不适用于ipad



这似乎解决了一些表现不佳的不良滚动行为,但不适用于iOS设备。这可能与它有关, ScrollLeft和使用动画链(jQuery)的Ipad上的ScrollTop ,但我已经找到了其他可行的方法(将在后面发布)。



就我而言可以说,iOS设备(7+)在任何scrollLeft动画之前自动滚动到顶部。我无法访问任何物理设备,但我可以访问iMac,在那里我可以查看iOS模拟器并观察不需要的滚动行为。我试图解开两个滚动行为(左和顶,因为大多数帖子会建议你试试),但这并没有什么不同。



它可能有与我正在滚动的内容(即body或html)有关,我在几篇文章中读到了这些内容,但是搞乱了那些没有用到的结果。



As我正在测试,我意识到只通过向左滚动,我的脚本就终于正常运行了。



有趣的是,我注意到浏览器会滚动到顶部AUTOMATICALLY BEFORE 水平滚动到我的目标。所以,如果他们更新他们的代码来使scrollLeft函数正确,我将不得不返回并添加一个scrollTop函数。就目前而言......



不完全是一个修复(浏览器的行为不适合我的利益,令人担忧),但我会接受。

问题#2



为了澄清,解决这个问题尤其棘手,因为页面NEEDS以便能够向左和向右滚动(具有水平布局和所有内容),但仅在需要时才能滚动。



就尝试禁用滑动操作而言,I真的出现了。我到那里最近的时候是一个名为touchSwipe的插件;然而,这太多了(在一些移动浏览器中CSS布局),并且我似乎无法重新启用非链接('a')资产的挖掘功能。



我最终做的是创建一个函数,该函数将监视窗口的水平滚动位置,并在窗口更改时重新定位窗口。在一些浏览器中似乎有点小错误,但似乎我已经接近让每个人都快乐。编辑:将功能更改为更符合标准的窗口。 scrollTo(),在我解雇之前只需要获取职位。还没有测试过一个不喜欢它的浏览器(到目前为止,指横过)。



附注



最后,当我进行RWD测试时...



我被Chrome的'Resize Window'插件宠坏了,没有意识到其他浏览器的工作插件的平均可用性。所以,我创建了一个完整的20个不同比例的内嵌框架的测试平台,并设置为匹配最流行的设备尺寸。



当我开始考虑移动设备尺寸时,意识到浏览器的滚动条正在扭曲我的比例。我之前曾研究过自定义滚动条,所以我深入研究它试图在整个领域均衡变量。



尝试了许多不同的插件后,'nicescroll'是我唯一能够正常工作的人( http://nicescroll.areaaperta.com/ )。如果您要使用它,请务必运行移动测试( http://www.detectmobilebrowsers.com/ ),并且只能在非移动设备上运行(当然,这个脚本似乎在挑选某些移动浏览器时失败了,但总比没有好)。我测试的所有移动浏览器已经有一个类似的滚动条(默认情况下),所以它是完全没有必要的(加上它打破了一些移动浏览器)。

工作JS < h2>

  $(document).ready(function(){

var loadedTarget = $(window.location。 Hash);

函数unbindWindow(){$(window).unbind('scroll');}

函数repositionWin(){
unbindWindow();
var targetPosLeft = loadedTarget.offset()。left;
$(window).on('scroll',function(e){
var alteredPosLeft = $(window).scrollLeft() ;
var alteredPosTop = $(window).scrollTop();
if(alteredPosLeft!= targetPosLeft){
window.scrollTo(targetPosLeft,changedPosTop),
unbindWindow(), //可能是UNNECESSARY,IOS让我陷入IT,如下b $ b repositionWin();
}
});
}

function browserResult(){
if(jQuery.browser.mobile === true){
$('body')。css({overflow -x : 隐藏的, 溢出-Y: 滚动});
repositionWin();

$ {b $ b $ setTimeout((function(){
$(html)。niceScroll({
cursorcolor:'#231f20',
cursoropacitymax:'0.5',
scrollspeed:'100',
mousescrollstep:'50'
});
}),300);
setTimeout(repositionWin,300);
}
}
browserResult();
$ b $('。main-nav-link')。click(function(e){
e.preventDefault();
var toTarget = $(this).attr ('href');
history.pushState(null,null,toTarget);

//特定代码项目(很可能是幻灯片暂停/玩游戏)OMITTED

$(window).triggerHandler('hashchange');
});

}); $(b)b $ b $(window).on('hashchange',function(){

if(!window.location.hash)return;
var target = $ (window.location.hash);
var targetHash = window.location.hash;

var iOS =(navigator.userAgent.match(/(iPad | iPhone | iPod)/ g) ?true; false);

var currentPosition = $(window).scrollLeft();

var targetPosLeft = target.offset()。left;

var targetPosTop = target.offset()。top;

函数unbindWindow(){$(window).unbind('scroll');}

函数repositionWin (){
unbindWindow();
$(window).on('scroll',function(){
var alteredPosLeft = $(window).scrollLeft();
var alteredPosTop = $(window).scrollTop();
if(alteredPosLeft!= targetPosLeft){
window.scrollTo(targetPosLeft,changedPosTop),
unbindWindow(),
repositionWin ();
}
}); (){
}

函数fadePages(){
if(targetPosLeft == currentPosition){
}
else {
function fadePageOut(){
$('。page-container')。stop(true,false).animate({
opacity:0.25,
transition:opacity 0.1s 0.0s ease
});
}
函数fadePageIn(){
$('。page-container')。stop(true,false).animate({
opacity:1.0,
过渡:不透明0.3s 0.0s缓解
});
}
fadePageOut();
setTimeout(fadePageIn,900);



函数pageChange(){
if(jQuery.browser.mobile === true){
if(iOS === true){
unbindWindow();
$('html,body')。stop(true,false).animate({
scrollLeft:targetPosLeft},1400);
setTimeout(repositionWin,1500);
}
else {
unbindWindow();
$('html,body')。stop(true,false).animate({
scrollLeft:targetPosLeft},1200,function(){
$(this).stop(true ,false).animate({
scrollTop:targetPosTop
},200,repositionWin);
});
}
}
else {
fadePages();
unbindWindow();
$('html,body')。stop(true,false).delay(100).animate({
scrollLeft:targetPosLeft,
scrollTop:targetPosTop
},1300 ,repositionWin);
}
}


//等待其他动画完成,以使移动设备不会被过度加载

if($ ('#mini-site-menu-button-container')。is(':visible')=== true&& $('#main-menu-wrapper')。hasClass('show-main-menu ')=== true){
setTimeout(pageChange,300)
}
if($。'footer-container')。is(':visible')=== true ){
setTimeout(pageChange,500)
}
if($。'form-instructions-wrapper')。hasClass('expand-form-instruct')=== true) {
setTimeout(pageChange,500)
}
if($('。quick-quote-container')。hasClass('toggle-open')=== true){
setTimeout(pageChange,500)
}
if($('#mini-site-menu-button-container')。is(':visible')=== false&& $('。footer-container')。is(':visible')=== false&& $('。form-instructions-wrapper')。hasClass('expand ('。-form-instruct')=== false&& $('。quick-quote-container')。hasClass('toggle-open')=== false){
pageChange(); $($'$')
if($('#main-menu-wrapper')。hasClass('show-main-menu')=== false&& $('。footer-container') .is(':visible')=== false&& $('。form-instructions-wrapper')。hasClass('expand-form-instruct')=== false&& $('。 hasClass('toggle-open')=== false){
pageChange();
}

});






干杯。



随着时间的推移,我会随时更新,或者我找到更好的解决方案。在此之前(改变选择器几乎是我的技能范围),我没有编程经验,实际上写了我自己的任何代码(这不全是我的),所以请原谅任何明显的错误。 >

Here is a basic demo of what I'm working with: http://jsfiddle.net/3N8wY/9/

Issue #1

If you view that link from a stock Android browser, or (more importantly) an iOS device, the website will not scroll. It does this odd fidgety/pulse thing and goes no where. It will sometimes scroll if you choose a link way on down the line, but it never ends up in the right spot.

I believe this has to do with the JS. When I tried it on my phone, I noticed it wasn't hashing the new value of the selected link.

JS

$(document).ready(function () {
    $('.main-nav').on('click', function (e) {
        e.preventDefault();
        var toTarget = $(this).attr('href');
        history.pushState(null, null, toTarget);
        $(window).triggerHandler('hashchange');
    });
});

$(window).on('hashchange', function () {
    if(!window.location.hash) return;
    var $target = $(window.location.hash);
    console.log($target);
    $('html, body').stop().animate({
        scrollLeft: $target.offset().left,
        scrollTop: $target.offset().top
    }, 900, 'swing');
});

CREDIT FOR JS - Horizontal One-Page site won't go "backwards" to previous DIV


Issue #2

If you swipe a little left or right, it moves the page. I do not want that. Setting the overflow to hidden has not helped with swiping.

Ideally, if the user swiped enough right or left, it would "snap" the page in the desired direction, and then push the correct hash value. If they didn't swipe enough, it would snap back to the current page.

Having said that, I will be quite happy with it if it just doesn't move at all. I had envisioned that the user would use the menu to navigate, and only be able to scroll up and down.

Somewhat off-topic

Does anyone have a suggestion for a desktop browser that closely emulates the browser in an iOS device? I believe that webkit driving the stock Android browser is very similar, so I think I'd kill two birds here if I could get a hold of that for testing. On another project, I noticed that my desktop version of Safari seemed to deliver very different results than what I'd find on an iOS device (absolutely positioned elements behaved differently with respect to "top/margin-top" in each respective browser).

Thank you very much in advance for reading and contributing! I am extremely appreciative and grateful.

解决方案

Issue #1

Turns out that I didn't have Modernizr installed correctly (hadn't included the no-js class in the html tag), which once rectified, solved the hashing issue I was running into on some stock Android browsers.

After that was fixed, I still ran into the odd scrolling behavior. Often, the page would scroll to the desired location, but then jump back. Upon further research, I came across this: Jquery Animate ScrollLeft doesnt work on ipad.

That seemed to fix the undesired scrolling behavior for some of the poor performers, but not on iOS devices. This could have something to do with it, ScrollLeft and ScrollTop on Ipad using animate chain (jQuery), but I've figured out something else that works (will post below).

So far as I can tell, iOS devices (7+) automatically scroll to top BEFORE any scrollLeft animation. I don't have access to any physical devices, but I do have access to an iMac, where I was able to get ahold of the iOS Simulator and observed the unwanted scrolling behavior. I tried unlinking the two scrolling actions (left & top, as most posts will suggest you try), but that didn't make a difference.

It might have had something to do with what I was scrolling (ie the body or the html), I read that in a few posts, but messing with that rendered no useful results.

As I was testing, I realized that by only scrolling left, my script finally functioned "properly".

The interesting bit is that I noticed that the browser would scroll to top AUTOMATICALLY BEFORE horizontally scrolling to my target. So, if they update their code to make scrollLeft function properly, I'll have to go back and add a scrollTop function. For the the time being...

Not exactly a "fix" (the browser behaving inappropriately working to my "benefit", worrisome), but I'll take it.

Issue #2

Just to clarify, it was especially tricky to tackle this one because the page NEEDS to be able to scroll left and right (what with the horizontal layout and all), but only when I want it to.

As far as attempting to disable swiping, I really came up short. The closest I got there was with a plugin called touchSwipe; however, that broke too much (CSS-layout in some mobile browsers), and I couldn't seem to re-enable the tapping of non-link('a') assets.

What I ended up doing is creating a function that would monitor the horizontal scroll position of the window, and reposition the window if it changed. Seems a little buggy in some browsers, but it seems like I'm close to making 'everybody' happy.

EDIT: Changed the function to the much more compliant window.scrollTo(), just had to fetch positions before I fired it. Haven't tested a browser that didn't like it (so far, fingers crossed).

Side note

Lastly, when I got to RWD testing...

I was spoiled with the 'Resize Window' plugin for Chrome, and didn't realize the lackluster availability of working plugins for other browsers. So, I created a testbed full of 20 or so iframes of differing proportions, set to match the most popular device dimensions.

When I got down to mobile device dimensions, I realized that the browser's scrollbar was skewing my proportions. I'd looked into custom scrollbars before, so I delved back into it to attempt to equalize the variable all across the field.

After trying many different plugins, 'nicescroll' was the only one I could get working properly (http://nicescroll.areaaperta.com/). If you're going to use it, be sure to run a mobile test (http://www.detectmobilebrowsers.com/), and only run it on non-mobile devices (admittedly, this script seems to fail at picking up some mobile browsers, but it's better than nothing). All the mobile browsers I tested already had a similar scrollbar in place (by default), so it's completely unnecessary (plus it breaks some mobile browsers).

Working JS

$(document).ready(function() {

    var loadedTarget = $(window.location.hash);

    function unbindWindow() { $(window).unbind('scroll'); }

    function repositionWin() {
        unbindWindow();
        var targetPosLeft = loadedTarget.offset().left;
        $(window).on('scroll', function(e) {
            var alteredPosLeft = $(window).scrollLeft();
            var alteredPosTop = $(window).scrollTop();
            if (alteredPosLeft != targetPosLeft) {
                window.scrollTo(targetPosLeft, alteredPosTop),
                unbindWindow(),  // MAY BE UNNECESSARY, IOS SCARED ME INTO IT, SAME AS BELOW 
                repositionWin();
            }           
        });
    }

    function browserResult() {
        if (jQuery.browser.mobile === true) {
            $('body').css({"overflow-x":"hidden","overflow-y":"scroll"});
            repositionWin();
        }
        else {
            setTimeout ((function(){
                $("html").niceScroll({
                    cursorcolor: '#231f20',
                    cursoropacitymax: '0.5',
                    scrollspeed: '100',
                    mousescrollstep: '50'
                });
            }), 300);
            setTimeout (repositionWin, 300);
        }
    }
    browserResult();

    $('.main-nav-link').click(function(e) {     
        e.preventDefault();
        var toTarget = $(this).attr('href');
        history.pushState(null, null, toTarget);

         // CODE SPECIFIC TO PROJECT (NAMELY FLEXSLIDER PAUSE/PLAY STUFF) OMITTED

        $(window).triggerHandler('hashchange');         
    });

});

$(window).on('hashchange', function () {

    if(!window.location.hash) return;
    var target = $(window.location.hash);
    var targetHash = window.location.hash;

    var iOS = ( navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false );

    var currentPosition = $(window).scrollLeft();

    var targetPosLeft = target.offset().left;

    var targetPosTop = target.offset().top;

    function unbindWindow() { $(window).unbind('scroll'); }

    function repositionWin() {
        unbindWindow();
        $(window).on('scroll', function() {
            var alteredPosLeft = $(window).scrollLeft();
            var alteredPosTop = $(window).scrollTop();          
            if (alteredPosLeft != targetPosLeft) {
                window.scrollTo(targetPosLeft, alteredPosTop),
                unbindWindow(),
                repositionWin();
            }           
        });
    }

    function fadePages() {
        if (targetPosLeft == currentPosition) {
        }
        else {
            function fadePageOut() {
                $('.page-container').stop(true,false).animate({
                    opacity: "0.25",
                    transition: "opacity 0.1s 0.0s ease"
                });
            }
            function fadePageIn() {
                $('.page-container').stop(true,false).animate({
                    opacity: "1.0",
                    transition: "opacity 0.3s 0.0s ease"
                });
            }
            fadePageOut();
            setTimeout (fadePageIn, 900);
        }
    }

    function pageChange() {
        if (jQuery.browser.mobile === true) {
            if (iOS === true) {
                unbindWindow();
                $('html,body').stop(true,false).animate({
                    scrollLeft: targetPosLeft}, 1400);
                    setTimeout (repositionWin, 1500);
            }
            else {
                unbindWindow();
                $('html,body').stop(true,false).animate({
                    scrollLeft: targetPosLeft}, 1200, function() {
                        $(this).stop(true,false).animate({
                            scrollTop: targetPosTop
                        }, 200, repositionWin);
                });
            }
        }
        else {
            fadePages();
            unbindWindow();
            $('html,body').stop(true,false).delay(100).animate({
                scrollLeft: targetPosLeft,
                scrollTop: targetPosTop
            }, 1300, repositionWin);
        }
    }


            // WAITING FOR OTHER ANIMATIONS TO COMPLETE SO THAT MOBILE DEVICES AREN'T TOO OVERLOADED

    if ($('#mini-site-menu-button-container').is(':visible') === true && $('#main-menu-wrapper').hasClass('show-main-menu') === true) {
        setTimeout (pageChange, 300)
    }
    if ($('.footer-container').is(':visible') === true) { 
        setTimeout (pageChange, 500)
    }
    if ($('.form-instructions-wrapper').hasClass('expand-form-instruct') === true) {
        setTimeout (pageChange, 500)
    }
    if ($('.quick-quote-container').hasClass('toggle-open') === true) {
        setTimeout (pageChange, 500)
    }
    if ($('#mini-site-menu-button-container').is(':visible') === false && $('.footer-container').is(':visible') === false && $('.form-instructions-wrapper').hasClass('expand-form-instruct') === false && $('.quick-quote-container').hasClass('toggle-open') === false) {
        pageChange();
    }
    if ($('#main-menu-wrapper').hasClass('show-main-menu') === false && $('.footer-container').is(':visible') === false && $('.form-instructions-wrapper').hasClass('expand-form-instruct') === false && $('.quick-quote-container').hasClass('toggle-open') === false) {
        pageChange();
    }

});


Cheers.

I'll update as time goes on, or if I find a better solution to either of the issues. I had zero programming experience actually writing any of my own code (and this isn't all "mine") before this (changing selectors was pretty much the extent of my "skills"), so please excuse any glaring mistakes.

这篇关于水平一页式网站:Mobile-Webkit滚动&amp;滑动问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆