2013-04-24 4 views
0

Скажем, у меня есть этот HTML:Замена выделения текста с помощью строки без разрушающих тегов вне выделения

<div class="edit" contenteditable="true"> 
    <b>Example text</b> 
    Text outside 
    <b> 
     <i> 
     <u>underlined and italic and bold</u> 
     italic and bold</i></b> 
    more Text 
    <br> 
    after the line break 
</div> 

И для удобства у меня есть эта яваскрипта функция, которая возвращает смещение конца выбора в данный элемент:


Допустим, пользователь сделал выбор, который начинается и заканчивается outside в italic and bold так это выглядит следующим образом:

"outsideunderlined and italic and bolditalic and bo" 

Как вы можете заменить всю эту строку, не повреждая <b>Example text</b> и текст, который приходит после выбора. Если строка заменим с пустой строкой "" результат должен выглядеть примерно так:

<div class="edit" contenteditable="true"> 
    <b>Example text</b> 
    Text 
    ld 
    more Text 
    <br> 
    after the line break 
</div> 

Я не волнует, если теги в выборе сохраняются или нет, я не уверен, какой способ проще.

Если вам не ясно, пожалуйста, спрашивайте.

Благодарим за помощь.

+0

"ld" был выделен полужирным шрифтом, он должен быть выделен полужирным шрифтом после замены текста, не согласны? – MaxArt

+0

@MaxArt На самом деле он был выделен жирным шрифтом и выделен курсивом. Мне все равно, останется ли это так. Но ни в коем случае он не должен полностью исчезать – MentholBonbon

+0

Непростая задача, во всяком случае. Вам нужно будет проверить, является ли 'range.startContainer === range.endContainer' - если это так, это тривиально. Или же вам придется удалить часть текстовых узлов и каждый элемент между ними. Я напишу ответ позже. – MaxArt

ответ

1

Этот ответ не для IE8- (пока). Эта функция заменяет выделенный текст replaceString и выбирает вновь вставленный узел. Возможно, вы захотите нормализовать DOM впоследствии, это могут быть смежные или пустые текстовые узлы.

Спросите меня, если что-то неясно.

function replSel(replaceString) { 
    var sel = getSelection(), rng, startNode, endNode, comAnc, sOff; 
    if (sel.rangeCount) { 
     rng = sel.getRangeAt(0); 
     sOff = rng.startOffset; 
     if (rng.startContainer === rng.endContainer) { 
      rng.endContainer.nodeValue = 
        rng.endContainer.nodeValue.substring(0, sOff) + replaceString 
        + rng.endContainer.nodeValue.substring(rng.endOffset); 
      rng.setStart(rng.startContainer, sOff); 
      rng.setEnd(rng.endContainer, sOff + replaceString.length); 
     } else { 
      comAnc = rng.commonAncestorContainer; 
      rng.startContainer.nodeValue = 
        rng.startContainer.nodeValue.substring(0, sOff); 
      // rng.startOffset is set to 0 when the node value is changed 
      // That's fine for the range's end, but not for the start. 
      rng.setStart(rng.startContainer, sOff); 
      rng.endContainer.nodeValue = 
        rng.endContainer.nodeValue.substring(rng.endOffset); 
      startNode = rng.startContainer; 
      while (startNode.parentNode !== comAnc) { 
       while (startNode.nextSibling) 
        startNode.parentNode.removeChild(startNode.nextSibling); 
       startNode = startNode.parentNode; 
      } 
      endNode = rng.endContainer; 
      while (endNode.parentNode !== comAnc) { 
       while (endNode.previousSibling) 
        endNode.parentNode.removeChild(endNode.previousSibling); 
       endNode = endNode.parentNode; 
      } 
      while (startNode.nextSibling !== endNode) 
       comAnc.removeChild(startNode.nextSibling); 
      comAnc.insertBefore(
        document.createTextNode(replaceString), endNode); 
     } 
     sel.removeAllRanges(); 
     sel.addRange(rng); 
    } 
} 
+0

Спасибо, это здорово! – MentholBonbon

Смежные вопросы