使用jsdom </script>有条件地包含<script>标签

时间:2013-09-06 13:11:03

标签: javascript jquery html jsdom

我正在尝试通过包含本地.js文件和2.0.3 jquery.min.js的标记来修改本地HTML文件。以下是代码的摘录(整个脚本为here):

 jsdom.env(
  data,
  ["//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js", "../javascripts/fixit.js"],
  function (errors, window) {
    var $ = window.jQuery;
⋮

现在,如果我运行两次脚本,它会再次在HTML中包含这两个链接。有没有办法让这个有条件,只有在它们不存在时才包含标签?

2 个答案:

答案 0 :(得分:3)

(我维持jsdom。)

jsdom的重点是你可以在Node内部进行正常的DOM操作,比如测试元素的存在或插入元素。所以我会做这样的事情:

var jsdom = require("jsdom").jsdom;

var document = jsdom(data);

if (!document.head.querySelector("script[src$='2.0.3/jquery.min.js']")) {
    var script = document.createElement("script");
    script.src = "//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js";
    document.head.appendChild(script);
}

// Same for ../javascripts/fixit.js

答案 1 :(得分:2)

[编辑:这是错误的。见下面的编辑]。 检查jQuery是否已经定义,如果没有,则包括脚本。

var scripts = [], undef;
if(typeof window.jQuery === typeof undef){
    scripts = ["//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js", "../javascripts/fixit.js"];
}

jsdom.env(
  data,
  scripts,
  function (errors, window) {
⋮

我还没有对它进行过测试,但是如果config.scripts是一个空数组,则jsdom source code判断它会触发scriptComplete回调。

编辑:在阅读完您的评论后,我意识到它不会起作用。我检查jQuery的上下文超出了jsdom.env的{​​{1}}对象的范围。并且jsdom不检查是否存在要追加的脚本,因为它的用例可能是临时DOM上的内存操作。

因此,如果您需要保留修改后的DOM并且能够从文件重新读取它并再次处理而不添加这些重复的window元素,那么最简单的解决方案就是在写入文件之前将其删除

<scipt />

在此行之前添加以上其中一项:

/* if you don't want to save the document with <script> elements at all */
Array.prototype.slice.call( document.scripts ) // convert document.scripts to regular Array
.forEach( 
    function( script ){ 
      /* you probably want to check if script.src matches jQuery or whatever,
       * e.g. if( script.src.indexOf('jquery.min.js' > -1 ){
       */
       script.parentNode.removeChild( script ); 
 });


/* alternatively if you want to have each <script> exactly one (remove duplicates) */
var srcs = {};
Array.prototype.slice.call( document.scripts ) // convert document.scripts to regular Array
  .forEach( 
     function( script ){ 
        if( srcs[ scipt.src ] ){
           script.parentNode.removeChild( script );
        }
        else {
           srcs[ script.src ] = 1;
        }
  });

顺便提一下,代码中的var output = window.document.doctype + window.document.innerHTML; 也会多次添加此链接。你应该检查它的存在:

$("head").append('<link ...