[JS] selection.createRange() en parentElement() in FF

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • ERIKvanPAASSEN
  • Registratie: September 2006
  • Laatst online: 20-09 10:12
Vandaag is voor mij weer zo'n dag dat je je de haren uit je kop trekt vanwege alle afwijkende 'javascript'-implementaties in de verschillende browsers. |:( Ik ben bezig met een WYSIWYG-editor m.b.v. een IFrame met designMode='on'.

Daarin wil ik van de huidige selectie in de editor controleren of deze zich in een link bevindt en zo ja, de href- en target-attributen uitlezen en kunnen beïnvloeden:
JavaScript:
1
2
3
4
5
6
sText = document.getElementById(activeEditor).contentWindow.document.selection.createRange();
if (sText.parentElement().tagName == "A") {
    // Is een link, nu kan ik met sText.parentElement().href en sText.parentElement().target aan de haal.
} else {
    // Is geen link.
}


Dit werkt precies zoals het moet in Internet Explorer. In Firefox werkt dit echter niet.
Na wat zoekwerk stuitte ik hierop:Nu heb ik m'n code javascript aangepast naar:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if (document.selection) {
    // IE.

    sText = document.getElementById(activeEditor).contentWindow.document.selection.createRange();
    if (sText.parentElement().tagName == "A") {
        // Is een link, nu kan ik met sText.parentElement().href en sText.parentElement().target aan de haal.
    } else {
        // Is geen link.
    }
} else {
    // Geen IE, bijv. Firefox.

    sText = document.getElementById(activeEditor).contentWindow.getSelection();
    if (sText.anchorNode.nodeName == "A") {
        // Is een link, nu kan ik met sText.anchorNode.href en sText.anchorNode.target aan de haal?
    } else {
        // Is geen link.
    }
}


Er is nu alleen een probleem:
De anchorNode-property doet niet wat ik verwacht, maar dat ligt ongetwijfeld aan mij ;) .
anchorNode
Returns the node in which the selection begins.

Mozilla Developer Center
Als ik nu van een selectie binnen <a>...</a> vraag wat .anchorNode.nodeName is, laat Firefox mij weten dat het een Text Node betreft, en dus geen Element is (zie spec. van nodeName), terwijl ik dus een A-element zou verwachten.

Hoe kan ik dit oplossen?

En ja, ik ken FCKEditor, TinyMCE, maar ik ben eigenwijs en wil graag het wiel opnieuw uitvinden.
Laten we het er maar even op houden dat ik daar een goede reden voor heb. ;)

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 23:57

crisp

Devver

Pixelated

zoiets misschien?
JavaScript:
1
2
3
var anchorNode = sText.anchorNode;
while (anchorNode.nodeType != 1)
    anchorNode = anchorNode.parentNode;

[ Voor 4% gewijzigd door crisp op 16-12-2008 00:18 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • ERIKvanPAASSEN
  • Registratie: September 2006
  • Laatst online: 20-09 10:12
En dan blijkt het toch zo simpel te zijn. |:( Dat kon ik dus nergens vinden.
Morgen ga ik 't even wat uitgebreider testen, maar ik denk dat ik er zo wel uitkom.

Alvast erg bedankt! _/-\o_

Acties:
  • 0 Henk 'm!

Verwijderd

Houd er wel rekening mee dat de anchorNode property van het Selection object in FF verwijst naar de node waar de selectie in begint, terwijl parentElement() in IE verwijst naar het element waar de complete selectie zich in bevindt. Je merkt het verschil zodra je ook een paar letters achter de link selecteert.

Wanneer je in IE wilt weten binnen welk element de selectie begint, zou je de opgevraagde range kunnen collapsen naar het begin. De parentElement() method van deze collapsed range verwijst dan naar het element waar de selectie in begint.

Je kunt in FF de diepste container van de gehele selectie opvragen via sText.getRangeAt(0).commonAncestorContainer. Dit kan overigens ook weer een tekst node zijn (net als bij anchorNode).

Vergeet ook niet dat selection.createRange() in IE ook een control range kan retourneren. Dit type range heeft niet eens een parentElement() method.

  • ERIKvanPAASSEN
  • Registratie: September 2006
  • Laatst online: 20-09 10:12
Oké, heel erg bedankt voor de handige tips! Zodra ik er tijd voor heb, ga ik dit alles uitproberen.