抛出TypeError错误:null不是一个对象(计算"$("body").append&

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

本文关键字:quot TypeError body append 错误 一个对象 抛出 计算 null      更新时间:2023-09-26

我正在开发safari扩展,并根据我的要求动态注入jquery和jqueryui。成功注入和加载后,我试图追加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计数。因此,我调整了脚本以查找此活动并在此计数增长时更新filesLoaded

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

现在jQuery文件已经加载,我们可以使用它们来创建Dialog元素。将原始HTML附加到正文中可能行得通,但我发现最好是在jQuery中构建元素,附加它们,然后初始化dialog()。我猜测了一下您可能希望它们如何工作。