Показать сообщение отдельно
  #2 (permalink)  
Старый 23.06.2020, 20:38
Аватар для Белый шум
Профессор
Отправить личное сообщение для Белый шум Посмотреть профиль Найти все сообщения от Белый шум
 
Регистрация: 19.01.2012
Сообщений: 498

Проверял только в хроме.

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <button id="h1-trigger">Turn selection</button>
  <button id="check">Check selection status</button>
  <div id="editor">This is the text where we can select some word by double-clicking, and press the "h1-trigger button". The function wraps the selection with h1 tags. When clicked again it will unwrap the selection and return to previous text. But if we unselect the wrapped word (h1 heading), select by double-click again, and press the button, it does another result. The second button shows the selection status with console log. Why re-selection doesn't contain the created tags?</div> 
</body>
<script>
document.getElementById('h1-trigger').addEventListener('click', function () {
  headerFormatter();
});

document.getElementById('check').addEventListener('click', function () {
  let sel = window.getSelection();
  let range = sel.getRangeAt(0).cloneRange();
  let rangeProxy = sel.getRangeAt(0).cloneContents();
  console.log(sel);
  console.log(range);
  console.log(rangeProxy);
});

function headerFormatter() {
  if( !window.getSelection ) { return; }
    let sel = window.getSelection();
    if( !sel.rangeCount ) { return; }
    let range = sel.getRangeAt(0).cloneRange();
      
    let node, start, end;
    if( range.startContainer.nodeName == "#text" ){
      	node = range.startContainer.parentNode;
        start = range.startOffset;
        end = range.endOffset;
    } else {
      	node = range.startContainer.childNodes[ range.startOffset ];
        start = 0;
        end = node.childNodes[0].length;
    }
    //console.log( node.closest("h1") );
    if( node.closest("h1") && node.closest("h1").closest("#editor") )
    {
        let childNodes = node.closest("h1").parentNode.childNodes;
        for( var i=0; i<childNodes.length; i++ ){
          if( childNodes[i] == node ) {--i; break;}
        }
        if( childNodes[i].nodeName == "#text" ){
          start += childNodes[i].length;
          end += childNodes[i].length;
          node = node.closest("h1");
          node.outerHTML = node.innerHTML; //удалить тег
          range.setStart(childNodes[i], start);
          range.setEnd(childNodes[i], end);
          sel.removeAllRanges();
          sel.addRange(range);
          //console.log(range);
        }
    } else {
      	if( !range.collapsed ){
          let newTag = document.createElement('h1');
          range.surroundContents(newTag);
          sel.removeAllRanges();
          sel.addRange(range);
        }
    }
}
</script>
</html>
Ответить с цитированием