2

I am trying to insert text at the current cursor position in the content editable div by clicking on some other element . This works perfect if I click on button , but not working with any other element . I mean for the button it is inserting at the cursor position , but for any other element clicks it is always adding the starting position of the div . Below is an example which includes Button click and DIV click( It is not working for any other tag ) . Is there any difference between these two clicks ? How can I make DIV click exactly like a button click . Please note I am not using JQUERY ( But if there is any solution with VUEJS I am fine ) . Thank You .

Here is the jsfiddle link http://jsfiddle.net/jwvha/2727/

function insertTextAtCursor(text) {
  document.getElementById('pre').focus();
  var sel, range, html;
  sel = window.getSelection();
  range = sel.getRangeAt(0);
  range.deleteContents();
  var textNode = document.createTextNode(text);
  range.insertNode(textNode);
  range.setStartAfter(textNode);
  sel.removeAllRanges();
  sel.addRange(range);
}
body {
  background-color: #CCC;
}

div {
  border: 1px #000 solid;
  background-color: #FFF;
  width: 900px;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  margin-top: 20px;
  margin-bottom: 20px;
  vertical-align: center;
  padding: 30px;
}
<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Editor</title>
</head>

<body>
  <div contenteditable id="pre">
    Update text Here . This is contenteditable div
  </div>
  <div>
    <input type="button" onClick="insertTextAtCursor('TEXT')" value="Click here to insert text above"> ( This button inserts text at the cursors current positions)
  </div>
  <div onClick="insertTextAtCursor('TEXT')">
    <b>Click here to insert in the above  contenteditable div </b> ( This won't insert at the current position , but always at the position 1)
  </div>
</body>

</html>
Bujji
  • 1,717
  • 10
  • 41
  • 66

1 Answers1

2

Buttons do not gain focus on click unlike many other elements. As you are relying on focus in your function, after a successful click event (which consists of mouseup + mousedown) that bubbles up the DOM tree, your focus is being set on the div first. You can avoid this by either listening to mousedown events and calling event.preventDefault() or simply trigger your function before click is fired, i.e. onmousedown.

Here is an answer to another post that explains everything pretty well.

var prevented = document.getElementById("prevented");
prevented.addEventListener('mousedown', event => event.preventDefault());

function insertTextAtCursor(text) {
  document.getElementById('pre').focus();
  var sel, range, html;
  sel = window.getSelection();
  range = sel.getRangeAt(0);
  range.deleteContents();
  var textNode = document.createTextNode(text);
  range.insertNode(textNode);
  range.setStartAfter(textNode);
  sel.removeAllRanges();
  sel.addRange(range);
}
body {
  background-color: #CCC;
}

div {
  border: 1px #000 solid;
  background-color: #FFF;
  width: 500px;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  margin-top: 20px;
  margin-bottom: 20px;
  vertical-align: center;
  padding: 30px;
}
<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Editor</title>
</head>

<body>
  <div contenteditable id="pre">
    Update text Here . This is contenteditable div
  </div>
  <div>
    <input type="button" onClick="insertTextAtCursor('TEXT')" value="Click here to insert text above"> ( This button inserts text at the cursors current positions)
  </div>
  <div onClick="insertTextAtCursor('TEXT')" id="prevented">
    <b>Click here to insert in the above  contenteditable div </b> ( This won't insert at the current position , but always at the position 1)
  </div>
</body>

</html>
mkrl
  • 740
  • 6
  • 20
  • But this doesn't solve the problem, it just sets it ONCE before losing focus. – Sherif Salah Nov 14 '18 at 02:16
  • I was just giving a basic idea of the root of the problem. I've updated my answer with a basic event listener. – mkrl Nov 14 '18 at 02:31
  • Thank You for your answer and the solution . This is really helpful . I have to check if this can be implemented for emoji-mart-vue . Thanks again – Bujji Nov 14 '18 at 10:36