0

我正在編寫Chrome擴展,並且所討論的功能來自內容腳本,並且當任何元素被右鍵單擊並且上下文菜單項被選中。功能:Chrome擴展程序:將元素追加到未立即出現在DOM中的新注入的元素

- 當一個元素是右clicked--

  1. 創建<div>
  2. 應用jQuery UI的對話框控件的<div>
  3. 注入一個HTML文件時,包含<select>元素,至<div>
  4. 解析所選元素的所有屬性(標記,屬性等)並編譯來自屬性的元素。
  5. <option>元素寫入<select>元素。

--Then上下文菜單之後是selected--

  • 最後,被選擇的上下文菜單項時,顯示的對話框中,將含有選擇元素與選項。
  • 該HTML文件是非常基本的,所以爲了簡潔起見,我將它從下面的代碼中刪除。

    問題是,當一個元素是右鍵單擊的第一次,但一切步驟5中的作品,但然後它的第二次。然後,每一個隨後的右鍵單擊都可以正常工作 - 不管元素如何。

    下面的代碼:

    var GTFA_ELE = {}; 
    var GTFA_DIALOG_FLAG = false; 
    
    $(document).on('contextmenu',function(event){ 
        GTFA_ELE = {}; 
        //Check if the dialog has been created yet, if not, make it: 
        if(!GTFA_DIALOG_FLAG){ 
         var dialogEle = document.createElement("div"); 
         dialogEle.id = "gtfa_dialog"; 
    
         //Inject the HTML for the rule form: 
         $.get(chrome.extension.getURL('inject.html'), function(data) { 
          $(data).appendTo(dialogEle); 
         }); 
         //Commit the dialog box modal to dom: 
         document.body.appendChild(dialogEle); 
    
         //Apply the modal widget: 
         $(function() { 
          $("#gtfa_dialog").dialog({ 
           autoOpen: false 
          }); 
         }); 
         GTFA_DIALOG_FLAG = true; 
        } 
    
        GTFA_ELE = {}; 
        //Get info from the clicked element: 
        var ele = $(event.target); 
    
        //Get all the attributes: 
        $(ele[0].attributes).each(function() { 
         //Handle multiple classes differently: 
         if(this.nodeName == "class" && this.nodeValue.indexOf(" ") > 0){ 
          //Split the string of classes into an array: 
          var classes = this.value.split(" "); 
          GTFA_ELE["classes"] = classes; 
         } else { 
          GTFA_ELE[this.nodeName] = this.value; 
         } 
        }); 
        //Get the tag name and the html of the selected element. These won't be added by the loop below, because they aren't attributes: 
        GTFA_ELE.tag = event.target.tagName; 
        GTFA_ELE.html = ele.html(); 
    
        var output_html = ""; 
        //Create the <option> elements from the available selectors (tag, id, class, href, etc...): 
        $.each(GTFA_ELE, function(key, item) { 
         if(key == "classes"){ 
          class_list = ""; 
          for(i = 0; i < item.length; i++){ 
           class_list += "<option>"+item[i]+"</option>"; 
          } 
          output_html += "<option>Class...</option>"; 
         } else { 
          output_html += "<option>"+key+": "+item+"</option>"; 
         } 
        }); 
        $("#GTFA_ruleForm_url").val(GTFA_ELE.tag); 
    
        //Inject the option elements created earlier: 
        $("#GTFA_ruleForm_selector").html(output_html); 
    }); 
    
    //Handle message from background.js (context menu item is selected): 
    chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse) { 
        console.log(sender.tab ? 
           "from a content script:" + sender.tab.url : 
           "from the extension"); 
        if (request.type == "open_rule"){ 
         $("#gtfa_dialog").dialog("open"); 
         //sendResponse({farewell: "goodbye"}); 
        } 
        }); 
    

    很抱歉,如果我的解釋太爛了,讓我知道如果有什麼我可以補充。我忽略了很多,因爲它基本上是不相關的,除了提供更多的上下文之外沒有任何幫助。

    回答

    0

    這是使用回調的經典誤解。實際上,步驟(4)和(5)第一次不能正常工作,因爲$.get請求尚未完成,因此(3)在嘗試(4)和(5)時未發生。

    我建議閱讀正確使用回調和異步JavaScript。

    然後我會把if(!GTFA_DIALOG_FLAG){塊(4)和(5)在自己的功能和調用它後(3)$.get回調內部,並在else塊後兩者。