插入到页外dom时保留脚本标记,然后使用jquery页面保留

时间:2012-09-19 08:43:52

标签: javascript jquery ajax dom

我正在构建一个无限滚动例程,用于缓存要在页面外添加的行。

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

我已经读过,当添加到dom 时,jquery将删除脚本标记然后执行javascript。

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

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

我已经添加了警报,并且javascript似乎永远不会被执行,无论是在添加到off page dom还是实际的dom页面,所以也许我&#39;在此之前失败就成了问题。


获取新行并将其放在离页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);

5 个答案:

答案 0 :(得分: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 beta上实现(jQuery 1.9将是继续旧行为的最后一个版本) 来自jQuery 2.0 upgrade guide

  

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

     

1.9之前的任何HTML接受方法(例如,$(),. append()或   .wrap())执行HTML中的任何脚本并从中删除它们   文件,以防止它们再次被执行。这仍然打破了   在脚本可能被删除并重新插入的情况下   文档使用.wrap()等方法。从1.9开始,插入了脚本   执行文档,但保留在文档中并标记为   已经执行,所以即使它们是,它们也不会被再次执行   删除并重新插入。

     

尽管有这种变化,混合可执行文件的做法很糟糕   JavaScript转换成HTML标记;它具有设计,安全性,可靠性和   性能影响。例如,包括外部脚本标记   在HTML中同步获取然后进行评估,这可能需要一个   大量的时间。没有接口可以在或时通知   这些脚本是否加载,或者在那里采取纠正措施   是一个错误。

     

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

答案 1 :(得分:1)

据我所知,问题是动态加载的脚本没有被执行。我在SO上找到了following post,并且根据解决方案<script>添加到现有DOM元素的标签没有被执行,你必须创建一个新元素并向其添加脚本,然后将该元素添加到whereever你想要的。

答案 2 :(得分: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
      }

答案 3 :(得分:0)

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

页面侧:

$.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");

答案 4 :(得分:0)

似乎还有另一种阻止JavaScript运行的方法,简单的功能如下所示

function preventJS(html) {
    return html.replace(/<script(?=(\s|>))/i, '<script type="text/xml" ');
}

这里详细描述 - JavaScript: How to prevent execution of JavaScript within a html being added to the DOM。 我在Chrome,IE和FireFox中测试过。我希望它也适合你。