Horizontal One-Page site won't go “backwards” to previous DIV

后端 未结 2 1962
被撕碎了的回忆
被撕碎了的回忆 2021-01-28 06:40

Quick backstory:

I had everything working perfectly, but after some time, I noticed it no longer functioned properly. The ability to go back a \"page\" is extremely impo

2条回答
  •  北恋
    北恋 (楼主)
    2021-01-28 07:41

    I wanted to add this so that those who have trouble with cross-browser compliance when using Wolff's code can have some reprieve from banging their head against [...dealer's choice].

    Back to Home Issue

    Some browsers don't play nice when trying to go back to the home page, as it has no hashvalue.

    Home Page Hash Fix

    function hashHome() {
        var currentHash = location.hash;
        var homeHash = '#home';
        if (currentHash == '') {
            history.pushState(null, null, homeHash);
        }
    }
    hashHome();
    

    Webkit Simultaneous Scrolling Issue

    A HUGE problem in some webkit browsers, specifically mobile (read iOS!!!), is that when you simultaneously scroll horizontally and vertically, what you end up with is a sputtering, jittery mess that lands you back where you started. Quite devastating, and very perplexing.

    I initially thought this was due to the browser not hashing the new values, but I later realized that the new values were there, just not "reported" to the viewport. The iOS address bar (7+) doesn't reveal changes as they happen, only after tapping the address bar (DOI! whoops, should've tried that first thing...) did I figure it out. Call me crazy, but if your code relies on one thing (the new hashvalue), and that thing isn't visibly happening, you might assume (like I did) that the reason the code isn't working is because of the one thing you're "seeing" isn't happening.

    For complete explanation: Horizontal One-Page Site: Mobile-Webkit Scrolling & Swiping Issues

    The click function remains the same as Wolff's.

    Cross-browser Fix

    $(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);
            }
        }   
        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();
        }
    
    });
    

    Additional Notes

    I removed most of my additional code, but left the conditional statements on end to show how you might call the page change on a mobile site. Depending on how you choose to allow the user to navigate your page (I chose to pop my menu out from the left, hence the "toggle-open"), you'll want to allow your other animations time to complete before you fire the scrolling animation. It tends to be a lot for most mobile devices to handle all at once. I'm still too green to understand how animations que, so this is how I addressed it.

    I also added a function to fade the page container while it's scrolling. If you're going from one end of the site to the other, there's quite a bit of leg work involved in traveling that far. That much content whizzing by can be a bit off-putting to watch. Fading it a little seems to dull the blow, and I daresay it adds a little something, as well.

    Lastly, for touch enabled devices, I added a function that monitors and corrects the horizontal scroll position in between page changes. It's really easy to accidentally scroll left and right by swiping on a phone, so it seemed necessary.

提交回复
热议问题