2015-07-14 12 views
6

Jestem nowicjuszem, pracującym w niepełnym wymiarze godzin, pracującym nad rozszerzeniem Chrome zaprojektowanym do pracy jako wewnętrzne narzędzie CR.Znajdź pozycję Caret Anywhere na stronie

Koncepcja jest prosta, na skrócie klawiaturowym, rozszerzenie otrzymuje słowo obok znaku, sprawdza to dla dopasowania wzorca, a jeśli dopasowanie jest "prawdą", zastępuje słowo odpowiedzią z puszki.

Do tego użyłem głównie zmodyfikowanej wersji this answer.

Udało mi się wykorzystać tę funkcję, ponieważ działa to dla aktywnego elementu, ale wygląda na to, że nie działa w przypadku takich elementów, jak okno "redagowanie" w Chrome lub spójne z innymi usługami (Salesforce wydaje się również nie na przykład, na przykład). Wywiercenie o trochę myślałem, że to może być problem z iframe, więc majstrował o trochę i modyfikować ten pokój kodu:

function getActiveElement(document){ 
    document = document || window.document; 
    if(document.body === document.activeElement || document.activeElement.tagName == 'IFRAME'){// Check if the active element is in the main web or iframe 
     var iframes = document.getElementsByTagName('iframe');// Get iframes 
     for(var i = 0; i<iframes.length; i++){ 
      var focused = getActiveElement(iframes[i].contentWindow.document);// Recall 
      if(focused !== false){ 
       return focused; // The focused 
      } 
     } 
    } 
    else return document.activeElement; 
}; 

(które pierwotnie dostał od siebie tak postu nie może już znaleźć). Wydaje się, że nie mam szczęścia, ponieważ nie ma kości.

Czy istnieje prosty sposób, aby zawsze aktywować aktywny element za pomocą aktywnego kranu na każdej stronie, nawet w oknie komponowania Gmaila i podobnych usług, czy też utknę, tworząc niestandardowy kod dla rosnącej listy serwisów, które mój kod nie może pobrać karetki?

Mój pełny kod jest tutaj. Jest szorstki, a ja po prostu staram się uzyskać to do pracy, więc rozumiem tam niechlujstwa części to, że potrzeba uporządkowany:

function AlertPrevWord() { 
     //var text = document.activeElement; //Fetch the active element on the page, cause that's where the cursor is. 
     var text = getActiveElement(); 
     console.log(text); 
     var caretPos = text.selectionStart;//get the position of the cursor in the element. 
     var word = ReturnWord(text.value, caretPos);//Get the word before the cursor. 
     if (word != null) {//If it's not blank 
      return word //send it back. 
     } 
    } 

    function ReturnWord(text, caretPos) { 
     var index = text.indexOf(caretPos);//get the index of the cursor 
     var preText = text.substring(0, caretPos);//get all the text between the start of the element and the cursor. 
     if (preText.indexOf(" ") > 0) {//if there's more then one space character 
      var words = preText.split(" ");//split the words by space 
      return words[words.length - 1]; //return last word 
     } 
     else {//Otherwise, if there's no space character 
      return preText;//return the word 
     } 
    } 




function getActiveElement(document){ 
    document = document || window.document; 
    if(document.body === document.activeElement || document.activeElement.tagName == 'IFRAME'){// Check if the active element is in the main web or iframe 
     var iframes = document.getElementsByTagName('iframe');// Get iframes 
     for(var i = 0; i<iframes.length; i++){ 
      var focused = getActiveElement(iframes[i].contentWindow.document);// Recall 
      if(focused !== false){ 
       return focused; // The focused 
      } 
     } 
    } 
    else return document.activeElement; 
}; 
+0

Po zidentyfikowaniu ramkę (na przykład poprzez rekurencyjne przetwarzanie ramek tego samego pochodzenia, jak zrobiłeś), można wymienić udział w daszek pomocą logiki „subproblem 2” w tej odpowiedzi: https://stackoverflow.com/questions/28055887/is-there-a-flexible-way-to-modify-the-contents-of-an-editable-element/28198957#28198957 –

Odpowiedz

2

Mam to praca dla okna Gmaila (i prawdopodobnie innych elementów contentEditable raczej niż tylko elementy wejściowe).

Edycja: niepowodzenie wokół linii łamania było spowodowane tym, że polecenie window.getSelection(). AnchorOffset zwraca przesunięcie względem danego elementu, podczas gdy ReturnWord otrzymywał tekst całego okna komponowania (zawierającego wiele elementów). window.getSelection(). anchorNode zwraca węzeł, w którym obliczane jest przesunięcie.

function AlertPrevWord() { 
    var text = getActiveElement(); 
    var caretPos = text.selectionStart || window.getSelection().anchorOffset;   
    var word = ReturnWord(text.value || window.getSelection().anchorNode.textContent, caretPos); 
    if (word != null) {return word;} 
} 

pierwotnie użył MutationObserver aby uwzględnić Gmail komponować dział tworzony po stronie obciążenia, tak aby dołączyć detektor zdarzeń do niego.

var observer = new MutationObserver(function(mutations) { 
    mutations.forEach(function(mutation) { 
    var nodes = mutation.addedNodes; //list of new nodes in the DOM 
    for (var i = 0; i < nodes.length; ++i) { 
     //attach key listener to nodes[i] that calls AlertPrevWord 
    } 
    });  
}); 
observer.observe(document, {childList: true, subtree:true }); 
    //childList:true notifies observer when nodes are added or removed 
    //subtree:true observes all the descendants of document as well 

Edytuj: Delegowany podmiot obsługi kliknięć, z którym testowałem. Kluczowe programy obsługi zdarzeń do tej pory nie działają.

$(document).on("click", ":text,[contenteditable='true']", function(e) { 
    e.stopPropagation(); 
    console.log(AlertPrevWord()); 
}); 
+1

Czy delegowane wydarzenie ograniczyłoby potrzebę MO? – dandavis

+0

Tak, to działa lepiej. Dzięki, nigdy wcześniej nie korzystałem z delegowanych wydarzeń. – ak2ln

+0

Wygląda na to, że działa minimalnie, o ile tylko próbuję uzyskać słowo w pierwszym wierszu wiadomości. Wydaje się, że nie podoba się to, jeśli istnieje druga linia oddzielona przez podział wiersza. Dodatkowo, czy byłbyś w stanie podać jego próbkę współpracując z delegowanym wydarzeniem? To by mnie naprawdę zainteresowało. – HDCerberus