简体   繁体   中英

How can i get the cursor line number of a contenteditable html element?

I need to get the line number with the cursor in it or better the offset of the cursor in a contenteditable body element.

How can i achieve this?

I found a solution to my problem, but it will only work if the line-height of all lines are the same. The idea is to insert a dummy element at the caret posititon, calculate the position relative to the body start and then divide this value by the line-height. The result is the number of line the caret is in.

Here some code to get started with:

        // get lineheight, eighter line-height or min-height
        var $elem = $(ed.getBody().firstElementChild);
        var lineHeight = parseInt($elem.css('line-height'), 10) || parseInt($elem.css('min-height'), 10);

        var rng = ed.selection.getRng();
        rng.collapse(true);

        var bm = ed.selection.getBookmark();
        var $marker = $(ed.getBody()).find('#'+bm.id);
        var elem = ed.getDoc().getElementById(bm.id+'_start');
        try {
            box = elem.getBoundingClientRect();
        } 
        catch(e){}

        var doc = ed.getDoc(),
            docElem = doc.documentElement,
            body = ed.getBody(),
            win = ed.getWin(),
            clientTop  = docElem.clientTop  || body.clientTop  || 0,
            clientLeft = docElem.clientLeft || body.clientLeft || 0,
            scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
            scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
            top  = box.top  + scrollTop  - clientTop,
            left = box.left + scrollLeft - clientLeft;

        // set Bookmark
        ed.selection.moveToBookmark(bm);

        var caret_line = Math.floor( (top) / lineHeight ) + 1;

Here is one of my older tools on the subject.

/**
 * @description This operation splits the content of a text area based on its cursor position
 *              and selection.
 * @param targetNode This argument expects the text node to be split.
 * @return This operation returns an object containing {first, middle, last}.
 */
var splitTextAreaBySelection = function(targetNode)
{
  var target = document.getElementById('Area_'+targetNode.uid);
  var response = {};

  // IE fails this DOM3 operation. Use IE proprietary code here to recover.
  // WARNING: This proprietary IE code has Win32 platform dependency!
  if (typeof(target.selectionStart) === "undefined")
  {
    var content = targetNode.content;
    // this captures the area selected text.
    var r = document.selection.createRange();
    if (r !== null) {
      // thankfully the middle is easy to get!
      response.middle = r.text;
      // now we must create a new text range and mess with it until the cursor             position can be discovered.
      var re = target.createTextRange();
      var rc = re.duplicate();
      re.moveToBookmark(r.getBookmark());
      rc.setEndPoint('EndToStart', re);          
      var cursorPos = rc.text.length;
      // now that we have the cursor position, we can abstract the first and last         strings from the content.
      response.first = content.substr(0,cursorPos);
      response.last = content.substr(cursorPos + response.middle.length);
    }
    else
    {
      response.first = content;
    }
  }
  else
  {
    response.first = target.value.substring(0,target.selectionStart);
    response.middle = arget.value.substring(target.selectionStart, target.selectionEnd);
    response.last = target.value.substring(target.selectionEnd, target.textLength);
  }
  return response;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM