Throw error of TypeError:null is not an object (evaluating "$("body").append") while appending html content using jquery which is dynamically injected

Throw error of TypeError:null is not an object (evaluating "$("body").append") while appending html content using jquery which is dynamically injected

我正在开发 Safari 扩展程序并根据我的要求动态注入 jquery 和 jqueryuiuirement。在成功注入和加载后,我正在尝试向其附加 html 内容。它抛出这种错误。

TypeError: null 不是一个对象(评估'$("body").append')

这是我的函数,它在页面加载后注入脚本

function injectFiles(files){
    var filesLoaded = 0;
    for(type in files){
      if(type=="css"){
          files[type].forEach(function(v,k){
              var linkTag = document.createElement('link');
              linkTag.setAttribute("rel", "stylesheet");
              linkTag.setAttribute("type", "text/css");
              linkTag.setAttribute("href", safari.extension.baseURI +"Scripts/"+v);
              document.body.appendChild(linkTag);
              linkTag.onload = function(){
                  filesLoaded++;
              };
          });
      }else if(type == "js"){
          files[type].forEach(function(v,k){
              var scriptTag = document.createElement('script');
              scriptTag.src = safari.extension.baseURI +"Scripts/"+ v;
              document.body.appendChild(scriptTag);
              scriptTag.onload = function(){
                  filesLoaded++;
              };
          });
      }
    }

    var interval = setInterval(function(){
      if(filesLoaded == files.totalFiles){
          clearInterval(interval);
          showDialog();
      }
    },100);
}

附加html内容的函数

function showDialog(){
    $("body").append( '<div id="dialog-confirm" title="Question from university tool"><p><span class="ui-icon ui-icon-alert" style="float:left; margin:12px 12px 20px 0;"></span>Is this the right login page for your school?</p></div><div id="dialog-form" title="Please enter your University URL"><input type="text" size=60 name="txtUniversityUrl" id="txtUniversityUrl" value="" class="text ui-widget-content ui-corner-all"></div>');
}

创建了一个在 FireFox 中运行并在 Windows 上的 Safari 中测试的工作示例。我稍后可以在 Mac 上测试。

示例:https://jsfiddle.net/Twisty/nt0c320p/7/

JavaScript

var cssnum = document.styleSheets.length;
var jsnum = document.scripts.length;

function injectFiles(files) {
  var filesLoaded = 0;
  var i = 0;
  for (type in files) {
    if (type == "css") {
      //files[type].forEach(function(v, k) {
      for (i = 0; i < files[type].length; i++) {
        var linkTag = document.createElement('link');
        linkTag.setAttribute("rel", "stylesheet");
        linkTag.setAttribute("type", "text/css");
        //linkTag.setAttribute("href", safari.extension.baseURI + "Scripts/" + v);
        linkTag.setAttribute("href", files[type][i]);
        document.head.appendChild(linkTag);
        //linkTag.onload = function() {
        if (cssnum < document.styleSheets.length) {
          filesLoaded++;
        };
        cssnum = document.styleSheets.length;
      }
    } else if (type == "js") {
      //files[type].forEach(function(v, k) {
      for (i = 0; i < files[type].length; i++) {
        var scriptTag = document.createElement('script');
        //scriptTag.src = safari.extension.baseURI + "Scripts/" + v;
        scriptTag.src = files[type][i];
        document.head.appendChild(scriptTag);
        //scriptTag.onload = function() {
        if (jsnum < document.scripts.length) {
          filesLoaded++;
        };
        jsnum = document.scripts.length;
      }
    }
  }

  console.log("Files Loaded: " + filesLoaded);
  var interval = setInterval(function() {
    if (filesLoaded == files.totalFiles) {
      clearInterval(interval);
      showDialog();
    }
  }, 100);
}

function showDialog() {
  var diag1 = $("<div>", {
    id: "dialog-confirm",
    title: "Question from university tool"
  });
  diag1.html('<p><span class="ui-icon ui-icon-alert" style="float:left; margin:12px 12px 20px 0;"></span>Is this the right login page for your school?</p>');
  var diag2 = $("<div>", {
    id: "dialog-form",
    title: "Please enter your University URL"
  });
  diag2.html('<input type="text" size=60 name="txtUniversityUrl" id="txtUniversityUrl" value="" class="text ui-widget-content ui-corner-all">');
  $("body").append(diag1).append(diag2);
  diag1.dialog({
    autoOpen: true,
    buttons: [{
      text: "Yes",
      click: function() {
        $(this).dialog("close");
        diag2.dialog("open");
      }
    },
    {
      text: "No",
      click: function() {
        $(this).dialog("close");
      }
    }]
  });
  diag2.dialog({
    autoOpen: false,
    width: "75%"
  });

}

var myFiles = {
  "css": [
    "https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"
  ],
  "js": [
    "https://code.jquery.com/jquery-1.12.4.js",
    "https://code.jquery.com/ui/1.12.1/jquery-ui.js"
  ],
  totalFiles: 3
};

injectFiles(myFiles);

根据我的研究,Safari 不会在加载新项目时触发事件,但会更新 document.styleSheetsdocument.scripts 计数。所以我调整了脚本以查找此 activity 并在此计数增长时更新 filesLoaded

对于我的测试,我无法访问您的本地文件,因此我从 CDN 调用了 jQuery 和 jQuery UI 文件。我还添加了一个测试对象 myFiles,其中包含这些文件的 URL。

现在 jQuery 文件已加载,我们可以使用它们来创建对话框元素。将原始 HTML 附加到正文中可能会成功,但我发现最好在 jQuery 中构建元素,附加它们,然后初始化 dialog()。我猜测了您可能希望它们如何工作。

如果您有任何问题,请告诉我。