0

I'm experiencing a seemingly simple but puzzling problem with javascript. Here I have two snippets; the two are almost the same, except that the yellow enter box of the latter snippet is produced by Javascript.

The differences between the two codes are:

<table><tbody><tr class="newdiv"><td style="background:yellow">enter</td></tr></tbody></table> click the yellow box!
<br><textarea id="result"></textarea>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
// the script below enables typing 'enter' into textarea by clicking the yellow box.
$('.newdiv>td').click(function(){
    var range = document.createRange();
    range.selectNodeContents(this);  
    var sel = window.getSelection(); 
    sel.removeAllRanges(); 
    sel.addRange(range);
    insertAtCaret('result', sel);return false;
});
function insertAtCaret(areaId, text) {
  var txtarea = document.getElementById(areaId);
  if (!txtarea) {
    return;
  }
  var scrollPos = txtarea.scrollTop;
  var strPos = 0;
  var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ?
    "ff" : (document.selection ? "ie" : false));
  if (br == "ie") {
    txtarea.focus();
    var range = document.selection.createRange();
    range.moveStart('character', -txtarea.value.length);
    strPos = range.text.length;
  } else if (br == "ff") {
    strPos = txtarea.selectionStart;
  }
  var front = (txtarea.value).substring(0, strPos);
  var back = (txtarea.value).substring(strPos, txtarea.value.length);
  txtarea.value = front + text + back;
  strPos = strPos + text.length;
  txtarea.scrollTop = scrollPos;
}
</script>

<button onclick="myfunction()">show</button>
<div id="show"></div>
<br><textarea class="txta" id="result"></textarea>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
function myfunction(){
document.getElementById('show').innerHTML = `
<table><tbody><tr class="newdiv"><td style="background:yellow">enter</td></tr></tbody></table> click the yellow box!
`;
}
// the script below enables typing 'enter' into textarea by clicking the yellow box.
$('.newdiv>td').click(function(){
    var range = document.createRange();
    range.selectNodeContents(this);  
    var sel = window.getSelection(); 
    sel.removeAllRanges(); 
    sel.addRange(range);
    insertAtCaret('result', sel);return false;
});
function insertAtCaret(areaId, text) {
  var txtarea = document.getElementById(areaId);
  if (!txtarea) {
    return;
  }
  var scrollPos = txtarea.scrollTop;
  var strPos = 0;
  var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ?
    "ff" : (document.selection ? "ie" : false));
  if (br == "ie") {
    txtarea.focus();
    var range = document.selection.createRange();
    range.moveStart('character', -txtarea.value.length);
    strPos = range.text.length;
  } else if (br == "ff") {
    strPos = txtarea.selectionStart;
  }
  var front = (txtarea.value).substring(0, strPos);
  var back = (txtarea.value).substring(strPos, txtarea.value.length);
  txtarea.value = front + text + back;
  strPos = strPos + text.length;
  txtarea.scrollTop = scrollPos;
}
</script>

The yellow box of the second snippet is produced by:

function myfunction(){
document.getElementById('show').innerHTML = `
<table><tbody><tr class="newdiv"><td style="background:yellow">enter</td></tr></tbody></table> click the yellow box!
`;
}

The second snippet generates the yellow box by a javascript function, and typing enter is functioned by jquery. My question is: why does the function work in the first snippet but not the second, although their differences (in my humble opinion) doesn't seem to affect the fuction itself?

Henry
  • 154
  • 9
  • 1
    to further clear the answers posted here. the issue in that your code is assigning an event to a non existing element. you can assign the event to the body or to a parent element. – Maher Fattouh Jan 09 '21 at 13:34

1 Answers1

2

Please change code with following code.

From

$('.newdiv>td').click(function(){
    var range = document.createRange();
    range.selectNodeContents(this);  
    var sel = window.getSelection(); 
    sel.removeAllRanges(); 
    sel.addRange(range);
    insertAtCaret('result', sel);return false;
});

To

$(document).on('click', '.newdiv>td', function(){
    var range = document.createRange();
    range.selectNodeContents(this);  
    var sel = window.getSelection(); 
    sel.removeAllRanges(); 
    sel.addRange(range);
    insertAtCaret('result', sel);return false;
});

Reference answer

<button onclick="myfunction()">show</button>
<div id="show"></div>
<br><textarea class="txta" id="result"></textarea>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
function myfunction(){
document.getElementById('show').innerHTML = `
<table><tbody><tr class="newdiv"><td style="background:yellow">enter</td></tr></tbody></table> click the yellow box!
`;
}
// the script below enables typing 'enter' into textarea by clicking the yellow box.
$(document).on('click', '.newdiv>td', function(){
    var range = document.createRange();
    range.selectNodeContents(this);  
    var sel = window.getSelection(); 
    sel.removeAllRanges(); 
    sel.addRange(range);
    insertAtCaret('result', sel);return false;
});
function insertAtCaret(areaId, text) {
  var txtarea = document.getElementById(areaId);
  if (!txtarea) {
    return;
  }
  var scrollPos = txtarea.scrollTop;
  var strPos = 0;
  var br = ((txtarea.selectionStart || txtarea.selectionStart == '0') ?
    "ff" : (document.selection ? "ie" : false));
  if (br == "ie") {
    txtarea.focus();
    var range = document.selection.createRange();
    range.moveStart('character', -txtarea.value.length);
    strPos = range.text.length;
  } else if (br == "ff") {
    strPos = txtarea.selectionStart;
  }
  var front = (txtarea.value).substring(0, strPos);
  var back = (txtarea.value).substring(strPos, txtarea.value.length);
  txtarea.value = front + text + back;
  strPos = strPos + text.length;
  txtarea.scrollTop = scrollPos;
}
</script>
Canopus
  • 509
  • 2
  • 17