2015-07-14 10 views
6

Ich bin ein Teilzeit newish Entwickler arbeiten an einer Chrome-Erweiterung, die als ein internes CR-Tool arbeiten soll.Suchen Sie Caret Position Anywhere auf Seite

Das Konzept ist einfach, auf einer Tastenkombination, die Erweiterung erhält das Wort neben dem Caret, überprüft es für eine Musterübereinstimmung, und wenn die Übereinstimmung 'true' ersetzt das Wort mit einer vordefinierten Antwort.

Um dies zu tun, habe ich meist eine modifizierte Version von this answer verwendet.

Ich habe einen Roadblock in diesem mit dem funktioniert für das aktive Element getroffen, aber es scheint nicht für Dinge wie das "Verfassen" -Fenster in Chrome oder konsequent über andere Dienste (Salesforce scheint auch zu funktionieren nicht wie es zum Beispiel). Stossen über ein wenig dachte ich, das könnte ein Problem mit iFrames, also bastelte ich ein bisschen und verändert diesen Frieden Code:

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

(Was ich von einem anderen ursprünglich so bekam ich Post nicht mehr finden kann). Es scheint, als hätte ich kein Glück, wie kein Würfel.

Gibt es eine einfache Möglichkeit, immer das aktive Element mit dem aktiven Caret auf jeder Seite zu erhalten, sogar für das Gmail-Verfassen-Fenster und ähnliche Dienste, oder werde ich für eine wachsende Liste von Diensten diesen Code schreiben Mein Code kann den Caret nicht abrufen?

Mein voller Code ist hier. Es ist rau, während ich nur versuchen, diese Arbeit zu bekommen, so verstehe ich es schlampig Teile davon, dass Bedarf aufräumte:

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

Nachdem der Rahmen zu identifizieren (zB durch rekursiv Same-Origin-Frames verarbeiten, wie Sie getan haben), können Sie das Teil an der caret mit der Logik der „Subproblem 2“ in dieser Antwort ersetzen: https://stackoverflow.com/questions/28055887/is-there-a-flexible-way-to-modify-the-contents-of-an-editable-element/28198957#28198957 –

Antwort

2

ich habe arbeiten sie für das Google Mail-Fenster (und vermutlich andere contenteditable Elemente, eher als nur Eingabeelemente).

Bearbeiten: Der Fehler um Zeilenumbrüche war, weil window.getSelection(). AnchorOffset den Offset relativ zu diesem bestimmten Element zurückgibt, während ReturnWord den Text des gesamten Compose-Fensters (das mehrere Elemente enthielt) übergeben wurde. window.getSelection(). anchorNode gibt den Knoten zurück, in dem der Offset berechnet wird.

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

habe ich ursprünglich einen MutationObserver für den Google Mail zusammenstellen zu berücksichtigen div nach dem Laden der Seite erstellt wird, nur ein Ereignis-Listener, um es zu befestigen.

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 

Bearbeiten: Der delegierte Click-Handler, mit dem ich getestet habe. Wichtige Ereignishandler funktionieren bisher nicht.

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

würde ein delegiertes Ereignis die Notwendigkeit für eine MO einschränken? – dandavis

+0

Ja, das funktioniert viel besser. Danke, ich habe noch nie zuvor delegierte Ereignisse verwendet. – ak2ln

+0

Dies scheint minimal zu funktionieren, solange ich nur versuche, ein Wort in die erste Zeile der Nachricht zu bekommen. Es scheint nicht zu mögen, wenn eine zweite Zeile durch einen Zeilenumbruch getrennt ist. Könnten Sie außerdem ein Beispiel dafür bereitstellen, das mit einem delegierten Ereignis arbeitet? Das würde mich wirklich interessieren. – HDCerberus

Verwandte Themen