[英]Executing javascript mixed with HTML from a jQuery ajax response
或者,不是精确地“执行”,而是使用响应中返回的功能更新响应之前存在的功能。
第1步
该功能在首次加载页面时有效。
第2步
第三步
我需要更新的区域之一是地图。 那部分不起作用。
我正在使用的是混合HTML和Javascript,它们在步骤1和步骤3中都相同:
<section id="mod-map" class="module mod-map">
<header class="mod-head">
<a href="#map" class="mod-head-link"> Map <span class="arrow"></span> </a>
</header>
<div id="map" class="mod-body">
<div id="cmMap" style="position:relative;width:369px;height:303px;"></div>
<script type="text/javascript" id="cfLoadMap">
// ...some global variables are defined to use...
function loadMap()
{
// ...Bing/Virtual Earth Map Stuff...
// This part here is unique to each location's detail
var propertypoint = new VELatLong(parseFloat(36.707756),parseFloat(-78.74204));
// ...More Bing/Virtual Earth Map Stuff...
// This part here is unique to each location's detail
var label = "<div class=\"wrapper\"><img onerror=\"replaceImage(this);\" src=\"noimage.jpg\" width=\"100\" class=\"thumb\" alt=\"\" /><div class=\"caption\"><br />City<br /> State, 12345</div></div>";
// ...More Bing/Virtual Earth Map Stuff...
}
</script>
</div>
</section>
现在,在步骤3 loadMap() 不会再次调用,但它只是刷新映射到相同的位置。 由于浏览器知道loadMap()函数不会使用通过ajax检索到的进行更新。
每次ajax调用之后,上面混合HTML和javascript的更新块确实已成功添加到页面中。 它原本放置在正确的位置,但是上面的注释所指示的坐标和标题不同。 ajax回调看起来像(略有简化):
$.get(urlToLoad, {}, function(data, status, request){
var newData = $(innerShiv(data, false)),
newModules = newData.find(".module");
// (innerShiv is used to make HTML5 tags work in IE. It's possible I'm going a little overboard with using it, but I had a lot of issues with IE. :-))
newModules.each(function(i){
var thisId = "#" + $(this).attr("id"),
thisBody = $(this).find(".mod-body").html(),
toReplaceAll = $("body").find(thisId),
toReplaceBody = toReplaceAll.find(".mod-body");
// These variables are used to choose add content in different ways based on thisID. Below is the one the map area is subject to.
toReplaceBody.html(innerShiv(thisBody));
}); // each
// Various things including loadMap() get called/re-initiated/etc. here
}, "html"); // get
这在Firefox 3.6中有效,但我没有测试过其他地方(Opera 11,IE 7,Chrome 8)。
在类似情况下,我已经通过将动态PHP生成的javascript写入单独的js文件的方式进行了此操作-$ .getScript在此效果很好。 但这混入了ajax响应的HTML中。
我一直在寻找并发现并尝试了以下方法(以及其他方法):
尝试的解决方案
1. var myScript = new Function($('script#cfLoadMap', data).text()); myScript();
2. eval(newData.text());
3. eval(newData.find("#cfLoadMap").text());
4. $("head").append(newData.find("#cfLoadMap"));
到目前为止,这些似乎都没有起到任何作用。
我知道理论上还有其他方法可以做到。 但是就目前而言,除了混合HTML和javascript响应之外,我没有任何其他改变的能力。 我需要一个解决方案,
之前已经提出并解决过非常类似的问题,所以我希望可以做到。 但是,我发现的所有解决方案都无法为我工作。 可能是犯了错误或遗漏了某些东西,或者当它是一个函数时,它可能有所不同?
任何帮助,将不胜感激。
它突然开始使用以下代码:
$.get(urlToLoad, {}, function(data, status, request){
var safeData = $(innerShiv(data, false)),
newModules = safeData.find(".module"),
newScript = safeData.find("script#cfLoadMap");
// Update Each module
newModules.each(function(i){
var jqoThis = $(this),
thisId = "#" + jqoThis.attr("id"),
newModule = jqoThis,
newModBody = jqoThis.find(".mod-body"),
curModule = $("body").find(thisId),
curModBody = curModule.find(".mod-body");
// Varies by id, this one is used by the map area.
curModBody.html(innerShiv(newModBody.html()));
}); // each
// Make sure plugins are bound to new content
$("body").oneTime(100, function(){
// Various things get initiated here
// Maps -- this one works: Chrome, Firefox, IE7, Opera
$("head").append(newScript);
// Maps -- these did not work
/*
// Firefox only (but Firefox always works)
runScript = new Function(newScript.text());
runScript();
*/
/*
// Firefox only (but Firefox always works)
eval(newScript.text());
*/
}); // oneTime
}, "html"); // get
有一件事我没有通知肯定的是,没有innerShiv,在我所有的浏览器,$(数据).find(“脚本#cfLoadMap”)文本()为空白 -这是我没有想到的。
很可能JavaScript中的函数可以在非全局范围内声明,因此,当您插入<script>
标记时,jQuery会对其进行eval
,但不会替换原始函数(如您所注意到的)。
解决此问题的方法是更改从中声明函数的方式:
function loadMap()
{
...
}
对此:
window.loadMap = function loadMap() {
...
}
这样,最高级别的loadMap
将始终是服务器中发布的最新loadMap
。
您可能要考虑不以这种方式修改客户端代码,因为它会使调试变得更加棘手,但这完全取决于您。 希望这个答案对您都有效。
它突然开始使用以下代码:
$.get(urlToLoad, {}, function(data, status, request){
var safeData = $(innerShiv(data, false)),
newModules = safeData.find(".module"),
newScript = safeData.find("script#cfLoadMap");
// Update Each module
newModules.each(function(i){
var jqoThis = $(this),
thisId = "#" + jqoThis.attr("id"),
newModule = jqoThis,
newModBody = jqoThis.find(".mod-body"),
curModule = $("body").find(thisId),
curModBody = curModule.find(".mod-body");
// Varies by id, this one is used by the map area.
curModBody.html(innerShiv(newModBody.html()));
}); // each
// Make sure plugins are bound to new content
$("body").oneTime(100, function(){
// Various things get initiated here
// Maps -- this one works: Chrome, Firefox, IE7, Opera
$("head").append(newScript);
// Maps -- these did not work
/*
// Firefox only (but Firefox always works)
runScript = new Function(newScript.text());
runScript();
*/
/*
// Firefox only (but Firefox always works)
eval(newScript.text());
*/
}); // oneTime
}, "html"); // get
有一件事我没有通知肯定的是,没有innerShiv,在我所有的浏览器,$(数据).find(“脚本#cfLoadMap”)文本()为空白 -这是我没有想到的。
但是,我真的看不出这与我之前尝试过的和失败的有何不同。 如果有人发现实质性差异,请让我知道,以供将来参考?
(注意:在超时中放置Map位似乎没有什么区别,它在超时之前也能正常工作。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.