【问题标题】:Is it possible to dynamically replace the script section of an html page?是否可以动态替换 html 页面的脚本部分?
【发布时间】:2016-10-13 03:42:29
【问题描述】:

我正在开始一个页面,其中一些预制/模拟数据被馈送到 Chart.JS 图表,例如:

data: [2755, 2256, 1637, 1608, 1603, 1433, 1207, 1076, 1056, 1048],

我想用真实/实时数据替换那些虚假数据。我可以用从 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);

【问题讨论】:

  • 您不需要将其添加到您的 HTML 页面中,您的数据在 returnddata 中,只需将其分配给您的图表.. 例如.. myChart.datasets[0].data = returneddata;我的图表。更新();。或类似的东西。
  • 您可以删除原始脚本节点并创建一个新节点(或者只是简单地“eval()”修改后的字符串),而不是设置脚本的“html”(不会执行)。但是 a) 很难判断该特定效果是否真的能得到你想要的,b) 你不能只修改图表的数据属性(与尝试编辑可能/可能尚未执行的脚本相比)
  • 从简单地更新图表数据到替换 html 标记内的所有内容之间还有很长的路要走。图表应该能够重新加载,如果不只是替换它并再次初始化它
  • 我的页面上有三个图表,所以我不能只将所有返回的数据分配给一个图表。我可能需要创建三个不同的 ajax 调用。
  • 我不知道我是否可以简单地“替换[图表]并再次对其进行初始化”,因为图表来自html语句,是一个简单的“画布”标签;让它生效的是 javascript,它为图表提供数据和选项,并创建图表。

标签: javascript jquery ajax asp.net-ajax script-tag


【解决方案1】:

我将补充 Travis 和其他评论者所说的内容。

在解析 HTML 时,只要看到结束的 script 标记,就会执行 script 标记。剩下的只是一个带有内部文本的标签。我将用下面的 sn-p 演示这种行为。

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>

此 sn-p 具有 contenteditable script。您可以在更改文本框时更改其内容。但你会看到它的效果不会改变。

或者,当一个新的script标签被插入到页面中时(例如javascript),它就会被执行。下面的 sn -p 演示了这一点。

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>

虽然这是您问题的答案,但我相信这不是您需要的答案。寻找“动态改变 ChartJS 数据”。基本上,您可以使用chart.addDatachart.removeData 函数来更新图表的数据。

【讨论】:

    【解决方案2】:

    我可以用从 AJAX 调用传回的内容替换 html 页面的 [script] 部分吗?

    不,你不能。一旦浏览器解释了脚本,它就只是display: none; 的文本。事实上,您可以删除所有脚本$('script').remove(),而不会对页面本身产生任何影响。

    这是因为一旦脚本执行,环境就会根据代码所做的事情发生变化,并反映执行代码的变化。

    相反,您应该尝试更改已分配给的data 变量,并使用该新数据重新初始化图表。或者,您可以在新数据进入时添加新图表。无论哪种方式,从 ajax 成功中获取数据的过程都需要在代码中完成,而不是简单地替换脚本标记的 html .

    为了执行从 ajax 调用返回的任何脚本,您可以在页面上放置的元素上使用 .html(htmlWithScriptElements),jQuery 将在内部为您执行脚本(使用 eval)。

    【讨论】:

    • 脚本必须在渲染后仍然有效,否则点击事件不会触发。可能我误会你了……
    • "从 ajax 成功中获取数据以显示的过程需要在代码中完成,而不是通过简单地替换脚本标签的 html" 是的,数据是在由 Ajax 调用并返回的 REST 方法。但是在我看来,是否可以为 Chart.JS 图表的数据属性分配返回的数据是一个悬而未决的问题。
    • 你能提供一个具体例子来说明你在最后一段中所说的内容吗?
    • @B.ClayShannon - “是否可以分配 Chart.Js 图表的数据属性”,是的,这是棘手的部分。您需要弄清楚如何根据该库的 api 重新播种数据,然后还使用 api 对其进行重绘或更新。
    • @B.ClayShannon - 在最后一段中,也许我不清楚。如果您在 ajax 成功方法中返回一个视图(因为您使用的是 mvc),并且它同时包含 html 和脚本,例如 &lt;div&gt;&lt;/div&gt;&lt;script&gt;&lt;/script&gt;&lt;p&gt;&lt;/p&gt;,并且您在变量中拥有该视图的 html 价值,例如 htmlWithScriptElements ,或者在成功回调中更常见地命名为data(我想你称之为returneddata),如果你在页面上的元素上使用.html(returneddata),那么你视图的&lt;script&gt;部分中的脚本仍然会被执行。
    猜你喜欢
    • 2012-07-08
    • 1970-01-01
    • 2013-04-30
    • 2020-08-18
    • 2023-01-13
    • 2021-04-01
    • 2018-08-24
    • 2014-04-22
    • 1970-01-01
    相关资源
    最近更新 更多