一旦加载并执行了脚本,除非您自己整理代码,否则即使您删除/删除了原始脚本标记,您仍然会保留该代码的残余。以下几点应该会有所帮助:
- 每当您在 js 中创建/导入结构时,请确保您已编写了取消导入/销毁功能。
- 不要依赖通过
.innerHTML 或$().html() 插入的脚本标签 - 较旧的浏览器不尊重它们,这可能会导致意外结果 - 即脚本标签被忽略,或者在较旧的 Internet Explorer 的情况下,试图从错误的地方加载。
- 而是按照 thedev 的建议进行操作,并以编程方式构建您的脚本标签。
- 如果您想让每个 ajax 脚本返回其关联的脚本标签,那么显然 #3 会很棘手。
- 因此,不是在您的 ajax 请求中返回纯 HTML,而是返回一个 JSON 对象,其中包含 HTML 和需要加载的脚本路径列表。
- 如果您确保每个加载的脚本都通过一个特别命名的对象公开其所有方法,那么您可以在下次加载下一个脚本时删除该对象。
下面是说明性代码,有更复杂的(更好的)方法来处理这个(即避免在窗口上存储对象),加上下面的代码可以在许多地方都需要改进 - 它应该只会让您了解您可以做什么以及如何思考它。
还应注意,在全局window 对象上存储对象时,应使用比one、two 或three 更多的唯一名称;)
标记:
<ul class="menu">
<li><a href="one.html" data-namespace="one">One Link</a></li>
<li><a href="two.html" data-namespace="two">Two Link</a></li>
<li><a href="three.html" data-namespace="three">Three Link</a></li>
</ul>
<div id="content">
...
</div>
javascript:
/// create a wrapping scope so that our variables can be local
/// to our internal code, but not mess around with the global space.
(function(){
/// create a remembered lastID var that can store what item was loaded
var lastID;
/// an addScripts function that takes a string namespace (can be anything
/// as long as it obeys usual javascript variable naming rules), and an
/// array of script URIs.
var addScripts = function(namespace, scripts){
var s,i;
for( i=0; i<scripts.length; i++ ){
s = $('<script />')
/// attach our src attribute with the right script path
.attr('src', scripts[i])
/// add our namespace as a class to help find script tag later
.addClass(namespace);
/// add to the head of the document
$('head').append(s);
}
}
/// removeScripts works based on using the namespace we passed
/// when adding scripts as a classname to find the script tags.
/// remember removing the tags doesn't remove the executed code.
var removeScripts = function(namespace){
/// in order to tidy our code we should include a function
/// to tidy up.
if ( window[namespace] && window[namespace].tidyup ) {
window[namespace].tidyup();
}
/// remove the tag to keep the markup neat
$('script.'+namespace).remove();
}
/// a typical click handler applied to the a tags
$('.menu a').click(function(){
/// if we have a lastID remove what was before.
if ( lastID ) {
removeScripts(lastID);
}
/// get our useful info from the link
var target = $('#content');
var url = $(this).attr('href');
/// grab out our "namespace" this will be used to tie the scripts
/// together with the collection object in the loaded javascript.
var namespace = $(this).attr('data-namespace');
/// trigger an ajax request that fetches our json data
/// from the server.
$.ajax('loader.php',{dataType:'json',data:{url:url}})
.done(function(data){
/// once we have that data, add the html to the page
target.html( data.html );
/// and then add the scripts
addScripts( id, data.scripts || [] );
});
/// store the last id so we know what to remove next time
lastID = id;
});
})();
loader.php:
<?php
/// create a library of what scripts belong to what page
$scripts = array(
'one.html' => array('scripts/js/one.js'),
'two.html' => array('scripts/js/two.js'),
'three.html' => array('scripts/js/three.js'),
);
/// because `$_GET[url]` can be affected by outside influence
/// make sure you check it's value before using it.
switch( ($file = basename($_GET['url'])) ){
case 'one.html':
case 'two.html':
case 'three.html':
$json = (object) null;
if ( file_exists($file) ) {
$json->html = file_get_contents($file);
}
if ( isset($scripts[$file]) ) {
$json->scripts = $scripts[$file];
}
header('content-type: application/json');
/// json_encode should handle escaping all your html correctly
/// so that it reaches your javascript in one correct piece.
echo json_encode($json);
break;
}
?>
json(由上面的php返回):
{
"html": "<div class=\"random-content\">This can be anything</div>",
"scripts": ["scripts/js/one.js"]
}
示例 js 包括 - 即 (one.js)
/// create our collection object named with the same namespace that
/// appears in the data-namespace attribute in the markup.
window.one = {};
window.one.someMethodThatMightBeUsedByLoadedContent = function(){
/// this function has been kept specifically as part of the 'one'
/// object because it needs to be globally accessible by the html
/// that has been injected into the page. by keeping it as part
/// of a named object, removing it is rather simple. (see tidyup).
}
window.one.tidyup = function(){
/// this is the most simplistic way of tidying up a property. Depending
/// on the complexity of your javascript there are other things you should
/// keep in mind. If you have any large custom object structures it is best
/// to traverse these structures key by key and remove each element. Things
/// to read up on would be 'Javascript memory leaks', 'javascript closures'
/// and 'garbage collection'. It is also best to keep in mind you can only
/// nullify variables i.e. `var abc; abc = null;` -- you can not `delete abc`
/// this is not a problem for properties i.e. `obj.prop = 123;` and is why
/// it is best to use them for code you wish to tidy up later.
delete window.one;
}
$(function(){
/// trigger off whatever code you need onload
/// this construction will never been kept by the
/// javascript runtime as it is entirely anonymous
/// so you don't need to be worry about tidying it up.
});
上面的代码是手动输入的,所以可能会有错误,但它应该说明一种实现整洁加载系统的方法,该系统在每次加载时都能正确整理。