removeChild sometimes removes entire span and sometimes doesn't

[亡魂溺海] 提交于 2019-12-12 08:57:54

问题


I'm working on a rich text editor for iOS and have most of it working but running into endless problems ensuring that the cursor is visible in the viewport when the user starts typing.

I came up with a novel approach: insert a span at the cursor position, scroll to the span, and then remove it. (I haven't gotten to only scrolling if the span is on-screen.) Here's what I wrote:

document.addEventListener('keypress', function(e) {            
   jumpToID();
}, false);

function jumpToID() {
  var id = "jumphere2374657";
  var text = "<span id='" + id + "'>&nbsp;</span>"
  document.execCommand('insertHTML', false, text);
  var element = document.getElementById(id);
  element.scrollIntoView();
  element.parentNode.removeChild(element);
}

In some cases this works just fine and in some cases it leaves a non-break space between every key press, removing the <span></span> tags only. Any ideas? I'm open to better ways of doing this if someone has suggestions. I'm a little shocked at how hard it is to make the cursor appear but then JS is new to me.

EDIT

This is the code that works:

var viewportHeight = 0;

function setViewportHeight(vph) {
  viewportHeight = vph;
  if(viewportHeight == 0 && vph != 0)
    viewportHeight = window.innerHeight;
}

function getViewportHeight() {
  if(viewportHeight == 0)
    return window.innerHeight;
  return viewportHeight;
}

function makeCursorVisible() {
  var sel = document.getSelection();                  // change the selection
  var ran = sel.getRangeAt(0);                        // into a range
  var rec = ran.getClientRects()[0];                  // that we can get coordinates from
  if (rec == null) {
    // Can't get coords at start of blank line, so we
    // insert a char at the cursor, get the coords of that,
    // then delete it again. Happens too fast to see.
    ran.insertNode( document.createTextNode(".") );
    rec = ran.getClientRects()[0];  // try again now that there's text
    ran.deleteContents();
  }
  var top = rec.top;               // Y coord of selection top edge
  var bottom  = rec.bottom;        // Y coord of selection bottom edge
  var vph = getViewportHeight();
  if (top < 0)      // if selection top edge is above viewport top,
    window.scrollBy(0, top);  // scroll up by enough to make the selection top visible
  if (bottom >= vph)   // if selection bottom edge is below viewport bottom,
    window.scrollBy(0, bottom-vph + 1); // scroll down by enough to make the selection bottom visible
}

The viewportHeight is more complicated than need be for a web app. For a mobile app we need to account for the keyboard so offer a method for setting the viewportHeight manually as well as the automatic setting from the window.innerHeight.


回答1:


I don't know if this will work on iOS, but if the position of the cursor means that there is a Selection at that point..

function moveToSelection(){
    var sel = document.getSelection(), // change the selection
        ran = sel.getRangeAt(0),       // into a range
        rec = ran.getClientRects()[0], // that we can get co-ordinates from
        dy  = rec.top;                 // distance to move down/up
    window.scrollBy( 0, dy );          // actual move

    // console.log( sel, ran, rec, y );   // help debug
}

moveToSelection();

Relevant links

  1. getSelection
  2. getRangeAt
  3. getClientRects
  4. scrollBy


来源:https://stackoverflow.com/questions/12737272/removechild-sometimes-removes-entire-span-and-sometimes-doesnt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!