Intussen ben ik ietsje verder gekomen. Wat ik nu doe is door alle childnodes van de selectie heen lopen en <span>-tags om de textnodes zetten.
Toch doet zich nog een vervelend probleem voor. Stel de gebruiker maakt de volgende selectie:
<p>Dit is parag
raaf 1</p><h3>Kopje</h3><p>Dit is paragraaf 2</p>
Dan maakt de functie getRangeAt(0); er het volgende van:
<p>Dit is parag
<p>raaf 1</p><h3>Ko</h3><h3>pje</h3><p>Dit is paragraaf 2</p>
Erg aardig natuurlijk, maar e.e.a. verknald wel mijn opmaak. Zie
deze voorbeeldpagina.
Hoe los ik dit op?
De relevante code is:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
| /* function mark() gives the selection a red background */
function mark()
{
if (window.getSelection)
{
var userSelection = window.getSelection();
var rangeObject = userSelection.getRangeAt(0);;
//extract the selection
oDocumentFragment = rangeObject.extractContents();
//give all textnodes in document fragment a red background
setDomNodeBackgroundColor(oDocumentFragment, 'red');
//re-insert the altered document fragment
rangeObject.insertNode(oDocumentFragment);
}
}
function setDomNodeBackgroundColor(oNode, sColor)
{
/* walk through all childnodes:
- put a <span> around text nodes
- reiterate this function for all other nodes
*/
/* get childnodes */
var aoChildNodes = oNode.childNodes;
var iLength = aoChildNodes.length;
for (i=0; i<iLength; i++)
{
var oChildNode = aoChildNodes[i];
if (oChildNode.nodeType==3)
{
/* childnode is textnode, add span */
setTextNodeBackgroundColor(oChildNode, sColor);
}
else
{
/* childnode is node, use this function again */
setDomNodeBackgroundColor(oChildNode, sColor)
}
}
}
function setTextNodeBackgroundColor(oTextNode, sColor)
{
if (oTextNode.nodeType==3)
{
/* create a span with the same contents as the textnode */
oTextClone = document.createTextNode(oTextNode.data);
oSpan = document.createElement('span');
oSpan.style.backgroundColor = sColor;
oSpan.appendChild(oTextClone);
/* replace the original textnode with the spanified one */
oTextNode.parentNode.replaceChild(oSpan, oTextNode);
}
} |