Skip to content
This repository has been archived by the owner on Oct 8, 2021. It is now read-only.

Allow first page to be deleted when Dom caching is disabled #3249

Closed
itechnology opened this issue Dec 12, 2011 · 36 comments
Closed

Allow first page to be deleted when Dom caching is disabled #3249

itechnology opened this issue Dec 12, 2011 · 36 comments

Comments

@itechnology
Copy link

Apparently any FIRST page you access, will be kept in the DOM, even if dom-cache is set to false (well, it's already false in the configuration..).

Example:

I access this page 1st:

<body class="ui-mobile-viewport">
<div class="ui-page ui-body-c ui-page-active" data-dom-cache="false" data-role="page" data-url="/Mobile/User/Home" tabindex="0" style="min-height: 965px;">
<div class="ui-loader ui-body-a ui-corner-all" style="top: 482.5px;">
</body>

Now i go to this page:

<body class="ui-mobile-viewport">
<div class="ui-page ui-body-c" data-dom-cache="false" data-role="page"  data-url="/Mobile/User/Home" tabindex="0" style="min-height: 965px;">
<div class="ui-loader ui-body-a ui-corner-all" style="top: 482.5px;">
<div id="user-search" class="ui-page ui-body-c ui-page-active" data-role="page" data-url="/Mobile/User/SearchView" data-external-page="true" tabindex="0" style="min-height: 965px;">
</body>

And now if i click to go back to the first page, even tho i'm saying i do not want any dom cache, the first page will simply be displayed again, and so i get a cached copy instead of a new one.

I can navigate all over the entire site, and it will always be kept in the dom as invisible, and then just be displayed if we ever navigate back to it again. All other pages get added and removed from the dom normally as we navigate around from page to page, it's just this 1st page.

If i would have navigated to the 2nd page first, then this page would have been eternally cached in the dom.

@toddparker
Copy link
Contributor

Yes, as of 1.0 the initial page isn't removed. The rule is that only pages pulled in via Ajax are removed so this is working as planned. We're going to revisit some topics around this in upcoming releases but it's not a bug per se.

@itechnology
Copy link
Author

The real problem for us is that we need to be able to control which pages are cached and which pages must be refreshed and when.

With this behavior, basically any page on your site, will be cached indefinitely if the user happens to access that specific page 1st. .. not really a problem if the user always happens to access some kinda static placeholder page, but a lot more problematic if you access your profile page, change some stuff and go back to you profile page and see nothing has changed (well ..just one example among many use cases you will find on any dynamic site).

So for now i had to toss this my start up code:

    // INFO: We don't want jqm to keep the first page indefinitely, we need to break the cache, even if we are doing ajax
    jQuery(document).bind("pagechange", function (toPage, info) {
        if (jQuery.mobile.firstPage && info.options.fromPage && (jQuery.mobile.firstPage == info.options.fromPage)) {
            jQuery.mobile.firstPage.remove();

            // We only need to remove 1 time from DOM, so unbind the unused event
            jQuery(document).unbind("pagechange", this);
        }
    });

For us it was either this solution, or setting ajaxEnabled = false on the entire site (which is kinda a bummer)

Maybe you have a better suggestion ?

tnx

@toddparker
Copy link
Contributor

This is something we've been discussing. I just updated the title to be clearer and flagged this as a feature request. Mind link to this from the feature request wiki page here?

@itechnology
Copy link
Author

Link away :)

@minfrin
Copy link

minfrin commented Mar 22, 2012

I would definitely mark this as a bug.

In our case, we have one page with a list of things, which link to subpages describing each thing. If you land on a subpage describing each thing instead of the list page (this is trivial to do - be on the subpage and press browser reload and now the subpage is your main page), and then use on-page functionality to update the thing which results in an error message (the error message being rendered as a proper jquery mobile page), from that point on the error message is cached, because it's the body of the opening page. Until you reload the page, that cached error message is all you see.

Ideally, all pages need to behave identically with respect to caching, including the opening page, otherwise all sorts of weirdness ensues when the end user presses browser reload.

The workaround from itechnology above works for me, but ideally it shouldn't be necessary.

@adammessinger
Copy link
Contributor

I also ran into this problem and scripted a fix that keeps the first-loaded page in the DOM but refreshes it when you return to that page: https://gist.github.com/2779268

You can find more discussion on this problem and my attempts to work around it on issue #4050.

@xshhe82
Copy link

xshhe82 commented Aug 14, 2012

$(document).on("pagechange", function (toPage, info) {
                if ($.mobile.firstPage && info.options.fromPage && info.toPage && ($.mobile.firstPage == info.options.fromPage) && !$.mobile.firstPage.is('[data-dom-cache="true"]') && (info.toPage.attr('data-url') != info.options.fromPage.attr('data-url'))) {
                    jQuery.mobile.firstPage.remove();
                    $(document).off("pagechange", this);
                }
            });

@orkarlinsky
Copy link

Had the same problem and LUCKILY got here to find the solutions. I strongly urge you to push this fix to 1.2.
It's a really buggy behavior and the fix is so simple it would be a shame not to. Also, it could be hard for the developer to understand what the problem is, from his point of view sometimes the page is being cached and sometimes not, it appears to be totally random and it's hard to notice the "first page" subtle difference.

@jaspermdegroot
Copy link
Contributor

@orkarlinsky - If you read the thread of #4050 you will understand the "fix" is not that simple as it appears.

@Golodhros
Copy link

Both solutions from @xshhe82 and @itechnology woked fine at first, but it happens that when you navigate to a page, and come back to the first one with some android devices (Kindle Fire HD and Samsung Galaxy Tablet 10.1 at least) it crashes the application...
Did anybody have this same problem?

@adammessinger
Copy link
Contributor

@Golodhros, can you give this a try and let me know if it doesn't work for you? https://gist.github.com/2779268

See my comments on #4050 (starting here) for some of the issues I found and fixed while creating that code -- yours may be among them.

Note: That Gist was written for jQM 1.1.0 and hasn't yet been tested with anything newer. It also assumes you're using jQuery 1.7.x. If you aren't, try tweaking it to replace my use of .on() with .bind().

@renhart
Copy link

renhart commented Jan 18, 2013

Is there a solution to this problem for jQM 1.2? Without a work-around it's a show stopper for dynamic sites where a visitor may start from different pages, or if the user clicks the browser's reload button on a page.

@toddparker
Copy link
Contributor

We'll re-evaluate this for 1.4.

@toddparker toddparker reopened this Jan 18, 2013
@diosney
Copy link

diosney commented Feb 16, 2013

+1 for this feature, it is reeeeally needed!!!

Could you please re-evaluate it for 1.3?

--Thanks

@ToshKoevoets
Copy link

I'm also running into this issue because I'm using the same id's on different pages. This causes some javascript functions to run the code on the first id and therefore not working on the ones that are visible.

@davep3
Copy link

davep3 commented Jul 17, 2013

I had the same issue using 1.3.1.

To get around it I just implemented the following:

$(document).on("pagebeforechange", function(event, data){
    if (typeof data.toPage == "string") {
        // If we currently aren't on the home page, and we are navigating to the home page
        if ($.mobile.activePage.attr("id") != "home_page" && $.mobile.path.parseUrl(data.toPage).filename == "home_page")  {    
            // Force a page reload
            data.options.reloadPage = true;         
        }
    }
});

Probably not the nicest way to do it, but it seems to work for me.

@mdgross
Copy link

mdgross commented Jul 27, 2013

// Fix caching of first page 
$(document).on('pagechange.fixcache', function (event, info) 
{
    if($.mobile.firstPage.is('[data-dom-cache="true"]') || $.mobile.page.prototype.options.domCache && $.mobile.firstPage.is(':not([data-dom-cache="false"])'))
    {
        $(document).off('pagechange.fixcache');
    }
    else if(info.options.fromPage != undefined)
    {
        if(!($(info.toPage).is('[data-role="dialog"]') || $(info.options.fromPage).is('[data-role="dialog"]')))
        {   
            if(info.toPage.attr('data-url') != info.options.fromPage.attr('data-url'))
            {
                $.mobile.firstPage.remove();
                $(document).off('pagechange.fixcache');
            }
        }
    }
});

@jaspermdegroot
Copy link
Contributor

Closing as feature request. We are going to update the roadmap. If we decide to implement the feature we will set a specific milestone. The ticket will be re-opened when we are going to work on implementing the feature.

@itechnology
Copy link
Author

A shame to see something as old and important as this still being around 2 years after initial reporting. Especially since it affects 100% of dynamic sites.

To me, if Dom caching is disabled and its still caching the Dom, then it's a bug not a feature.

@diosney
Copy link

diosney commented Aug 7, 2013

+1 for @itechnology

This has to be considered as a bug and not as a feature since it is an unexpected and inconsistent behaviour that its very annoying.

@jaspermdegroot
Copy link
Contributor

I understand that people want this, but I don't agree that it is a bug. From the beginning it has been documented that only AJAX loaded pages are removed. If adding this feature was a simple change we would have implemented it already, but it is not.
It is still something we want to add, but there is more refactoring of navigation needed and some things might need to be done before we start working on this.

@itechnology
Copy link
Author

I understand that since 1.0 many things have probably changed making this harder to fix than most suspect.

However I reported this on 1.0 final, and alpha and beta versions did not have this behavior, so i conclude that this was tossed in as a performance enhancement afterthought since it exist since 1.0 final, but did not exist in 1.0 beta.

Anyway, enough rant. Jqm is still a pretty cool project

@renhart
Copy link

renhart commented Aug 7, 2013

Very disappointing news - was really hoping it'd be fixed for 1.4 (was actually holding off on a release to find out). Every project has bugs, but this has really been a biggie for us. This one problem has caused more trouble in work-arounds, testing, and user-support than all other JQM bugs/quirks combined. We're sticking with version 1.2 for the foreseeable future because we have a (somewhat) working set of work-arounds and known issues for the initial page loading/caching bug and don't see any enough value in future versions (to justify going through it all again) until this problem is fixed.

People are spending a LOT of time on work-arounds, none of which work 100%, and seem to require work-around after work-around themselves. If a real fix is possible, even if it takes a lot of work and postpones other fixes and other features, it would still be a very good investment. Thanks for listening!

@madscientistmark
Copy link

100% agreed. This behavior is just lame. We'd like consistent loading of pages, whether they happen to be the same as the first request or otherwise.

about to implement mdgross's hack, out of unfortunate necessity.

@ColaColin
Copy link

This is a pretty horrible issue to me as well, massively complicating my work with jqm :(
jqm is pretty awesome overall, but this bug causes a lot of trouble with all sorts of weird errors.
/votes for a fix in the near future.

Testing around it seems that a simple:
$('#page that was loaded as the first one').remove();
in the console once I navigated somewhere via ajax seems to fix my issues though.
At least in a first quick test in firefox.

Are there any downsides to this I am not seeing so far?

EDIT:
So far my solution of adding this:
$(document).on('pageshow', function(event, data) {
$('[data-role=page]').not(".ui-page-active").remove();
});
to all pages seems to work for me on opera android as well as firefox.
I have no idea what the big issue with just removing those elements from the DOM is supposed to be.

@jaspermdegroot jaspermdegroot removed this from the 1.5 - 2.0 milestone May 30, 2014
@solymosi
Copy link
Contributor

My workaround for 1.4.3 is the following:

$(function() {
    $(document).on("pagecontainerchange", $.mobile.pageContainer, function(event, ui) {
        if($.mobile.firstPage === ui.prevPage && !ui.prevPage.page("option", "domCache")) {
            ui.prevPage.remove();
        }
    });
});

@mdgross
Copy link

mdgross commented Jul 25, 2014

Hi @solymosi ,

That will work in some cases but I recommend that you use my "pagechange.fixcache" code above for a number of reasons including checking the DOM cache settings and whether a page is a dialog.

@kevg
Copy link

kevg commented Aug 23, 2014

Updated solution from @mdgross to pagecontainerchange (pagechange is deprecated):

$(document).on("pagecontainerchange.fixcache", $.mobile.pageContainer, function(event, ui) {
  if($.mobile.firstPage.is('[data-dom-cache="true"]') || $.mobile.page.prototype.options.domCache && $.mobile.firstPage.is(':not([data-dom-cache="false"])')) {
    $(document).off('pagecontainerchange.fixcache');
  } else if(ui.prevPage != undefined) {
    if(!($(ui.toPage).is('[data-role="dialog"]') || $(ui.prevPage).is('[data-role="dialog"]'))) {     
      if(ui.toPage.attr('data-url') != ui.prevPage.attr('data-url')) {
        $.mobile.firstPage.remove();
        $(document).off('pagecontainerchange.fixcache');
      }
    }
  }
});

@lpsinger
Copy link

Updated solution from @mdgross to pagecontainerchange (pagechange is deprecated):

$(document).on("pagecontainerchange.fixcache", $.mobile.pageContainer, function(event, ui) {
if($.mobile.firstPage.is('[data-dom-cache="true"]') || $.mobile.page.prototype.options.domCache && $.mobile.firstPage.is(':not([data-dom-cache="false"])')) {
$(document).off('pagecontainerchange.fixcache');
} else if(ui.prevPage != undefined) {
if(!($(ui.toPage).is('[data-role="dialog"]') || $(ui.prevPage).is('[data-role="dialog"]'))) {
if(ui.toPage.attr('data-url') != ui.prevPage.attr('data-url')) {
$.mobile.firstPage.remove();
$(document).off('pagecontainerchange.fixcache');
}
}
}
});

This solution worked for me too.

@zefrench
Copy link

Hi,
To force easily the first page to be clear from the cache use this
Saying the page name in data-role is "page1"
Use this script :
$('#page1').on('pagehide',function(event){
$('#page1').remove();
});

@mdgross
Copy link

mdgross commented Mar 12, 2015

As of 1.4.4 there is an issue with $.mobile.firstPage.remove() and the header. Calling $.mobile.firstPage.remove() is causing the header position to change. Please see #7995 for more information.

@vedbhawsar
Copy link

Can someone tell me how I can fire a javascript code written inside a document.ready statement.

What I am doing is: submitting some data to second page using HTTPPost method. It loads the second page correctly but fails to invoke the $(documnet).ready().

Thanks in advance!

@kapilgarg1996
Copy link
Contributor

@vedbhawsar try to use .delegate() method to attach events to elements now or in the future.

@thenewguy
Copy link

Since removing the first page no longer works I tackled this problem from another direction and so far the solution seems to work for my use case. I figured I would post it in case it helps anyone else.

The idea is that since the first page cannot be removed, the only way to prevent showing stale content on the first page is to generate the first page dynamically and never actually show it again after loading the app.

$(document).on("mobileinit", function(){
    $.mobile.autoInitializePage = false;
    $.mobile.loader.prototype.options.textVisible = true;
    $.mobile.loading("show");
});
$(window).one("load", function(){
    var endpoint = window.location.href;
    var $initialPage = $(":jqmData(role='page')");
    $.mobile.navigate($initialPage.attr("data-url"));
    var initialUrl = window.location.href;
    $.mobile.initializePage();
    $.mobile.path.isFirstPageUrl = function(url){return url == initialUrl};
    $.mobile.pageContainer.pagecontainer("change", endpoint);
});

My endpoint returns a noscript version of the page content and sets data-url to '/initial-page/' when it isn't requested by ajax, so I don't create the initial dummy content in the listener, but it would be trivial to adjust this to create the actual initial page content on the fly.

The downside to this approach is that it takes additional time on the initial page load. But it isn't a significant length of time and also shows the user a loading spinner. I am sure with additional tweaking it can be sped up.

@adityatr
Copy link

adityatr commented Dec 13, 2016

my Solution for 1.4.5 Bug
Step 1. Put this in our Project root folder
kapilgarg1996@b201388
This fixes header postion to change.

Then use this code which is a modified version of @mdgross

    $(document).on("pagecontainerchange.fixcache", $.mobile.pageContainer, function (event, ui) {
        if ($.mobile.firstPage.is('[data-dom-cache="true"]') || $.mobile.page.prototype.options.domCache && $.mobile.firstPage.is(':not([data-dom-cache="false"])')) {
            $(document).off('pagecontainerchange.fixcache');
        } else if (ui.prevPage != undefined) {
            if (!($(ui.toPage).hasClass('ui-dialog') || $(ui.prevPage).hasClass('ui-dialog'))) {

                
                    $.mobile.firstPage.remove();
                    $(document).off('pagecontainerchange.fixcache');
            }
        }
    });
});```

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests