2016-10-13 3 views
1

Я разрабатываю расширение сафари и динамически вставляю jquery и jqueryui в соответствии с мое требование. и после успешного ввода и загрузки я пытаюсь добавить к нему html-контент. это бросает мне такую ​​ошибку.

TypeError: нуль не является объектом (оценка '$ ("тело") добавить.)

вот моя функция, впрыснуть скрипт после загрузки страницы

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); 
} 

функции to append html content

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>'); 
} 
+0

Возможно, JQuery еще не загружен. вы пытались «jQuery (« body »). append();'? Предположение, что «null» не является объектом, предполагает, что он не видит элемент «body», и поэтому jQuery не может создать объект для этого селектора. – Twisty

+0

Когда я запустил его в FireFox, я вижу следующую ошибку: 'files [type] .forEach не является функцией' – Twisty

+0

У меня есть это до сих пор, которое должно работать так, как вы описали, но я вижу, что' filesLoaded' не выходит за пределы '0'. Это говорит о том, что событие onLoad не запускается при добавлении ссылок на файлы и источников сценариев. https://jsfiddle.net/Twisty/nt0c320p/ – Twisty

ответ

1

Создал рабочий пример, который работает в FireFox и протестирован в Safari в Windows. Я могу проверить на 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.styleSheets и document.scripts счет. Поэтому я скорректировал сценарий для поиска этой активности и обновил filesLoaded, когда этот счет растет.

Для моего тестирования у меня не было доступа к вашим локальным файлам, поэтому я вызвал файлы jQuery и jQuery UI из CDN. Я также добавил тестовый объект, myFiles, содержащий URL-адреса этих файлов.

Теперь, когда файлы jQuery загружаются, мы можем использовать их для создания элементов Dialog. Добавление необработанного HTML в тело может работать, но я считаю, что лучше построить элементы в jQuery, добавить их, а затем инициализировать dialog(). Я сделал некоторые догадки о том, как вы, возможно, захотите, чтобы они работали.

Дайте мне знать, если у вас есть вопросы.

+0

привет извилистая. и спасибо за решение, и он работает. так как u говорит в комментариях сафари can can, чтобы обнаружить события, таким образом, я пытаюсь это другим способом. просто хочу подтвердить, что это правильный путь. Я получаю содержимое js и css через вызов ajax и сохраняю его в теге стиля и скрипта. даже я сталкиваюсь с некоторыми проблемами. но позже я пытаюсь это решение работать. –