是否可以动态替换 html 页面的脚本部分?
Is it possible to dynamically replace the script section of an html page?
我开始创建一个页面,其中一些 canned/mock 数据被馈送到 Chart.JS 图表,例如:
data: [2755, 2256, 1637, 1608, 1603, 1433, 1207, 1076, 1056, 1048],
我想用 real/live 数据替换那个虚假数据。我可以用从 AJAX 调用返回的内容替换 html 页面的 <script>
部分吗?
IOW,我可以这样做吗:
$.ajax({
type: 'GET',
url:
'@Url.RouteUrl(routeName: "QuadrantData"
routeValues: new { httpRoute = true, unit = "un", begdate = "bd", enddate
"ed" })'
.replace("un", encodeURIComponent(_unit))
.replace("bd", encodeURIComponent(_begdate))
.replace("ed", encodeURIComponent(_enddate)),
contentType: 'text/plain',
cache: false,
xhrFields: {
withCredentials: false
},
success: function (returneddata) {
$("script").html(returneddata);
$("#newhourglass").addClass("hide");
},
error: function () {
console.log('error in ajax call t
QuadrantData');
$("#newhourglass").addClass("hide");
}
});
?
IOW,而不是:
$("html").html(returneddata);
...或类似这样的东西:
$("script").html(returneddata);
Can I replace the [script] part of an html page with what is passed back from an AJAX call?
不,你不能。一旦浏览器解释了脚本,它就只是 display: none;
的文本。事实上,您可以删除所有脚本 $('script').remove()
而不会对页面本身产生任何影响。
这是因为一旦脚本执行完毕,环境就会根据代码正在执行的操作进行更改,并反映已执行代码的更改。
相反,您应该尝试更改已分配给的 data
变量,并使用新数据重新初始化图表。或者,您可以在新数据输入时添加新图表。无论哪种方式,从 ajax 成功中获取数据的过程都需要在代码中完成,而不是简单地替换 html 脚本标签。
为了执行从 ajax 调用返回的任何脚本,您可以在放置在页面上的元素上使用 .html(htmlWithScriptElements)
,jQuery 将在内部为您执行脚本(使用 eval
)。
我将补充 Travis 和其他评论者所说的话。
当 HTML 被解析时,script
标签在看到结束的 script
标签时立即执行。剩下的只是一个带有内部文本的标签。我将使用以下代码片段演示此行为。
script {
display: block;
background: white;
min-height: 100px;
border: 1px solid black;
white-space: pre;
font-size: 13px;
}
Below scripts counts upward every second. But editing it wont change its after effects.
<script contenteditable="true">
counter=0;
counterInterval = setInterval(function clicked(){
console.log(counter++);
},1000);
</script>
此代码段具有 contenteditable script
。您可以在更改文本框时更改其内容。但是你会看到它的效果不会改变。
或者,当一个新的 script
标签被插入页面时(例如 javascript
),它会被执行。下面的片段演示了这一点。
reinsertScripts = function() {
var script = document.querySelector("#reinsert");
var parent = script.parentNode;
var nscript = document.createElement("script");
nscript.contentEditable = true;
nscript.id = "reinsert";
nscript.innerHTML = script.innerHTML;
parent.removeChild(script);
parent.appendChild(nscript);
}
script[contenteditable="true"] {
display: block;
background: white;
min-height: 100px;
border: 1px solid black;
white-space: pre;
font-size: 13px;
}
<p><span>Count: </span><span id="counter"></span></p>
Below scripts counts upward every second. Clicking reinsert button will rerun the script and you may see changes.
<script contenteditable="true" id="reinsert">
counter = 0;
clearInterval(window.counterInterval);
counterInterval = setInterval(function clicked() {
document.getElementById("counter").innerHTML=counter++;
}, 1000);
</script>
<button onClick="reinsertScripts()">Reinsert script</button>
虽然这是您问题的答案,但我相信这不是您需要的答案。寻找 "dynamically changing ChartJS data"。基本上,您可以使用 chart.addData
和 chart.removeData
函数来更新图表的数据。
我开始创建一个页面,其中一些 canned/mock 数据被馈送到 Chart.JS 图表,例如:
data: [2755, 2256, 1637, 1608, 1603, 1433, 1207, 1076, 1056, 1048],
我想用 real/live 数据替换那个虚假数据。我可以用从 AJAX 调用返回的内容替换 html 页面的 <script>
部分吗?
IOW,我可以这样做吗:
$.ajax({
type: 'GET',
url:
'@Url.RouteUrl(routeName: "QuadrantData"
routeValues: new { httpRoute = true, unit = "un", begdate = "bd", enddate
"ed" })'
.replace("un", encodeURIComponent(_unit))
.replace("bd", encodeURIComponent(_begdate))
.replace("ed", encodeURIComponent(_enddate)),
contentType: 'text/plain',
cache: false,
xhrFields: {
withCredentials: false
},
success: function (returneddata) {
$("script").html(returneddata);
$("#newhourglass").addClass("hide");
},
error: function () {
console.log('error in ajax call t
QuadrantData');
$("#newhourglass").addClass("hide");
}
});
?
IOW,而不是:
$("html").html(returneddata);
...或类似这样的东西:
$("script").html(returneddata);
Can I replace the [script] part of an html page with what is passed back from an AJAX call?
不,你不能。一旦浏览器解释了脚本,它就只是 display: none;
的文本。事实上,您可以删除所有脚本 $('script').remove()
而不会对页面本身产生任何影响。
这是因为一旦脚本执行完毕,环境就会根据代码正在执行的操作进行更改,并反映已执行代码的更改。
相反,您应该尝试更改已分配给的 data
变量,并使用新数据重新初始化图表。或者,您可以在新数据输入时添加新图表。无论哪种方式,从 ajax 成功中获取数据的过程都需要在代码中完成,而不是简单地替换 html 脚本标签。
为了执行从 ajax 调用返回的任何脚本,您可以在放置在页面上的元素上使用 .html(htmlWithScriptElements)
,jQuery 将在内部为您执行脚本(使用 eval
)。
我将补充 Travis 和其他评论者所说的话。
当 HTML 被解析时,script
标签在看到结束的 script
标签时立即执行。剩下的只是一个带有内部文本的标签。我将使用以下代码片段演示此行为。
script {
display: block;
background: white;
min-height: 100px;
border: 1px solid black;
white-space: pre;
font-size: 13px;
}
Below scripts counts upward every second. But editing it wont change its after effects.
<script contenteditable="true">
counter=0;
counterInterval = setInterval(function clicked(){
console.log(counter++);
},1000);
</script>
此代码段具有 contenteditable script
。您可以在更改文本框时更改其内容。但是你会看到它的效果不会改变。
或者,当一个新的 script
标签被插入页面时(例如 javascript
),它会被执行。下面的片段演示了这一点。
reinsertScripts = function() {
var script = document.querySelector("#reinsert");
var parent = script.parentNode;
var nscript = document.createElement("script");
nscript.contentEditable = true;
nscript.id = "reinsert";
nscript.innerHTML = script.innerHTML;
parent.removeChild(script);
parent.appendChild(nscript);
}
script[contenteditable="true"] {
display: block;
background: white;
min-height: 100px;
border: 1px solid black;
white-space: pre;
font-size: 13px;
}
<p><span>Count: </span><span id="counter"></span></p>
Below scripts counts upward every second. Clicking reinsert button will rerun the script and you may see changes.
<script contenteditable="true" id="reinsert">
counter = 0;
clearInterval(window.counterInterval);
counterInterval = setInterval(function clicked() {
document.getElementById("counter").innerHTML=counter++;
}, 1000);
</script>
<button onClick="reinsertScripts()">Reinsert script</button>
虽然这是您问题的答案,但我相信这不是您需要的答案。寻找 "dynamically changing ChartJS data"。基本上,您可以使用 chart.addData
和 chart.removeData
函数来更新图表的数据。