Chrome Extension contenteditable obțineți și setați poziția de îngrijire

Working with the DOM in a Google extension

Creez o extensie Google Chrome în care trebuie să introduc o legătură într-o fereastră gmail . Sunt capabil să creez un simplu buton de extensie în partea superioară a ferestrei și să execut cod care înlocuiește elementele din documentul de e-mail.

Acum, vreau să adaug adăugarea de linkuri în secțiunea contenționabilă pe măsură ce scriu. Se pare că ar trebui să existe o modalitate simplă de a înlocui textul cu un link în modelul obiect de documente javascript. De asemenea, acest lucru trebuie doar să funcționeze pentru crom, deoarece nu intenționez să scriu o versiune firefox sau o versiune mai curând.

Originally I was trying to do the following:

  1. Introduceți textul din poziția actuală de îngrijire
  2. Capturăți poziția de îngrijire.
  3. Setați poziția orificiului prin decalajul acesteia.

getSelection, nu atât de repede

Am încercat să folosesc window.getSelection în contextul gmail (adică un element corporal setat la contenteditable și încorporat într-o iframe în fila gmail) pentru a obține intervalul și poziția actuale. Selecția a fost întotdeauna goală și nu conținea niciun interval, indiferent dacă textul a fost selectat sau nu.

Am constatat că motivul pentru care codul getSelection nu a funcționat a fost că a fost selectat document.getSelection în fereastra greșită. Există 5 iframe (ferestre) disponibile atunci când creați un mesaj nou în gmail. Există unul numit adânc în interiorul acestui cadru este iframe-ul care trebuie apelat getSelection pentru a obține selecția corectă a textului. Iată câteva coduri care vă vor permite să obțineți poziția de îngrijire selectată în zona contenționabilă pentru mesajul dvs. de e-mail.

Aceasta este o modalitate de a obține selecția pentru fereastra pentru documente Gmail

var mySelection = $("iframe")[4].contentDocument.
    querySelector("iframe").contentDocument.getSelection();

Prima încercare de înlocuire a textului

Acum am ajuns, sperăm, puțin mai aproape de o soluție. Ne pare rău dacă este neclintit Nu găsesc nicio documentație bună despre cum să scrieți acest cod.

// Select the keyword
var range = s.getRangeAt(0);
var keyEl = range.startContainer.splitText(index);
var newRange = doc.createRange();
newRange.selectNode(keyEl);
s.removeAllRanges();
newRange.setEnd(keyEl, length);
s.addRange(newRange);

// Insert the link
var newLink = document.createElement("a");
newLink.setAttribute("href", value);
s.removeAllRanges();
newRange.surroundContents(newLink);

// Set the position
newRange.setStartAfter(newLink);
newRange.collapse(true);
s.addRange(newRange);

Acest lucru funcționează aproape perfect, dar problema este că textul caret se află în interiorul link-ului, astfel încât orice text scris după ce este inserat în legătură. Aceasta este o mare problemă. Și, încercând câteva lucruri, am reușit să fac ca problema să dispară parțial. O nouă problemă care a fost similară a condus la unele linkuri ciudate care s-au extins la următoarele cuvinte, dar numai pentru câteva caractere.

Sperăm că încercarea finală de înlocuire a textului

// find position in text 
var index = s.focusNode.data.search(keyword);
var length = keyword.length;

var range = s.getRangeAt(0);
var keyEl = range.startContainer.splitText(index);
var newRange = doc.createRange();
newRange.selectNode(keyEl);
s.removeAllRanges();
newRange.setEnd(keyEl, length);
s.addRange(newRange);

var newLink = document.createElement("a");
newLink.setAttribute("href", value);
$(newLink).css("text-decoration", "none");
$(newLink).css("cursor", "pointer");
$(newLink).css("color", "color:#3366FF");
newRange.surroundContents(newLink);
newRange.collapse(false);
s.removeAllRanges();
s.addRange(newRange);

A existat o problemă care părea a fi omniprezentă în numeroasele mele încercări care au dispărut acum. Acest lucru a făcut niște legături ciudate care s-au extins la următoarele cuvinte.

Feel free to help me clean up the code to make it more succinct

2
Sperăm că acest lucru este puțin mai clar și urmează normele pe care le rup despre scrierea unui post.
adăugat autor jwize, sursa

1 răspunsuri

Dacă știți exact poziția în care doriți să inserați cartea, trebuie să o faceți:

var node = someTextNode;
var caret = 10;//insert caret after the 10th character
var range = document.createRange();
range.setStart(node,caret);
range.setEnd(node,caret);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);

Acest lucru funcționează totuși numai pe nodurile text DOM. Deci, dacă doriți să manipulați conținutul unui div contenteditable sau similar, va trebui să faceți plimbări recursiv prin elementele copilului său și să verificați nodurile de text.

I recently wrote a Chrome extension that does text replacement on websites including GMail - here's the source of the corresponding jQuery plugin, feel free do exploit it if it fits your use case: https://github.com/squidpeople/ASCIImoji/blob/master/asciimoji.jquery.js

0
adăugat
JavaScript, România - Moldova
JavaScript, România - Moldova
328 participanți

Comunitatea Română JavaScript: github.com/js-ro Pentru confort, opriți notificările. Parteneri: @node_ro, @php_ro, @python_ro, @seo_ro, @RomaniaGroup, @ai_ro, @Grupuri_IT Offtop: @holywars_ro Joburi: @js_jobs_ro Sponsored with ❤️ by ciupacabra.com