Попытка развернуть некоторые части текста, оставляя остальную часть завернутой - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть следующая строка html,

<p>
    a
    <i>
        b
        <u>
            c X d
        </u>
        e
    </i>
    f
</p>

Я бы хотел развернуть тег <i> вокруг X, оставив остальной текст с собственными тегами. другими словами, я хочу обернуть b, c, d и e тегом <i>, получая при этом X. Например, это должно выглядеть так:

<p>
    a
  <i>
    b
    <u>
      c 
    </u>
  </i>
  <u>
    X
  </u>
  <i>
    <u> 
      d
    </u>
    e
  </i>
  f
</p>

Это то, что я сделал, все работает нормально, но мне было интересно, есть ли лучший способ сделать это.

function unwrapX(htmlText) {
        if(!htmlText.includes('X')){
            return htmlText;
        }
        var div = document.createElement('div');
        div.innerHTML = htmlText;
        var arr = [];
        div.querySelectorAll("p").forEach(function(p){
            p.innerHTML = p.innerHTML.replace(/X/g, "<dummy>X</dummy>");
            var item = p.querySelector("dummy");
            while(item) {
                arr.push([]);
                var it = item
                while(it.nodeName !== "P"){
                    if(it.nodeName !== "DUMMY"){
                        var clonedNode = it.cloneNode();
                        arr[arr.length-1].push(clonedNode)
                    }
                    it = it.parentNode
                }
                item.outerHTML = "<temp id=\"" + (arr.length-1).toString() + "\">" + item.innerHTML + "</temp>"
                item = p.querySelector("dummy");
            }
        })
        Array.from(div.querySelectorAll('*:empty')).forEach(el=>{el.remove();});


        div.querySelectorAll("temp").forEach(function(temp){
            var id = temp.id;
            var wrappers = arr[id];
            var closeAll = "";
            for(var i = 0; i < wrappers.length; i++){
                closeAll += wrappers[i].outerHTML.match(/<\/[a-zA-Z]+(>|.*?[^?]>)/g)[0];
            }
            var openAllButI = "";
            for(var i = wrappers.length-1; i >= 0; i--){
                if(wrappers[i].nodeName === "I") continue;
                openAllButI += wrappers[i].outerHTML.match(/<[a-zA-Z]+(>|.*?[^?]>)/g)[0];
            }
            var closeAllButI = "";
            for(var i = 0; i < wrappers.length; i++){
                if(wrappers[i].nodeName === "I") continue;
                closeAllButI += wrappers[i].outerHTML.match(/<\/[a-zA-Z]+(>|.*?[^?]>)/g)[0];
            }
            var openAll = "";
            for(var i = wrappers.length-1; i >= 0; i--){
                openAll += wrappers[i].outerHTML.match(/<[a-zA-Z]+(>|.*?[^?]>)/g)[0];
            }
            var replaceOpen = closeAll + openAllButI;
            var replaceClose = closeAllButI + openAll;
            var orig = temp.outerHTML;
            var repl = replaceOpen + "X" + replaceClose;
            div.innerHTML = div.innerHTML.replace(orig, repl)
        });
        while(div.querySelectorAll('*:empty').length > 0){
            Array.from(div.querySelectorAll('*:empty')).forEach(el=>{el.remove();})
        }
        return div.innerHTML;
    }           
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...