2

I have a button element, which needs to have text which can be modified dynamically. I was having trouble with adding spaces which is when I refered this answer to have a span, which is contenteditable. During this time, I was testing on Chrome and it was working.

However, when I was testing this feature in Firefox, I was not able to insert spaces in the span element. I do not see anything about this online either. Is there anyway I can have this supported on Firefox too?

I should also note that, I am doing this for an Extension that I am building for Chrome and Firefox.

This is what my code looks like:

<!-- HTML -->
<button id="editableBtn">
  <span id="titleText" contenteditable="false" style="border: solid; border-color: green;">Button</span>
</button>
<button id="editorBtn">Click me to edit</button>

<!-- JS -->
<script>
  var spanText = document.getElementById("titleText");
  var editableBtn = document.getElementById("editableBtn");
  var editorBtn = document.getElementById("editorBtn");

  spanText.addEventListener('keydown', (event) => {
    console.log("Span keydown = ", event)
  })

  editorBtn.addEventListener('click', (event) => {
    spanText.contentEditable = "true"
  })

</script>

Firefox Version: 110.0

Google Chrome Verion: 110.0

healthyCoder
  • 27
  • 1
  • 5

1 Answers1

3

You could add an event listener to the span element for the "keydown" event, so when the space bar is pressed it manually inserts a space character at the current cursor position.

var spanText = document.getElementById("titleText");
var editableBtn = document.getElementById("editableBtn");
var editorBtn = document.getElementById("editorBtn");

// modified from https://stackoverflow.com/a/2925633/1612562
function insertTextAtCaret(text) {
  var sel, range;
  if (window.getSelection) {
    sel = window.getSelection();
    if (sel.getRangeAt && sel.rangeCount) {
      range = sel.getRangeAt(0);
      range.deleteContents();
      range.insertNode(document.createTextNode(text));
      // un-select the newly-inserted text node and place cursor behind it
      range.collapse();
    }
  } else if (document.selection && document.selection.createRange) {
    document.selection.createRange().text = text;
  }
}

spanText.addEventListener('keydown', (event) => {
  if (event.keyCode === 32) { // 32 is the keycode for the spacebar
    // prevent default behavior, since we're handling it ourselves
    event.preventDefault();
    // insert the space character at the current cursor position
    insertTextAtCaret(' ');
  }
});

editorBtn.addEventListener('click', (event) => {
  spanText.contentEditable = "true"
});
<button id="editableBtn">
  <span id="titleText" contenteditable="false" style="border: solid; border-color: green; white-space: pre-wrap">Button</span>
</button>
<button id="editorBtn">Click me to edit</button>
rphv
  • 5,409
  • 3
  • 29
  • 47
  • Isn't `document.execCommand` deprecated? Is there any alternative command which performs similar to `document.execCommand`? – healthyCoder Feb 21 '23 at 03:53
  • Yes, there is. I've modified the answer to use `window.getSelection` as detailed in [this answer](https://stackoverflow.com/a/2925633/1612562). The addition of `range.collapse()` places the cursor at the end of the inserted space character. – rphv Feb 21 '23 at 04:49