Html jQuery Mobile:动态加载的内容使DOM膨胀
TLDR:通过AJAX将弹出组件注入并替换到div中会导致jQM在div之外插入自己的覆盖元素而不删除它们 我有一个jQM网页,在ajax调用成功时动态加载div标记的内容:Html jQuery Mobile:动态加载的内容使DOM膨胀,html,caching,dom,jquery-mobile,Html,Caching,Dom,Jquery Mobile,TLDR:通过AJAX将弹出组件注入并替换到div中会导致jQM在div之外插入自己的覆盖元素而不删除它们 我有一个jQM网页,在ajax调用成功时动态加载div标记的内容: $("#contentPane").html(data).trigger("create"); ajax调用可以进行多次,每次都替换div以前的内容。加载的内容不同:它们可能有与以前相同的组件,也可能完全不同 我注意到的是,如果我注入的内容包含从页面“弹出”的UI组件(例如对话框,或带有data native menu=
$("#contentPane").html(data).trigger("create");
ajax调用可以进行多次,每次都替换div以前的内容。加载的内容不同:它们可能有与以前相同的组件,也可能完全不同
我注意到的是,如果我注入的内容包含从页面“弹出”的UI组件(例如对话框,或带有data native menu=“false”
)的selectmenu),JQM将覆盖元素直接插入活动页面主内容div之外的主体标记或活动页面标记中
例如:
<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>
...
...
...
...
...
问题是,每当我替换“contentPane”div的内容时,这些覆盖元素都会保留在DOM中。如果我注入的新内容也需要覆盖元素,那么JQM会创建新内容,而不会删除过时的内容。所以最终我的DOM看起来是这样的:
<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>
...
...
...
...
...
...
...
现在这不是一个大问题,因为它不会破坏任何功能,但看看这是一个移动应用程序,如果DOM失控,则会导致性能降低
我想知道的是,是否有某种方法可以告诉JQM清理这些过时的DOM元素,或者是否有一种方法可以检查这些覆盖是否已经过时,比如使用
$(“.ui overlay shadow,.ui-overlay-a”)
然后检查一些属性。您可以将注入页面的元素保存到变量中,然后使用jQuery中的.remove()
操作符
不幸的是,这并没有删除覆盖元素。jQuery文档确实说,对于.remove(),“与元素关联的所有绑定事件和jQuery数据都将被删除”,但我猜JQM创建的覆盖本身并没有“绑定”到我注入的元素。所以它不会从DOM中删除元素?这很奇怪,因为jQM是否对元素做了任何事情并不重要。可能只针对函数绑定,而不是DOM元素……它删除了我注入的元素,而不是JQM通过我的元素解析时创建的元素。我不能对页面中与覆盖类匹配的所有元素调用
.remove()
,因为页面上可能有一些与我注入的元素完全无关的弹出窗口。这就是为什么我想知道覆盖是否有某种属性表明它们已经“过时”了。这就是为什么我建议将注入的DOM元素保存在一个变量中,以便只针对注入的元素。jQuery mobile解析注入的代码,并在我注入的代码之外插入新元素。例如,我将我的元素放入一个div标记中,该标记位于上面示例中的“ControlContent”标记内,但JQM在“ControlContent”之外插入了自己的div(所有“ui选择菜单等”)。因此,如果我将注入的元素保存到变量中并.remove()
它,它不会影响覆盖,因为它们不包含在我的变量中。
var injectedDomElement = ...;
$(document).one("pagehide", function(){
injectedDomElement.remove();
}