最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - unable to createRange() - Stack Overflow

programmeradmin2浏览0评论

I am trying to select a dynamically added timestamp - hit enter in the contentEditable element.

$('#content').on('keypress', function(e) {
  if (e.which === 13) {
    console.log('enter pressed');
    e.preventDefault();
    var range = window.getSelection().getRangeAt(0);
    var element = document.createElement('p');
    element.setAttribute("id", "uniqueIdentifier");
    var date = new Date().getTime();
    date = date.toString();
    console.log('date: ' + date);
    element.textContent = date;
    //element.innerHTML = '<br>';
    range.insertNode(element);
    var range2 = document.createRange();
    console.log('$(#content).text(): ' + $('#content').text());
    var startOffset = $('#content').text().indexOf(date);
    console.log('startOffset: ' + startOffset);
    range2.setStart(document.getElementById('uniqueIdentifier'), startOffset);
    range2.setEnd(document.getElementById('uniqueIdentifier'), startOffset + date.length);
    //        $('#content p.new').focus();
  }
});
<script src=".1.1/jquery.min.js"></script>
<p id='content' contentEditable='true'>test</p>

I am trying to select a dynamically added timestamp - hit enter in the contentEditable element.

$('#content').on('keypress', function(e) {
  if (e.which === 13) {
    console.log('enter pressed');
    e.preventDefault();
    var range = window.getSelection().getRangeAt(0);
    var element = document.createElement('p');
    element.setAttribute("id", "uniqueIdentifier");
    var date = new Date().getTime();
    date = date.toString();
    console.log('date: ' + date);
    element.textContent = date;
    //element.innerHTML = '<br>';
    range.insertNode(element);
    var range2 = document.createRange();
    console.log('$(#content).text(): ' + $('#content').text());
    var startOffset = $('#content').text().indexOf(date);
    console.log('startOffset: ' + startOffset);
    range2.setStart(document.getElementById('uniqueIdentifier'), startOffset);
    range2.setEnd(document.getElementById('uniqueIdentifier'), startOffset + date.length);
    //        $('#content p.new').focus();
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id='content' contentEditable='true'>test</p>

I am getting this error:

Uncaught IndexSizeError: Failed to execute 'setStart' on 'Range': There is no child at offset 4.

What am I missing?

Share Improve this question edited Aug 30, 2020 at 1:47 Rahul Desai asked Jun 15, 2015 at 21:43 Rahul DesaiRahul Desai 15.5k20 gold badges88 silver badges144 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 27

There are two ways. Either pass the DOM node or pass node's text part. If you pass the DOM node you should give the start and end offsets as 0 and 1 to create a range over the DOM node like this

range.setStart(document.getElementById('uniqueIdentifier'), 0);
range.setEnd(document.getElementById('uniqueIdentifier'), 1);

If you are giving the text node part then you have to give the length of the text node to create a range over the text part of the DOM node like this

var uid = document.getElementById('uniqueIdentifier');
range.setStart(uid.firstChild, 0); <-- firstChild refers to the text part of a DOM node
range.setEnd(uid.firstChild, uid.firstChild.length);

You are mixing the two ways. You can solve it like this

$('#content').on('keypress', function(e) {
  if (e.which === 13) {
    e.preventDefault();
    var date = new Date().getTime();
    date = date.toString();
    var range = window.getSelection().getRangeAt(0);
    var element = $('<p></p>')
                    .attr('class', 'uniqueIdentifier') 
                    .text(date);
    range.insertNode(element[0]); // the date node is added to the DIV at this stage
    var range2 = document.createRange();
    range2.setStart(element[0], 0); // <--- Give the entire date node starting at 0
    range2.setEnd(element[0], 1); // <--- Ending at 1 since there is only one node that you want a range of 
    var newNode = document.createElement("b"); // <--- I created a b element just so that the range is visible
    range2.surroundContents(newNode);
  }
});

Hope this helps.

$('#content').on('keypress', function(e) {
  if (e.which === 13) {
    e.preventDefault();
    var date = new Date().getTime();
    date = date.toString();
    var range = window.getSelection().getRangeAt(0);
    var element = $('<p></p>')
      .attr('class', 'uniqueIdentifier')
      .text(date);
    range.insertNode(element[0]);
    var range2 = document.createRange();
    range2.setStart(element[0], 0);
    range2.setEnd(element[0], 1);
    var newNode = document.createElement("b");
    newNode.style.color = getRandomColor(); // <-- Just so that range is visible
    range2.surroundContents(newNode);
  }
});

/* Courtesy: http://stackoverflow.com/a/1484514 */
function getRandomColor() {
  var letters = '0123456789ABCDEF'.split('');
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id='content' contentEditable='true'>test</p>

发布评论

评论列表(0)

  1. 暂无评论