LoginSignup
3

More than 5 years have passed since last update.

contenteditableの文章をキャレット位置で分割する

Last updated at Posted at 2018-04-07

よく枯れているキャレット位置取得コード

fn.gcp= function getCaretPosition(editableDiv) {
//https://stackoverflow.com/questions/3972014/
  var caretPos = 0,
    sel, range;
  if (window.getSelection) {
    sel = window.getSelection();
    if (sel.rangeCount) {
      range = sel.getRangeAt(0);
      if (range.commonAncestorContainer.parentNode == editableDiv) {
        caretPos = range.endOffset;
      }
    }
  } else if (document.selection && document.selection.createRange) {
    range = document.selection.createRange();
    if (range.parentElement() == editableDiv) {
      var tempEl = document.createElement("span");
      editableDiv.insertBefore(tempEl, editableDiv.firstChild);
      var tempRange = range.duplicate();
      tempRange.moveToElementText(tempEl);
      tempRange.setEndPoint("EndToEnd", range);
      caretPos = tempRange.text.length;
      //console.log(tempRange.text)
    }
  }
 // console.log(caretPos,sel,range)
  return caretPos;
}

ctrl+enterが押されたタイミングで、新しいcontenteditableを生成

function fac(text){
 let el=temp.cloneNode(true),ed=fn.q('[contenteditable]',el)
 ;
 ed.textContent=text;
 ed.onkeydown=calc;
 return el;
}

全部 ctrl+enterで分割

<outline temp style="display:none">
 <div f><div contenteditable="plaintext-only"></div></div>
</outline>
<style>
[contenteditable]{
 padding:0.5rem; margin:2rem 0;
 outline:none; border:2px solid;
} 
</style>
let fn={}
fn.q=(s,doc=document)=>{return doc.querySelector(s)};
fn.as2 =function(me,p){p.parentNode.insertBefore(me,p.nextSibling);return me}
fn.gcp= function getCaretPosition(editableDiv) {
//https://stackoverflow.com/questions/3972014/
  var caretPos = 0,
    sel, range;
  if (window.getSelection) {
    sel = window.getSelection();
    if (sel.rangeCount) {
      range = sel.getRangeAt(0);
      if (range.commonAncestorContainer.parentNode == editableDiv) {
        caretPos = range.endOffset;
      }
    }
  } else if (document.selection && document.selection.createRange) {
    range = document.selection.createRange();
    if (range.parentElement() == editableDiv) {
      var tempEl = document.createElement("span");
      editableDiv.insertBefore(tempEl, editableDiv.firstChild);
      var tempRange = range.duplicate();
      tempRange.moveToElementText(tempEl);
      tempRange.setEndPoint("EndToEnd", range);
      caretPos = tempRange.text.length;
      //console.log(tempRange.text)
    }
  }
 // console.log(caretPos,sel,range)
  return caretPos;
}
;
let temp=fn.q('[temp] [f]')
,calc=function(ev){
 if(!(ev.ctrlKey&&ev.keyCode===13))return
 ;
 let me=this,splits=me.textContent.slice(fn.gcp(me))
 me.textContent=me.textContent.replace(splits,'')
 let el=fac(splits)
 fn.as2(el,me.parentElement);//me.parente.. is [f]
 fn.q('[contenteditable]',el).focus();
}
;
function fac(text){
 let el=temp.cloneNode(true),ed=fn.q('[contenteditable]',el)
 ;
 ed.textContent=text;
 ed.onkeydown=calc;
 return el;
}
;
document.body.appendChild(fac('ctrl+enter is split text'))
;

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3