javascript - 使用动态注入(inject)的 jquery 追加 html 内容时抛出 TypeError :null is not an object (evaluating "$("body").append") 错误

标签 javascript jquery html jquery-ui safari-extension

我正在开发 safari 扩展,并根据我的要求动态注入(inject) jquery 和 jqueryui。成功注入(inject)并加载后,我尝试将 html 内容附加到其中。它向我抛出了这种错误。

类型错误:null 不是对象(计算 '$("body").append')

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

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()。我对您可能希望它们如何工作进行了一些猜测。

如果您有疑问,请告诉我。

关于javascript - 使用动态注入(inject)的 jquery 追加 html 内容时抛出 TypeError :null is not an object (evaluating "$("body").append") 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40013890/

相关文章:

JavaScript:instanceof 运算符出现意外结果

javascript - Jquery:每 20 秒自动移动一次鼠标

javascript - 在 DOM 中被触发的事件列表

jquery - 如何使用 ajax 从 python wsgi 应用程序读取 JSON 对象

javascript - 半透明的 <img> 是否有可能影响它下面的元素?

javascript - 触发 iframe 上的点击不起作用

javascript - 使用 jquery 单击 div 时重定向到 Html.ActionLink

javascript - 图像交替功能交替错误的图像

jquery - 无法在 jquery 中删除克隆

video - 没有来源的 HTML5 视频标签?