TinyMCE: Programmatically select word at caret position












0















How can I modify the current selection from tinyMCE 4 so that it can be extended to the current word's boundary?



Say the caret is at the position represented below. How can I force tinyMCE to select the 'test' word?




This is a t|est




I suspect that may to use the browser's Range object, but I'm not sure how to do this



My end goal is that when I trigger a custom action from a button, it applies to either the selection (if there is one), or to the word containing the caret position. Basically, same behaviour at when you click the Bold button










share|improve this question



























    0















    How can I modify the current selection from tinyMCE 4 so that it can be extended to the current word's boundary?



    Say the caret is at the position represented below. How can I force tinyMCE to select the 'test' word?




    This is a t|est




    I suspect that may to use the browser's Range object, but I'm not sure how to do this



    My end goal is that when I trigger a custom action from a button, it applies to either the selection (if there is one), or to the word containing the caret position. Basically, same behaviour at when you click the Bold button










    share|improve this question

























      0












      0








      0








      How can I modify the current selection from tinyMCE 4 so that it can be extended to the current word's boundary?



      Say the caret is at the position represented below. How can I force tinyMCE to select the 'test' word?




      This is a t|est




      I suspect that may to use the browser's Range object, but I'm not sure how to do this



      My end goal is that when I trigger a custom action from a button, it applies to either the selection (if there is one), or to the word containing the caret position. Basically, same behaviour at when you click the Bold button










      share|improve this question














      How can I modify the current selection from tinyMCE 4 so that it can be extended to the current word's boundary?



      Say the caret is at the position represented below. How can I force tinyMCE to select the 'test' word?




      This is a t|est




      I suspect that may to use the browser's Range object, but I'm not sure how to do this



      My end goal is that when I trigger a custom action from a button, it applies to either the selection (if there is one), or to the word containing the caret position. Basically, same behaviour at when you click the Bold button







      javascript tinymce






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 22 '18 at 9:31









      DavidDavid

      10.9k63451




      10.9k63451
























          1 Answer
          1






          active

          oldest

          votes


















          1





          +50









          I suppose that you already have the fundamentals of how to add a button to the TinyMCE and how to call a function and all that. So I'm only going to answer the 'how to mark the work at caret position?' part.



          If the editable content is a textarea, use this:






          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let textUntilCaret = this.textContent.substr(0, this.selectionStart)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = this.textContent.substr(this.selectionStart)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          this.selectionStart = textUntilCaret.length
          this.selectionEnd = this.textContent.length - textFromCaret.length
          }

          function startWordAtPosition() {

          }

          })();

          Click in the textarea and the whole word will be selected!<br>
          <textarea name="" id="ex" cols="50" rows="10">Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus aliquam magni molestias et, nihil asperiores obcaecati dolores sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut. Suscipit, architecto perferendis. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</textarea>





          If the editable content is a div with attribute contenteditable set, use this:
          It even works with child elements and mixed text nodes and child element:
          This does not work in MSIE11 and below,






          console.clear();
          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let caretPosition = getCaretPosition(evt.target);
          let caretNode = getCaretTextNode(evt);

          let textUntilCaret = caretNode.textContent.substr(0, caretPosition)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = caretNode.textContent.substr(caretPosition)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          selectRange(caretNode, textUntilCaret.length, caretNode.textContent.length - textFromCaret.length)
          }

          function selectRange(node, start, end) {
          // console.log(node, start, end)
          let range = document.createRange()
          range.selectNodeContents(node)
          range.setStart(node, start)
          range.setEnd(node, end)

          selection = window.getSelection();
          selection.removeAllRanges();
          selection.addRange(range);
          }

          function getCaretTextNode(evt) {
          var range, textNode
          // standard
          if (document.caretPositionFromPoint) {
          range = document.caretPositionFromPoint(evt.pageX, evt.pageY);
          textNode = range.offsetNode;
          // WebKit
          } else if (document.caretRangeFromPoint) {
          range = document.caretRangeFromPoint(evt.pageX, evt.pageY);
          textNode = range.startContainer;
          } else if (document.body.createTextRange) {
          // range = document.body.createTextRange();
          // range.moveToPoint(evt.pageX, evt.pageY);
          // range.select();
          var sel = document.getSelection()
          textNode = sel.focusNode
          }
          return textNode;
          }

          function getCaretPosition(editableDiv) {
          var caretPos = 0,
          sel, range;
          if (window.getSelection) {
          sel = window.getSelection();
          if (sel.rangeCount) {
          range = sel.getRangeAt(0);
          if (range.commonAncestorContainer.parentNode == editableDiv) {
          caretPos = range.endOffset;
          }
          }
          } else if (document.selection && document.selection.createRange) {
          range = document.selection.createRange();
          if (range.parentElement() == editableDiv) {
          var tempEl = document.createElement("span");
          editableDiv.insertBefore(tempEl, editableDiv.firstChild);
          var tempRange = range.duplicate();
          tempRange.moveToElementText(tempEl);
          tempRange.setEndPoint("EndToEnd", range);
          caretPos = tempRange.text.length;
          }
          }
          return caretPos;
          }


          })();

          <div contenteditable id="ex">Lorem   ipsum dolor <b>sit amet</b> consectetur <em>adipisicing</em> elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus <span>aliquam magni molestias et, nihil asperiores obcaecati dolores </span>sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut.   Suscipit, <span>architecto perferendis</span>. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias   repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam   dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</div>








          share|improve this answer


























          • These do not work, if the page is scrolled.

            – HerrSerker
            Nov 28 '18 at 9:55











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53427728%2ftinymce-programmatically-select-word-at-caret-position%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1





          +50









          I suppose that you already have the fundamentals of how to add a button to the TinyMCE and how to call a function and all that. So I'm only going to answer the 'how to mark the work at caret position?' part.



          If the editable content is a textarea, use this:






          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let textUntilCaret = this.textContent.substr(0, this.selectionStart)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = this.textContent.substr(this.selectionStart)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          this.selectionStart = textUntilCaret.length
          this.selectionEnd = this.textContent.length - textFromCaret.length
          }

          function startWordAtPosition() {

          }

          })();

          Click in the textarea and the whole word will be selected!<br>
          <textarea name="" id="ex" cols="50" rows="10">Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus aliquam magni molestias et, nihil asperiores obcaecati dolores sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut. Suscipit, architecto perferendis. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</textarea>





          If the editable content is a div with attribute contenteditable set, use this:
          It even works with child elements and mixed text nodes and child element:
          This does not work in MSIE11 and below,






          console.clear();
          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let caretPosition = getCaretPosition(evt.target);
          let caretNode = getCaretTextNode(evt);

          let textUntilCaret = caretNode.textContent.substr(0, caretPosition)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = caretNode.textContent.substr(caretPosition)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          selectRange(caretNode, textUntilCaret.length, caretNode.textContent.length - textFromCaret.length)
          }

          function selectRange(node, start, end) {
          // console.log(node, start, end)
          let range = document.createRange()
          range.selectNodeContents(node)
          range.setStart(node, start)
          range.setEnd(node, end)

          selection = window.getSelection();
          selection.removeAllRanges();
          selection.addRange(range);
          }

          function getCaretTextNode(evt) {
          var range, textNode
          // standard
          if (document.caretPositionFromPoint) {
          range = document.caretPositionFromPoint(evt.pageX, evt.pageY);
          textNode = range.offsetNode;
          // WebKit
          } else if (document.caretRangeFromPoint) {
          range = document.caretRangeFromPoint(evt.pageX, evt.pageY);
          textNode = range.startContainer;
          } else if (document.body.createTextRange) {
          // range = document.body.createTextRange();
          // range.moveToPoint(evt.pageX, evt.pageY);
          // range.select();
          var sel = document.getSelection()
          textNode = sel.focusNode
          }
          return textNode;
          }

          function getCaretPosition(editableDiv) {
          var caretPos = 0,
          sel, range;
          if (window.getSelection) {
          sel = window.getSelection();
          if (sel.rangeCount) {
          range = sel.getRangeAt(0);
          if (range.commonAncestorContainer.parentNode == editableDiv) {
          caretPos = range.endOffset;
          }
          }
          } else if (document.selection && document.selection.createRange) {
          range = document.selection.createRange();
          if (range.parentElement() == editableDiv) {
          var tempEl = document.createElement("span");
          editableDiv.insertBefore(tempEl, editableDiv.firstChild);
          var tempRange = range.duplicate();
          tempRange.moveToElementText(tempEl);
          tempRange.setEndPoint("EndToEnd", range);
          caretPos = tempRange.text.length;
          }
          }
          return caretPos;
          }


          })();

          <div contenteditable id="ex">Lorem   ipsum dolor <b>sit amet</b> consectetur <em>adipisicing</em> elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus <span>aliquam magni molestias et, nihil asperiores obcaecati dolores </span>sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut.   Suscipit, <span>architecto perferendis</span>. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias   repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam   dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</div>








          share|improve this answer


























          • These do not work, if the page is scrolled.

            – HerrSerker
            Nov 28 '18 at 9:55
















          1





          +50









          I suppose that you already have the fundamentals of how to add a button to the TinyMCE and how to call a function and all that. So I'm only going to answer the 'how to mark the work at caret position?' part.



          If the editable content is a textarea, use this:






          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let textUntilCaret = this.textContent.substr(0, this.selectionStart)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = this.textContent.substr(this.selectionStart)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          this.selectionStart = textUntilCaret.length
          this.selectionEnd = this.textContent.length - textFromCaret.length
          }

          function startWordAtPosition() {

          }

          })();

          Click in the textarea and the whole word will be selected!<br>
          <textarea name="" id="ex" cols="50" rows="10">Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus aliquam magni molestias et, nihil asperiores obcaecati dolores sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut. Suscipit, architecto perferendis. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</textarea>





          If the editable content is a div with attribute contenteditable set, use this:
          It even works with child elements and mixed text nodes and child element:
          This does not work in MSIE11 and below,






          console.clear();
          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let caretPosition = getCaretPosition(evt.target);
          let caretNode = getCaretTextNode(evt);

          let textUntilCaret = caretNode.textContent.substr(0, caretPosition)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = caretNode.textContent.substr(caretPosition)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          selectRange(caretNode, textUntilCaret.length, caretNode.textContent.length - textFromCaret.length)
          }

          function selectRange(node, start, end) {
          // console.log(node, start, end)
          let range = document.createRange()
          range.selectNodeContents(node)
          range.setStart(node, start)
          range.setEnd(node, end)

          selection = window.getSelection();
          selection.removeAllRanges();
          selection.addRange(range);
          }

          function getCaretTextNode(evt) {
          var range, textNode
          // standard
          if (document.caretPositionFromPoint) {
          range = document.caretPositionFromPoint(evt.pageX, evt.pageY);
          textNode = range.offsetNode;
          // WebKit
          } else if (document.caretRangeFromPoint) {
          range = document.caretRangeFromPoint(evt.pageX, evt.pageY);
          textNode = range.startContainer;
          } else if (document.body.createTextRange) {
          // range = document.body.createTextRange();
          // range.moveToPoint(evt.pageX, evt.pageY);
          // range.select();
          var sel = document.getSelection()
          textNode = sel.focusNode
          }
          return textNode;
          }

          function getCaretPosition(editableDiv) {
          var caretPos = 0,
          sel, range;
          if (window.getSelection) {
          sel = window.getSelection();
          if (sel.rangeCount) {
          range = sel.getRangeAt(0);
          if (range.commonAncestorContainer.parentNode == editableDiv) {
          caretPos = range.endOffset;
          }
          }
          } else if (document.selection && document.selection.createRange) {
          range = document.selection.createRange();
          if (range.parentElement() == editableDiv) {
          var tempEl = document.createElement("span");
          editableDiv.insertBefore(tempEl, editableDiv.firstChild);
          var tempRange = range.duplicate();
          tempRange.moveToElementText(tempEl);
          tempRange.setEndPoint("EndToEnd", range);
          caretPos = tempRange.text.length;
          }
          }
          return caretPos;
          }


          })();

          <div contenteditable id="ex">Lorem   ipsum dolor <b>sit amet</b> consectetur <em>adipisicing</em> elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus <span>aliquam magni molestias et, nihil asperiores obcaecati dolores </span>sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut.   Suscipit, <span>architecto perferendis</span>. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias   repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam   dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</div>








          share|improve this answer


























          • These do not work, if the page is scrolled.

            – HerrSerker
            Nov 28 '18 at 9:55














          1





          +50







          1





          +50



          1




          +50





          I suppose that you already have the fundamentals of how to add a button to the TinyMCE and how to call a function and all that. So I'm only going to answer the 'how to mark the work at caret position?' part.



          If the editable content is a textarea, use this:






          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let textUntilCaret = this.textContent.substr(0, this.selectionStart)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = this.textContent.substr(this.selectionStart)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          this.selectionStart = textUntilCaret.length
          this.selectionEnd = this.textContent.length - textFromCaret.length
          }

          function startWordAtPosition() {

          }

          })();

          Click in the textarea and the whole word will be selected!<br>
          <textarea name="" id="ex" cols="50" rows="10">Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus aliquam magni molestias et, nihil asperiores obcaecati dolores sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut. Suscipit, architecto perferendis. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</textarea>





          If the editable content is a div with attribute contenteditable set, use this:
          It even works with child elements and mixed text nodes and child element:
          This does not work in MSIE11 and below,






          console.clear();
          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let caretPosition = getCaretPosition(evt.target);
          let caretNode = getCaretTextNode(evt);

          let textUntilCaret = caretNode.textContent.substr(0, caretPosition)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = caretNode.textContent.substr(caretPosition)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          selectRange(caretNode, textUntilCaret.length, caretNode.textContent.length - textFromCaret.length)
          }

          function selectRange(node, start, end) {
          // console.log(node, start, end)
          let range = document.createRange()
          range.selectNodeContents(node)
          range.setStart(node, start)
          range.setEnd(node, end)

          selection = window.getSelection();
          selection.removeAllRanges();
          selection.addRange(range);
          }

          function getCaretTextNode(evt) {
          var range, textNode
          // standard
          if (document.caretPositionFromPoint) {
          range = document.caretPositionFromPoint(evt.pageX, evt.pageY);
          textNode = range.offsetNode;
          // WebKit
          } else if (document.caretRangeFromPoint) {
          range = document.caretRangeFromPoint(evt.pageX, evt.pageY);
          textNode = range.startContainer;
          } else if (document.body.createTextRange) {
          // range = document.body.createTextRange();
          // range.moveToPoint(evt.pageX, evt.pageY);
          // range.select();
          var sel = document.getSelection()
          textNode = sel.focusNode
          }
          return textNode;
          }

          function getCaretPosition(editableDiv) {
          var caretPos = 0,
          sel, range;
          if (window.getSelection) {
          sel = window.getSelection();
          if (sel.rangeCount) {
          range = sel.getRangeAt(0);
          if (range.commonAncestorContainer.parentNode == editableDiv) {
          caretPos = range.endOffset;
          }
          }
          } else if (document.selection && document.selection.createRange) {
          range = document.selection.createRange();
          if (range.parentElement() == editableDiv) {
          var tempEl = document.createElement("span");
          editableDiv.insertBefore(tempEl, editableDiv.firstChild);
          var tempRange = range.duplicate();
          tempRange.moveToElementText(tempEl);
          tempRange.setEndPoint("EndToEnd", range);
          caretPos = tempRange.text.length;
          }
          }
          return caretPos;
          }


          })();

          <div contenteditable id="ex">Lorem   ipsum dolor <b>sit amet</b> consectetur <em>adipisicing</em> elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus <span>aliquam magni molestias et, nihil asperiores obcaecati dolores </span>sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut.   Suscipit, <span>architecto perferendis</span>. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias   repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam   dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</div>








          share|improve this answer















          I suppose that you already have the fundamentals of how to add a button to the TinyMCE and how to call a function and all that. So I'm only going to answer the 'how to mark the work at caret position?' part.



          If the editable content is a textarea, use this:






          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let textUntilCaret = this.textContent.substr(0, this.selectionStart)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = this.textContent.substr(this.selectionStart)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          this.selectionStart = textUntilCaret.length
          this.selectionEnd = this.textContent.length - textFromCaret.length
          }

          function startWordAtPosition() {

          }

          })();

          Click in the textarea and the whole word will be selected!<br>
          <textarea name="" id="ex" cols="50" rows="10">Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus aliquam magni molestias et, nihil asperiores obcaecati dolores sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut. Suscipit, architecto perferendis. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</textarea>





          If the editable content is a div with attribute contenteditable set, use this:
          It even works with child elements and mixed text nodes and child element:
          This does not work in MSIE11 and below,






          console.clear();
          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let caretPosition = getCaretPosition(evt.target);
          let caretNode = getCaretTextNode(evt);

          let textUntilCaret = caretNode.textContent.substr(0, caretPosition)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = caretNode.textContent.substr(caretPosition)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          selectRange(caretNode, textUntilCaret.length, caretNode.textContent.length - textFromCaret.length)
          }

          function selectRange(node, start, end) {
          // console.log(node, start, end)
          let range = document.createRange()
          range.selectNodeContents(node)
          range.setStart(node, start)
          range.setEnd(node, end)

          selection = window.getSelection();
          selection.removeAllRanges();
          selection.addRange(range);
          }

          function getCaretTextNode(evt) {
          var range, textNode
          // standard
          if (document.caretPositionFromPoint) {
          range = document.caretPositionFromPoint(evt.pageX, evt.pageY);
          textNode = range.offsetNode;
          // WebKit
          } else if (document.caretRangeFromPoint) {
          range = document.caretRangeFromPoint(evt.pageX, evt.pageY);
          textNode = range.startContainer;
          } else if (document.body.createTextRange) {
          // range = document.body.createTextRange();
          // range.moveToPoint(evt.pageX, evt.pageY);
          // range.select();
          var sel = document.getSelection()
          textNode = sel.focusNode
          }
          return textNode;
          }

          function getCaretPosition(editableDiv) {
          var caretPos = 0,
          sel, range;
          if (window.getSelection) {
          sel = window.getSelection();
          if (sel.rangeCount) {
          range = sel.getRangeAt(0);
          if (range.commonAncestorContainer.parentNode == editableDiv) {
          caretPos = range.endOffset;
          }
          }
          } else if (document.selection && document.selection.createRange) {
          range = document.selection.createRange();
          if (range.parentElement() == editableDiv) {
          var tempEl = document.createElement("span");
          editableDiv.insertBefore(tempEl, editableDiv.firstChild);
          var tempRange = range.duplicate();
          tempRange.moveToElementText(tempEl);
          tempRange.setEndPoint("EndToEnd", range);
          caretPos = tempRange.text.length;
          }
          }
          return caretPos;
          }


          })();

          <div contenteditable id="ex">Lorem   ipsum dolor <b>sit amet</b> consectetur <em>adipisicing</em> elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus <span>aliquam magni molestias et, nihil asperiores obcaecati dolores </span>sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut.   Suscipit, <span>architecto perferendis</span>. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias   repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam   dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</div>








          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let textUntilCaret = this.textContent.substr(0, this.selectionStart)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = this.textContent.substr(this.selectionStart)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          this.selectionStart = textUntilCaret.length
          this.selectionEnd = this.textContent.length - textFromCaret.length
          }

          function startWordAtPosition() {

          }

          })();

          Click in the textarea and the whole word will be selected!<br>
          <textarea name="" id="ex" cols="50" rows="10">Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus aliquam magni molestias et, nihil asperiores obcaecati dolores sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut. Suscipit, architecto perferendis. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</textarea>





          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let textUntilCaret = this.textContent.substr(0, this.selectionStart)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = this.textContent.substr(this.selectionStart)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          this.selectionStart = textUntilCaret.length
          this.selectionEnd = this.textContent.length - textFromCaret.length
          }

          function startWordAtPosition() {

          }

          })();

          Click in the textarea and the whole word will be selected!<br>
          <textarea name="" id="ex" cols="50" rows="10">Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus aliquam magni molestias et, nihil asperiores obcaecati dolores sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut. Suscipit, architecto perferendis. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</textarea>





          console.clear();
          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let caretPosition = getCaretPosition(evt.target);
          let caretNode = getCaretTextNode(evt);

          let textUntilCaret = caretNode.textContent.substr(0, caretPosition)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = caretNode.textContent.substr(caretPosition)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          selectRange(caretNode, textUntilCaret.length, caretNode.textContent.length - textFromCaret.length)
          }

          function selectRange(node, start, end) {
          // console.log(node, start, end)
          let range = document.createRange()
          range.selectNodeContents(node)
          range.setStart(node, start)
          range.setEnd(node, end)

          selection = window.getSelection();
          selection.removeAllRanges();
          selection.addRange(range);
          }

          function getCaretTextNode(evt) {
          var range, textNode
          // standard
          if (document.caretPositionFromPoint) {
          range = document.caretPositionFromPoint(evt.pageX, evt.pageY);
          textNode = range.offsetNode;
          // WebKit
          } else if (document.caretRangeFromPoint) {
          range = document.caretRangeFromPoint(evt.pageX, evt.pageY);
          textNode = range.startContainer;
          } else if (document.body.createTextRange) {
          // range = document.body.createTextRange();
          // range.moveToPoint(evt.pageX, evt.pageY);
          // range.select();
          var sel = document.getSelection()
          textNode = sel.focusNode
          }
          return textNode;
          }

          function getCaretPosition(editableDiv) {
          var caretPos = 0,
          sel, range;
          if (window.getSelection) {
          sel = window.getSelection();
          if (sel.rangeCount) {
          range = sel.getRangeAt(0);
          if (range.commonAncestorContainer.parentNode == editableDiv) {
          caretPos = range.endOffset;
          }
          }
          } else if (document.selection && document.selection.createRange) {
          range = document.selection.createRange();
          if (range.parentElement() == editableDiv) {
          var tempEl = document.createElement("span");
          editableDiv.insertBefore(tempEl, editableDiv.firstChild);
          var tempRange = range.duplicate();
          tempRange.moveToElementText(tempEl);
          tempRange.setEndPoint("EndToEnd", range);
          caretPos = tempRange.text.length;
          }
          }
          return caretPos;
          }


          })();

          <div contenteditable id="ex">Lorem   ipsum dolor <b>sit amet</b> consectetur <em>adipisicing</em> elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus <span>aliquam magni molestias et, nihil asperiores obcaecati dolores </span>sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut.   Suscipit, <span>architecto perferendis</span>. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias   repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam   dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</div>





          console.clear();
          ;(function() {
          var position

          var elem = document.getElementById('ex')
          elem.addEventListener('click', renderClick)

          function renderClick(evt) {
          let caretPosition = getCaretPosition(evt.target);
          let caretNode = getCaretTextNode(evt);

          let textUntilCaret = caretNode.textContent.substr(0, caretPosition)
          textUntilCaret = textUntilCaret.replace(/w+$/, '')

          let textFromCaret = caretNode.textContent.substr(caretPosition)
          textFromCaret = textFromCaret.replace(/^w+/, '')

          selectRange(caretNode, textUntilCaret.length, caretNode.textContent.length - textFromCaret.length)
          }

          function selectRange(node, start, end) {
          // console.log(node, start, end)
          let range = document.createRange()
          range.selectNodeContents(node)
          range.setStart(node, start)
          range.setEnd(node, end)

          selection = window.getSelection();
          selection.removeAllRanges();
          selection.addRange(range);
          }

          function getCaretTextNode(evt) {
          var range, textNode
          // standard
          if (document.caretPositionFromPoint) {
          range = document.caretPositionFromPoint(evt.pageX, evt.pageY);
          textNode = range.offsetNode;
          // WebKit
          } else if (document.caretRangeFromPoint) {
          range = document.caretRangeFromPoint(evt.pageX, evt.pageY);
          textNode = range.startContainer;
          } else if (document.body.createTextRange) {
          // range = document.body.createTextRange();
          // range.moveToPoint(evt.pageX, evt.pageY);
          // range.select();
          var sel = document.getSelection()
          textNode = sel.focusNode
          }
          return textNode;
          }

          function getCaretPosition(editableDiv) {
          var caretPos = 0,
          sel, range;
          if (window.getSelection) {
          sel = window.getSelection();
          if (sel.rangeCount) {
          range = sel.getRangeAt(0);
          if (range.commonAncestorContainer.parentNode == editableDiv) {
          caretPos = range.endOffset;
          }
          }
          } else if (document.selection && document.selection.createRange) {
          range = document.selection.createRange();
          if (range.parentElement() == editableDiv) {
          var tempEl = document.createElement("span");
          editableDiv.insertBefore(tempEl, editableDiv.firstChild);
          var tempRange = range.duplicate();
          tempRange.moveToElementText(tempEl);
          tempRange.setEndPoint("EndToEnd", range);
          caretPos = tempRange.text.length;
          }
          }
          return caretPos;
          }


          })();

          <div contenteditable id="ex">Lorem   ipsum dolor <b>sit amet</b> consectetur <em>adipisicing</em> elit. Itaque, officiis et reiciendis maxime ipsam doloribus quo inventore animi voluptatibus maiores eligendi, corrupti cum placeat nobis possimus exercitationem ratione aut. Explicabo deserunt eum natus id laudantium repellendus <span>aliquam magni molestias et, nihil asperiores obcaecati dolores </span>sapiente. Nisi fugiat, beatae possimus impedit dolore quos nihil illo mollitia at exercitationem quo dignissimos eum, dolorum, delectus vel error sunt placeat eos ut.   Suscipit, <span>architecto perferendis</span>. Minus debitis optio ratione aperiam sapiente est blanditiis vero cum alias accusantium veniam, molestiae odit soluta esse sint dolore dignissimos culpa autem ullam molestias   repudiandae ab vitae eligendi inventore! Inventore, quas perspiciatis cumque repellat distinctio odio facilis explicabo ab molestiae laboriosam illo est at excepturi, deleniti dolore eum impedit quam voluptates. Totam quasi veniam   dolor omnis magni atque, ex minus officia at adipisci similique a soluta possimus vitae blanditiis minima. Odit sequi blanditiis nesciunt, nemo reprehenderit dignissimos voluptatum aut, ex saepe ipsa itaque nobis similique, expedita eum sapiente quibusdam inventore aliquam et. Enim consequuntur, ipsam possimus quia perferendis obcaecati similique laborum! Tempora minus, repellat repellendus itaque obcaecati optio autem ad velit blanditiis id quasi quia quaerat fuga at praesentium hic accusamus assumenda. Doloribus sit distinctio vitae nostrum quo maiores, aperiam eius exercitationem suscipit quod et explicabo. Alias, explicabo quidem? Ipsum, fugiat aliquam obcaecati ab tempore ducimus pariatur, itaque, consequuntur ea beatae consectetur. Modi ducimus perspiciatis asperiores atque neque iste, eligendi odio voluptatibus labore, dolorem, iusto ipsa hic rem facere. Tempora officia doloribus repellendus excepturi, eaque temporibus architecto non sequi cupiditate harum pariatur, alias quia beatae voluptatem quas, vel illo inventore eligendi deserunt cumque laudantium id nulla. Eos cum soluta magnam quam, aliquam facere accusantium quasi, minus doloremque adipisci incidunt debitis non tempore! Perspiciatis eius illum maiores nam laborum dicta repellendus similique incidunt, cum ut, aliquid eveniet? Voluptatum, doloremque et?</div>






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 28 '18 at 9:50

























          answered Nov 28 '18 at 8:28









          HerrSerkerHerrSerker

          20k84779




          20k84779













          • These do not work, if the page is scrolled.

            – HerrSerker
            Nov 28 '18 at 9:55



















          • These do not work, if the page is scrolled.

            – HerrSerker
            Nov 28 '18 at 9:55

















          These do not work, if the page is scrolled.

          – HerrSerker
          Nov 28 '18 at 9:55





          These do not work, if the page is scrolled.

          – HerrSerker
          Nov 28 '18 at 9:55


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53427728%2ftinymce-programmatically-select-word-at-caret-position%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          404 Error Contact Form 7 ajax form submitting

          How to know if a Active Directory user can login interactively

          TypeError: fit_transform() missing 1 required positional argument: 'X'