Search code examples
vue.jsselectioncontenteditable

How to work with vue.js and window.getSelection()?


Here is an example from some tutorial:

<p id="p">Example: <i>italic</i> and <b>bold</b></p>

<script>
  let range = new Range();

  range.setStart(p.firstChild, 2);
  range.setEnd(p.querySelector('b').firstChild, 3);

  alert(range); // ample: italic and bol

  // use this range for selection (explained later)
  window.getSelection().addRange(range);
</script>

How to do this with vue?

Should I use query selectors too?

I am interested how to do this selection manipulation within contenteditable. I can use "ref" for contenteditable container but inner content with bold, italic etc. tags is dynamic and mark this code with refs:

... <b><i>some text</i></b> ...

isn't appropriate.


Solution

  • If you're using the Selection API to manipulate the DOM (not just creating ranges, but adding/removing/modifing/reordering DOM nodes), then you should be doing those manipulations on DOM elements not managed by Vue. You must not modify parts of the DOM managed by Vue because Vue won't know about those changes and it will get confused when trying to patch the DOM during the next render cycle. Vue "owns" the rendered DOM of its components.

    This doesn't mean you can't use the Selection API and Vue together, it just means you need to be careful not to tinker in the DOM willy-nilly.

    Should I use query selectors too? Using p.querySelector('b').firstChild isn't vue way but I don't know what should I use insted

    This rule only applies if you want to get a reference to a DOM node rendered by Vue. If the container were content editable, then its contents would not be managed by Vue and you would have no way of referencing its contents without using querySelector and other DOM functions. Try not to get caught up with "am I doing it the Vue-way?" when what you are trying to do is inherently not Vue related anyway.