Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Startup JavaScript code is not executed when using the Firefox "Back" button

This website has a fancy effect: when a navigation link is clicked, the content fades out and when the new page (on a different URL) loads, its contents fade in.

What's interesting is, after users click on the "Back" button of their browsers, they go back to the previous page and the content still fades in. In other words, the previous page doesn't stay at the faded-out state, which is what was last seen. According to this comment, a page should be staying at its last seen state.

I tried many ways to reproduce this effect, yet on my tests, after clicking on the "Back" button the previous page still shows nothing (the content stays at the faded-out state). Sometimes it works on some browsers but not on others. Sometimes it works, but then it doesn't after reopening the browser.

How does the website implement this effect, which even works after users use the "Back" button to go to the previous page?


=== EDIT 1 ===

Here are my test pages.


=== EDIT 2 ===

The above test pages have been tested with Firefox on three different PCs, and Firefox from version 4 all the way to version 20 via an online cross-browser testing service. And the results are the same: doesn't work.

like image 283
Ian Y. Avatar asked Nov 29 '22 13:11

Ian Y.


2 Answers

You need a very simple workaround: hook into window.unload event, and a specific condition to reload the page inside window.onpageshow!


Firefox fix

jQuery:

$(window).unload(function () { $(window).unbind('unload'); });

JavaScript:

function UnloadHandler() { window.removeEventListener('unload', UnloadHandler, false); }
window.addEventListener('unload', UnloadHandler, false);

iOS Safari fix

jQuery:

$(window).bind('pageshow', function(event) {
    if (event.originalEvent.persisted) {
        window.location.reload() 
    }
});

JavaScript:

window.addEventListener('pageshow', function (event) {
    if (event.persisted) {
        window.location.reload() 
    }
}, false);

Working sample

Since I don't have access to update your page, I've uploaded one here.


Why Firefox needs window.onunload? MDN window.unload says:

Using this event handler in your page prevents Firefox 1.5 from caching the page in the in-memory bfcache. See Using Firefox 1.5 caching for details.

Some users might not want to disable Firefox's bfcache [see section Page caching despite unload and beforeunload handlers), and it is why the Firefox fix above is unbinding the onunload event inside of the onunload event.

Why Safari needs window.onpageshow? Apparently there's no way of disabling Safari's "bfcache", and we must refresh the page when it's shown.

PS. bfcache means back/forward cache.


Full HTML/JavaScript for reference:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Page</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>

    <div>
        <a href="fadingpage.html?p=1">Page 1</a>
        <a href="fadingpage.html?p=2">Page 2</a>
    </div>

    <div id="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas laoreet imperdiet diam, in sodales velit porta eget. Ut tellus urna, vestibulum vel facilisis eu, blandit sed est. Sed tortor justo, interdum vel iaculis eu, semper ut libero. Morbi porttitor sem eget dolor eleifend fermentum. Mauris lacinia dictum lacus ut pharetra. Proin lacus felis, vestibulum sit amet malesuada id, pretium at lorem. Duis elementum sapien vitae nibh consequat tincidunt. Proin gravida rhoncus metus sed feugiat. Sed ultricies tellus et augue adipiscing dictum. In vitae tellus eget sapien fringilla tincidunt. Vestibulum gravida, velit quis mattis elementum, lacus felis vestibulum neque, et commodo quam orci quis odio. Nunc varius viverra metus, eu dictum massa venenatis vel. Cras suscipit, orci a gravida pretium, erat massa facilisis turpis, quis sodales sem metus vitae ligula. Nunc interdum augue vel arcu vulputate quis aliquet nulla vehicula. Suspendisse eros odio, ultrices hendrerit euismod nec, condimentum sed metus.</p>
        <p>Donec at dolor et arcu aliquam tincidunt. Nulla eu elit sit amet leo facilisis posuere. Etiam non elit ac elit ornare elementum a vitae felis. Aenean semper nunc urna. Ut et interdum mi. Duis mollis est eu leo gravida vitae adipiscing leo commodo. Ut scelerisque cursus nulla, nec bibendum elit molestie sed. Nulla facilisi. Proin neque arcu, aliquam sed sagittis non, ultrices in enim. Fusce vitae nunc neque, ut sodales magna. Proin aliquam lobortis augue sed aliquet. Maecenas sit amet pellentesque mauris. Donec luctus purus hendrerit nisl pharetra eleifend. Mauris a lectus mi. In elit dui, porta a venenatis vel, consectetur id magna. Quisque vehicula leo vel nulla convallis quis sollicitudin sem fringilla.</p>
        <p>Morbi nec mi odio, eget porttitor nisi. Duis luctus blandit lacus. Donec quis sagittis mi. Maecenas id nisl enim. Aliquam erat volutpat. Nulla facilisi. Donec ac velit diam, interdum rutrum mauris. Nullam at odio eget felis tempus elementum. Nam a augue nibh, sed bibendum massa. Vivamus eget sollicitudin mauris. Pellentesque dapibus quam nec ligula blandit scelerisque. In vulputate mauris vel dolor interdum vitae aliquet nisl convallis. In massa mi, consectetur id malesuada at, suscipit vitae libero. Sed a ligula erat.</p>
    </div>

    <script type="text/javascript">
        $(function() {
            $('body').hide().fadeIn(800);
            $('a').click(function() {
                var href = $(this).attr('href');
                $('body').fadeOut(800, function() {
                    window.location = href;
                });
                return false;
            });
        });
        // Firefox fix
        $(window).unload(function () { $(window).unbind('unload'); });
        // iOS Safari fix
        $(window).bind('pageshow', function(event) {
            if (event.originalEvent.persisted) {
                window.location.reload() 
            }
        });
    </script>
</body>
</html>
like image 171
Jesse Avatar answered Dec 04 '22 07:12

Jesse


For anybody running in problems with Rails and this -- your issue isn't bfcache -- it's the turbolinks gem. Here is how to remove it.

like image 44
Yuval Karmi Avatar answered Dec 04 '22 06:12

Yuval Karmi