TLDR: Injecting and then replacing popup components into a div via AJAX is causing jQM to insert its own overlay elements outside of the div without removing them.
I have a jQM web page which dynamically loads the contents of a div tag on success of an ajax call:
$("#contentPane").html(data).trigger("create");
The ajax call can be made several times, each one replacing the previous contents of the div. The contents which are loaded vary: they may have identical components to what was previously there or, they may be completely different.
What I'm noticing is that if the contents I inject contain UI components which "popup" from the page (for example a dialog, or a selectmenu with data-native-menu = "false"
) JQM inserts overlay elements directly into the body tag or the active page tag, outside my active page's main content div.
For example:
<body>
...
<div class="ui-page ui-body-b ui-page-header-fixed ui-page-active" position="fixed" data-theme="b" data-role="page">
<div id="contentHeader" class="ui-header ui-bar-b ui-header-fixed slidedown" data-theme="b" data-position="fixed" data-role="header" role="banner">...</div>
<div id="contentPane" class="ui-content ui-body-b" data-theme="b" data-role="content" role="main">...</div>
<div class="ui-selectmenu ui-overlay-shadow ui-corner-all ui-body-a pop ui-selectmenu-hidden">...</div>
<div class="ui-selectmenu-screen ui-screen-hidden"></div>
</div>
...
<div class="ui-page ui-body-c ui-dialog ui-overlay-a" data-overlay-theme="a" data-theme="c" data-role="dialog" tabindex="0" style="min-height: 399px;">
</body>
The problem is that whenever I replace the contents of my "contentPane" div, these overlay elements stay in the DOM. If the new contents I inject require overlay elements as well, JQM creates new ones without removing the stale ones. So eventually my DOM looks like this:
<div class="ui-page ui-body-b ui-page-header-fixed ui-page-active" position="fixed" data-theme="b" data-role="page">
<div id="contentHeader" class="ui-header ui-bar-b ui-header-fixed slidedown" data-theme="b" data-position="fixed" data-role="header" role="banner">...</div>
<div id="contentPane" class="ui-content ui-body-b" data-theme="b" data-role="content" role="main">...</div>
<div class="ui-selectmenu-screen ui-screen-hidden" style="height: 3150px;"></div>
<div class="ui-selectmenu ui-overlay-shadow ui-corner-all ui-body-a pop ui-selectmenu-hidden">...</div>
<div class="ui-selectmenu-screen ui-screen-hidden"></div>
<div class="ui-selectmenu ui-selectmenu-hidden ui-overlay-shadow ui-corner-all ui-body-a pop">...</div>
<div class="ui-selectmenu-screen ui-screen-hidden"></div>
<div class="ui-selectmenu ui-selectmenu-hidden ui-overlay-shadow ui-corner-all ui-body-a pop">...</div>
<div class="ui-selectmenu-screen ui-screen-hidden"></div>
<div class="ui-selectmenu ui-selectmenu-hidden ui-overlay-shadow ui-corner-all ui-body-a pop">...</div>
<div class="ui-selectmenu-screen ui-screen-hidden"></div>
<div class="ui-selectmenu ui-selectmenu-hidden ui-overlay-shadow ui-corner-all ui-body-a pop">...</div>
</div>
Now this isn't a HUGE issue, as it doesn't break any functionality, but seeing how this is a mobile app, bloating up the DOM can lead to slow performance if it gets out of hand.
What I'm wondering is if there is some way I can tell JQM to clean up any of these stale DOM elements, or if there is a way I can check if any of these overlays have gone stale myself, say by using $(".ui-overlay-shadow, .ui-overlay-a")
and then checking some property.