3

I have been trying to build a web based text editor. And as part of the process, I am trying to dynamically create and modify elements based and keystroke events for font editing. In this particular jsfiddle example I'm trying to create a strong element upon hitting CTRL+b and setting the focus/caret inside the strong element so that subsequent text entered will be part of the bold element and hence will have bold text. But my code is just creating a strong element but not transferring the focus hence no text is getting bolder.

In the below code I'm creating event listener to capture keystroke events

p=document.getElementsByTagName("p")[0];

//console.log(p)

// adding eventlistener for keydown
p.addEventListener("keydown",listener);

// eventlistenerr callback function
function listener(){
  e=window.event;
  if(e.ctrlKey && e.keyCode==66)
    {
      console.log("CTRL+B");

      // creating bold element
      belm=document.createElement("strong");
      belm.setAttribute("contenteditable","true")
      p.appendChild(belm);

      //bug below
      // setting focus inside bold element
      setfocus(belm,0);
      e.preventDefault();
    }
}

Here is the function for setting the focus.

function setfocus(context, position){
    var range = document.createRange();
    position =position || 0;
    var sel = window.getSelection();
    range.setStart(context, position);
    range.collapse(true);
    sel.removeAllRanges();
    sel.addRange(range);
    context.focus();
}

However, I have not doubt that the function which sets focus is faulty, because in the fiddle if you observe, I have created a separate setup just to test this out. Click on the button "Click Here" and the focus dynamically shifts to paragraph element without any hassle. I am unable to figure out what is going wrong.

mx0
  • 6,445
  • 12
  • 49
  • 54
nanu146
  • 97
  • 1
  • 1
  • 9

1 Answers1

1

It's pretty much impossible to move the cursor into an empty element in a contenteditable div. However, as shay levi suggested in another post, you can insert the zero-width character &#200B into your empty element to give it an index value.

Here's an example*:

function insertNode(nodeName) {
  var sel = window.getSelection(),
    range;
  range = sel.getRangeAt(0);
  range.deleteContents();

  var child = document.createElement(nodeName);
  child.innerHTML = '​';
  range.insertNode(child);
}

var div = document.querySelector('div'),
  btn = document.querySelector('button');

btn.addEventListener('click', function() {
  insertNode('strong');
  div.focus();
});

div.focus();
<div contenteditable></div><button><strong>B</strong></button>

*For the sake of simplicity, this script doesn't toggle bold text, it only sets it.

clabe45
  • 2,354
  • 16
  • 27