Найти текст (дочерние текстовые узлы) и обернуть его в абзац - PullRequest
2 голосов
/ 12 марта 2020

Мне нужна функция, которая находит текст (дочерние текстовые узлы) внутри некоторых (для этого примера div) элементов и переносит текст в абзац.

Text1
<div>
  <div>
    Text2
    <div>Text3</div>
  </div>
  <div>Text4</div>
  <p>Text5</p>
</div>
<div>Text6</div>
<div>
  Text7
  <p>Text8</p>
  Text9
</div>

пытался это сделать так:

const fn = (doc) => {
  const coll = [...doc.childNodes];
  coll.forEach(el => {
    if (el.tagName === 'DIV' && el.childElementCount === 0) {
      el.innerHTML = `<p>${el.innerHTML}</p>`;
    }
    if (el.childElementCount > 0) {
      el.childNodes.forEach(item => {
          if (item.nodeType === 3 && item.textContent.trim()) {
            const content = item.textContent.trim();
            item.innerHTML = `<p>${content}</p>`;
            console.log('2: ', item.innerHTML);
          }
        });
      fn(el);
    }
  });
}

но это работает неправильно - если условие (el.childElementCount> 0) в журнале консоли, я получил все необходимые узлы в тегах p. но не в результате. item.innerHTML = `<p>${content}</p>`; не применять его к документу :(. Кто-нибудь может помочь исправить это?

результат, который мне нужен:

Text1
<div>
  <div>
    <p>Text2</p>
    <div><p>Text3</p></div>
  </div>
  <div><p>Text4</p></div>
  <p>Text5</p>
</div>
<div><p>Text6</p></div>
<div>
  <p>Text7</p>
  <p>Text8</p>
  <p>Text9</p>
</div>

Ответы [ 3 ]

4 голосов
/ 23 марта 2020

Вы можете использовать replaceWith() для замены узла text элементом абзаца

function filterTextNode(node) {
  var textNodes = [];
  for (node = node.firstChild; node; node = node.nextSibling) {
    if (node.nodeType == 3 && node.textContent.trim()) textNodes.push(node);
    else textNodes = textNodes.concat(filterTextNode(node));
  }
  return textNodes;
}

function wrapTextNode(text) {
  var p = document.createElement('p');
  p.innerHTML = text.textContent;
  text.replaceWith(p);
}

const fn = (doc) => {
  var textNodes = filterTextNode(doc);
  textNodes.forEach(text => {
    if (text.parentNode.tagName != 'P') {
      wrapTextNode(text);
    }
  });
}

fn(document.body)
p {
  color: red;
}
Text1
<div>
  <div>
    Text2
    <div>Text3</div>
  </div>
  <div>Text4</div>
  <p>Text5</p>
</div>
<div>Text6</div>
<div>
  Text7
  <p>Text8</p>
  Text9
</div>

Ссылки

2 голосов
/ 13 марта 2020

Учитывая childElementCount из div, мы можем получить желаемый результат. Перепишите свою функцию, как показано ниже.

const fn = (document) => {
    let elements = document.getElementsByTagName('div');
    elements = Array.prototype.slice.call(elements);
    elements.forEach(el => {
      if (el.innerHTML && el.childElementCount === 0) {
        el.innerHTML = `<p>${el.innerHTML}</p>`;
        }
    });
  }
1 голос
/ 13 марта 2020

var elements = document.getElementsByTagName('div');
  for(var i=0;i<elements.length;i++){
    if(elements[i]===0){
      console.log(elements[i].textContent);
     
                       }
  else{
    var y=elements[i].innerHTML
console.log(y)
      }
  }
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>testing result</title>
</head>
<body>
  
<div>Text1</div>
<div>
<div>Text2</div>
<p>Text3</p>
</div>
<div>Text4</div>
</body>


</body>
</html>

я пробовал это, но я не могу получить последние два div (4 и 2), как этот вывод в консоли <div>text4</div> и <div>text2</div> я надеюсь, что это мой помогите, и я не знаю, как напечатать последние два div div HTML

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...