一、 問題描述 下面舉個簡單的例子,演示問題所在。在下面 " /> 精品国产免费人成网站,国产精品午夜在线观看,欧美成a人片免费看久久

一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

用AJAX返回HTML片段中的JavaScript腳本

這是AJAX開發(fā)中很常見的問題,如果你不是一直在用JavaScript框架做開發(fā),相信你早就發(fā)現(xiàn)這個問題了。本文分析了兩個解決辦法,其中一個是講解jQuery框架的實現(xiàn)。

一、 問題描述
下面舉個簡單的例子,演示問題所在。在下面的例子中,假設變量responseText就是AJAX加載的HTML片段數(shù)據(jù),其中包含腳本彈出一條消息,用innerHTML方法插入ID為ajaxData的DIV中,你可能期望看到彈出那個消息框,結(jié)果你發(fā)現(xiàn)沒有,問題就是這樣。
復制代碼 代碼如下:
<div id="ajaxData"></div>
<script type="text/Javascript">
var responseText = '<p>這是一個段落</p><script>alert("這是AJAX加載回來的腳本片段")</script>';
document.getElementById('ajaxData').innerHTML = responseText;
</script>

二、兩種解決辦法
1、 利用JavaScript的eval方法執(zhí)行腳本。

本方法的具體實現(xiàn)思路是把xmlHttp.responseText中的腳本都抽取出來,不管AJAX加載的HTML包含多少個腳本塊,我們對找出來的腳本塊都調(diào)用eval方法執(zhí)行它即可。下面提供一個封裝好的函數(shù):
復制代碼 代碼如下:
function executeScript(html)
{
var reg = /<script[^>]*>([^/x00]+)$/i;
//對整段HTML片段按<//script>拆分
var htmlBlock = html.split("<//script>");
for (var i in htmlBlock)
{
var blocks;//匹配正則表達式的內(nèi)容數(shù)組,blocks[1]就是真正的一段腳本內(nèi)容,因為前面reg定義我們用了括號進行了捕獲分組
if (blocks = htmlBlock[i].match(reg))
{
//清除可能存在的注釋標記,對于注釋結(jié)尾-->可以忽略處理,eval一樣能正常工作
var code = blocks[1].replace(/<!--/, '');
try
{
eval(code) //執(zhí)行腳本
}
catch (e)
{
}
}
}
}

本方法的使用如下,對HTML用innerHTML方法添加到DOM,緊跟著調(diào)用executeScript方法執(zhí)行腳本塊:
復制代碼 代碼如下:
document.getElementById("div1").innerHTML = xmlHttp.responseText;
executeScript(xmlHttp.responseText);

顯然這個方法還是存在缺陷的,如果xmlHttp.responseText包含像這樣的外部腳本調(diào)用:
<script type="text/Javascript" src="/js/common.js"></script>,executeScript方法不能再深入執(zhí)行這個外部加載的腳本。

2、 學習并使用jQuery框架的實現(xiàn)

jQuery對于AJAX加載HTML,是最終在執(zhí)行html(value)方法時把整個xmlHttp.responseText數(shù)據(jù)轉(zhuǎn)換成DOM,然后利用DOM相關操作方法來找出里面的腳本,最后再把這些腳本插入到head中。具體原理也不好說,先舉個最簡單的例子,然后再分析一下大致思路。先看例子:
復制代碼 代碼如下:
$.get('ajax.ASPx', function(data)
{
$('#div1').html(data);
});

現(xiàn)在假設上面ajax.ASPx頁面返回的是HTML片段,而且包含一個或多個腳本塊,甚至外部腳本引用。div1是AJAX請求發(fā)起頁的一個DIV標簽的ID,整句代碼實現(xiàn)的結(jié)果是加載ajax.ASPx中的HTML填充到一個ID為div1的DIV標簽中。

在匿名回調(diào)函數(shù)中通過typeof(data)可以發(fā)現(xiàn)data還是原始的字符串,即等同于xmlHttp.responseText,通過代碼執(zhí)行跟蹤發(fā)現(xiàn),對AJAX加載腳本片段的執(zhí)行處理不在jQuery的AJAX模塊代碼中,而是在html(value)方法,即把一段包含腳本塊的HTML字符串插入DOM時,由它負責抽出腳本進行調(diào)用處理。而html(value)方法其實又是調(diào)用了append(value)方法……,整個過程大概調(diào)用了以下方法,箭頭代表調(diào)用這些方法的先后順序:

html -> append -> domManip -> clean -> evalScript -> globalEval

其中clean方法特別關鍵,這個方法也是jQuery比較重要的方法,其中也涉及修復HTML錯誤(標簽沒有結(jié)束,表格結(jié)構調(diào)整等方法)處理腳本。而腳本的抽出也是在這里進行的??纯聪嚓P源代碼(jQuery1.3.2):
復制代碼 代碼如下:
if (fragment)
{
for (var i = 0; ret[i]; i++)
{
if (jQuery.nodeName(ret[i], "script") && (!ret[i].type || ret[i].type.toLowerCase() === "text/Javascript"))
{
scripts.push(ret[i].parentNode ? ret[i].parentNode.removeChild(ret[i]) : ret[i]);
}
else
{
if (ret[i].nodeType === 1)
ret.splice.apply(ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))));
fragment.appendChild(ret[i]);
}
}
return scripts;
}

另外,在evalScript方法中我們還發(fā)現(xiàn)如下代碼,這里是“同”步加載像<script type="text/Javascript" src="/js/common.js"></script>這樣的外部腳本,解決executeScript方法存在的一個缺陷:
復制代碼 代碼如下:
if (elem.src)
jQuery.ajax(
{
url: elem.src,
async: false,
dataType: "script"
});

同時也發(fā)現(xiàn)如下代碼,這段代碼是把xmlHttp.responseText中的腳本刪除,因為在這個方法中,jQuery是準備把抽取的腳本放入head區(qū),所以刪除可以避免最終的HTML出現(xiàn)重復的腳本塊:
復制代碼 代碼如下:
if (elem.parentNode)

最后,在globalEval方法中,發(fā)現(xiàn)head.removeChild( script );方法,就是把腳本插入head后馬上又移除腳本標簽,這也是避免因為重復執(zhí)行html(value)方法在head區(qū)生成重復的腳本塊。這個移除是不影響腳本執(zhí)行的,同是也是不會清除腳本塊中的相關變量值。顯然,如果你想看看html(data)最終的執(zhí)行結(jié)果,比如抽取后插入到head的腳本塊是什么,你可以先臨時注釋這一行代碼。

JavaScript技術用AJAX返回HTML片段中的JavaScript腳本,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 国内一级特黄女人精品毛片 | 久草视频中文在线 | 一级风流片a级国产 | 精品国产第一国产综合精品 | 加勒比一到三区 | 91精品国产高清久久久久久io | 亚洲国产成人99精品激情在线 | 黄色长视频| 999成人精品视频在线 | 青草五月天 | 国产在线视频区 | 国产精品自产拍视频观看 | 精品国产高清自在线一区二区三区 | 欧美视频xxx | 99久久精品国产片 | 一区二区手机视频 | xx视频在线永久免费观看 | 欧美xxxx做受欧美人妖 | 激情婷婷六月天 | 久久精品网 | 99精品国产成人一区二区 | 国内久久精品视频 | fefe66毛片免费看 | 色综合久久婷婷天天 | 99精品视频在线观看 | 亚洲国产精品久久网午夜 | 青青热久久综合网伊人 | 亚洲精品国产第1页 | 色在线视频观看 | 在线亚洲精品中文字幕美乳 | 九九99久久精品午夜剧场免费 | 国产精品吹潮香蕉在线观看 | 一道精品一区二区三区 | 中国精品视频一区二区三区 | 美女三级视频 | 天天操天 | 欧美欧美乱码一二三区 | 欧美 日产 国产动漫 | 国产精品色综合久久 | 国内久久久久久久久久 | 国产91色拍 |