Browser is getting confused with .innerHTML being updated

Hey SP,

I’m trying to write a code editor that will allow me to program a website directly from the backend of the website. Currently I’m trying to make it so that I can apply some syntax highlighting colors to a content editable div. The best way I could describe the issue I’m having is that once I update the innerHTML of the div the browser seems to disconnect the textContent from div.

It might take me a few posts and questions to fully explain the issue, but I believe this issue is related to the substantiation of textContent which I’m guessing isn’t automatically updated simply becuase innerHTML is updated. How could I get around this?

I’m using the latest version of Firefox.

Do you mean that when you set the innerHTML of an element, the new contents appear outside of that element in the DOM? A possible cause there could be invalid HTML. Or did you mean to say it’s no longer contenteditable?

Best to provide a working example we can play with.

1 Like

Basically I take the entire textContent from the div, and split it up into an array of lines by \n

Then I go line by line adjusting the coloring. So far All I’m searching for is the php open tags of “<?" and "?>”.

So I go through line by line in a loop and do

line_of_text.replace("<?","<span class="phptag"><?</span>")

Then once I’ve iterated through all of the lines I reassign them to a new variable called new_inner_html, and then at the very end of the function is document.getElementById('code_editor').innerHTML = new_inner_html;

And it works, the <? appear in red according to the CSS styling. The issue is that I am no longer able to edit the text in the div any longer. When I type in new characters into the editable div (the code window), regardless of where the caret is, all of the typed characters appear in the first line as if the div were empty of text. I also lose the ability to delete highlighted text.

I’d love to give an example but I’m not sure how I could without having access to a server I could post the code on. But I can paste the syntax_highlight function if you’d like?

It feels as though the browser is not syncing the innerHTML to the textContent any longer. I’m nearly positive this is the issue.

Making a demo you can share is easy in javascript:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <style media="screen">
      #code_editor {
        height: 300px;
        border: 1px dotted #ccc;
      }
    </style>
  </head>
  <body>
    <div id="code_editor" contenteditable>Hello</div>
    <button onclick="updateContent()">Update</button>
    <script>
    var updateContent = function() {
      document.getElementById('code_editor').innerHTML = 'I am <span style="color: red">updated</span>.';
    }
    </script>
  </body>
</html>

This shows that you can indeed set the innerHTML of a contenteditable and keep the contents editable, so you must be doing something else.

1 Like

Thanks so much for your assistance. I’ve narrowed the issue down. My syntax_update() function appears to work properly if I run it from an onclick button, but when I run it from my javascript function that runs anytime a key is pressed it has the issue I’m experiencing. Here is the way I’m catching keystrokes.

document.onkeydown = function(e) 
{
  code_editor_instance = document.getElementById('code_editor');
  /*
  //SHIFT+TAB - Outdent two spaces
  if (e.shiftKey && e.keyCode === 9) 
  {
    //alert('Tab Outdent');
    tab_outdent(code_editor_instance);
    return false;
  }
  else
  //TAB - Indent two spaces
  if (e.keyCode === 9) 
  {
    //alert('Tab Indent');
    tab_indent(code_editor_instance);
    return false;
  }
  else
  //SHIFT+DEL - Delete existing line
  if (e.shiftKey && e.keyCode === 46) 
  {
    //alert('Delete Existing Line');
    line_delete(code_editor_instance);
    return false;
  }
  else
  //CTRL+D - Duplicate current line
  if (e.ctrlKey && e.keyCode === 68) 
  {
    //alert('Duplicate Current Line');
    line_duplicate(code_editor_instance);
    return false;
  } */
  
  //Syntax Update 
  syntax_update(code_editor_instance);
};

So the issue must somehow be related to the keystroke thing.

Yes, that makes sense. When setting the innerHTML of the element the caret position is collapsing down to the start so ruins it as a text editor.

Building a code editor is not a simple thing to achieve at all, I’d suggest you use a solid implementation like CodeMirror

If you want to persist with it you need to look at saving the caret position before setting innerHTML and then setting the caret position afterwards. I suspect setting the innerHTML on every keystroke is not the best way to do this, these other editors have solved all these problems for you already, just use theirs.

I’m actually aware of that. My tabindent code for example allows me to tab as two spaces intead of a tab character and shift tab over a highlighted range will subtract two spaces from the starting of each line affected, all with working caret movement adjustment.

This issue I’m having is unique to the fact that I’m having troubles adjusting the innerHTML when using a keypress event instead of just clicking a button (which seems to work OK).

I’m aware of codemirror as well, I didn’t enter into this too lightly but I want this editor to do some pretty custom things and I’m still thinking it’s less to work to just write a very small editor with just a few key features I need rather than trying to hack codemirror. Time will tell, I’m probably wrong lol.

You’re braver than I then :slight_smile:

If you get something working in all the major browsers do show us, I’ve worked on rich text editors in the past and they’re simpler than a code editor with syntax highlighting would be. Good luck.

Depending on how deep you get into it https://github.com/atom/atom might contain some of the best work in this space.

1 Like

Thanks for the support.

I won’t even be trying to make it multibrowser compliant. This is just a personal development tool for my own projects. I only use Mozilla based browsers so that’s all I’m writing it for.

I’ll check out atom.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.