问题
We have a bug at this CKEditor plugin, and a generic solution is like to this, applying a generic string-filter only to terminal text nodes of the DOM.
QUESTION: how (need code example) to traverse a selection node (editor.getSelection()
) by CKEditor-4 tools, like CKEDITOR.dom.range?
回答1:
First step will be to get ranges from current selection. To do this just call:
var ranges = editor.getSelection().getRanges();
This gives you an array of ranges, because theoretically (and this theory is proved only by Firefox) one selection can contain many ranges. But in 99% of real world cases you can just handle the first one and ignore other. So you've got range
.
Now, the easiest way to iterate over each node in this range is to use CKEDITOR.dom.walker. Use it for example this way:
var walker = new CKEDITOR.dom.walker( range ),
node;
while ( ( node = walker.next() ) ) {
// Log values of every text node in range.
console.log( node.type == CKEDITOR.NODE_TEXT && node.getText() );
}
However, there's a problem with text nodes at the range's boundaries. Consider following range:
<p>[foo<i>bar</i>bo]m</p>
This will log: foo
, bar
, and bom
. Yes - entire bom
, because it is a single node and walker does not modify DOM (there's a bug in documentation).
Therefore you should check every node you want to transform if it equals range's startContainer
or endContainer
and if yes - transform only that part of it which is inside range.
Note: I don't know walker's internals and I'm not sure whether you can modify DOM while iterating over it. I'd recommend first caching nodes and then making changes.
来源:https://stackoverflow.com/questions/18469707/traversing-dom-nodes-in-ckeditor-4