2

我正在构建一个无限滚动例程来缓存行以添加页外。

$.get将行添加到 a$('<div/>')中,然后每当我需要新行时,我从该 dom 添加一个到页面。

我读过当添加到 dom jquery 时会去掉脚本标签并执行 javascript。

这似乎给我带来了一个问题,因为当 jquery 运行脚本时,元素位于页面外 dom 中,而不是主页 dom 中。

如何保留脚本以便在向页面添加页外元素时执行它?

我已经添加了警报,并且在添加到关闭页面 dom 或实际页面 dom 时,javascript 似乎根本没有被执行,所以在这成为问题之前我可能会失败。


获取新行并将它们放置在页外 dom 中的代码:

var nextPageDOM = $('<div/>');
var jqxhr = $.get(data.nextPageURL, function(nextPageHTML) {
    nextPageDOM.html($(nextPageHTML).find(data.settings.pagedContent));

    // Get the elements to add to the page
    data.nextPageElements = nextPageDOM.find(data.settings.rowSelector);
}

从页外 DOM 添加到页面的代码:

var elementToAdd = data.nextPageElements.first().clone();
$(data.settings.pagedContent).append(elementToAdd);
4

4 回答 4

3

不知道许多变量指向哪里很难解决,所以如果我们假设 data.settings.pagedContent 指向页面上的 DOM,为什么只找到与您在 ajax 响应中已有的元素相等的元素?另一方面,如果 data.settings.pagedContent 是一个选择器,我想知道脚本是否超出了选择器。如果您提供 ajaxresponse 示例,将会非常有用。

无论如何,如果您正在寻找避免 jQuery 脚本剥离的方法,您可以执行以下操作:创建辅助 div 容器

var $cont = $("<div/>");

通过 innerHTML 将 ajax 响应插入其中(希望格式正确)

$cont[0].innerHTML = nextPageHTML;

然后从 $cont 中选择脚本并保存它们

$scripts = $cont.find("script");

现在您已经提取了脚本,您可以像以前一样继续缓存,但分别处理 html 和脚本,并且当您想要在页面 DOM 中检索一些 html 时,您还可以将脚本附加到DOM。

希望它有所帮助,很抱歉在这里要求澄清而不是在评论中,但我没有足够的声誉。

编辑(2013-01-22)

jQuery 核心功能中关于处理脚本标签解析的新闻,在jQuery 2.0 升级指南中的 jQuery 2.0 beta 上实现(jQuery 1.9 将是最后一个延续旧行为的版本)

在 HTML 内容中加载和运行脚本

在 1.9 之前,任何接受 HTML 的方法(例如,$()、.append() 或 .wrap())都会执行 HTML 中的任何脚本并将它们从文档中删除以防止它们再次被执行。在使用 .wrap() 等方法删除脚本并重新插入到文档中的情况下,这仍然会中断。从 1.9 开始,插入到文档中的脚本会被执行,但会留在文档中并标记为已执行,因此即使移除并重新插入它们也不会再次执行。

尽管发生了这种变化,但将可执行的 JavaScript 混入 HTML 标记中是非常糟糕的做法;它具有设计、安全性、可靠性和性能方面的影响。例如,HTML 中包含的外部脚本标签会被同步获取,然后进行评估,这可能会花费大量时间。没有界面可以通知这些脚本何时或是否加载,或者在出现错误时采取纠正措施。

尝试通过克隆现有脚本标记并将该克隆注入文档来加载脚本的代码将不再起作用,因为克隆的脚本标记已被标记为已执行。要加载新脚本,请改用 jQuery.getScript()。

于 2012-09-21T10:37:43.037 回答
1

据我了解,问题是没有执行动态加载的脚本。我在 SO 上找到了以下帖子,根据<script>添加到现有 DOM 元素的解决方案标签没有被执行,您必须创建一个新元素并将脚本附加到它,然后将该元素添加到您想要的任何位置。

于 2012-09-21T10:48:50.640 回答
0

简单地说,如果你想执行脚本获取脚本内容,然后使用 eval(不推荐)或通过 jQuery 创建脚本标签并将脚本插入标签中,它将自动执行

var nextPageDOM = $('<div/>');
var jqxhr = $.get(data.nextPageURL, function(nextPageHTML) {
    nextPageHTML =  stripScripts(nextPageHTML );  // remove the script tag ;)
    nextPageDOM.html($(nextPageHTML).find(data.settings.pagedContent));

    // Get the elements to add to the page
    data.nextPageElements = nextPageDOM.find(data.settings.rowSelector);
}

此函数将从 html 字符串中获取所有脚本

function getScripts(text) {
       var SCRIPT_REGEX = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
         text = text.match(SCRIPT_REGEX);
        return test;   // you can use eval to execute the script or you can crete a script tag and insert the script in the tag and it will get executed
      }

页面中的演示脚本

`<scr<script>Ha!</script>ipt> alert(document.cookie);</script>`

此功能将删除所有这些

   function stripScripts(text) {
       var SCRIPT_REGEX = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
       while (SCRIPT_REGEX.test(text)) {
         text = text.replace(SCRIPT_REGEX, "");
        }
      return test
      }
于 2012-09-21T10:49:33.723 回答
0

使用$.ajax({... datatype:script ...})而不是$.get(...)那种方式,您可以执行所有需要的 js,当然,在这个 js 中,附加页面可见部分的代码。

在页面侧:

$.ajax({url:data.nextPageURL, datatype:script, data:relevant_data_map,});

在服务器响应时(请注意标签不得存在):

alert('this is running');                        // or whatever
var nextPageDOM = $('<div/>');
nextPageDOM.html('this is from the server');     // or whatever
$(nextPageDOM).insertBefore("#end_of_content_mark");
于 2012-09-21T21:51:11.337 回答