2017-10-10 1 views
2

에서 텍스트를 대체하는 일반적인 방법 나는 두 래퍼가 :추출하고 DOM

function wrapSentences(str, tmpl) { 
    return str.replace(/[^\.!\?]+[\.!\?]+/g, tmpl || "<sentence>$&</sentence>") 
} 

function wrapWords(str, tmpl) { 
return str.replace(/\w+/g, tmpl || "<word>$&</word>"); 
} 

내가 어떤 웹 페이지에 모든 단어와 문장을 포장하기 위해 확장에서 이러한 사용을 사용자가 TTS 및 설정을 위해 방문합니다.

document.body은 모든 웹 사이트에서 가장 기본적인 요소이지만, body.innerHTML = wrapWords(body.innerText)을 수행하면 다른 텍스트 노드 사이에있는 요소를 바꿔 (따라서 웹 사이트의 시각적 부분을) 깨뜨릴 수 있습니다. 해당 요소에 대해 구체적인 내용을 모르는 상태에서 텍스트 주위의 가장 가까운 요소를 찾는 방법을 찾고 있습니다. 따라서 어떤 방식 으로든 웹 사이트를 변경하지 않고도 래핑 된 요소로 대체 ​​할 수 있습니다.

나는 가장 깊은 자식에게가는 몇 가지 예제를 발견했지만 확장 기능이 알 수있는 방법이없는 노드 (노드 또는 ID)를 전달해야합니다. 우리는 강조 표시를 사용하기를 원하지만 동일한 이슈가 있습니다 ... 임의의 사이트를 방문 할 때 확장이 인식 할 수없는 노드 나 ID를 항상 전달해야합니다. 전달 노드를 필요로하는 예

하나 :

function replaceTextNodes(node, newText) { 
    if (node.nodeType === 3) { 
     //Filter out text nodes that contain only whitespace 
     if (!/^\s*$/.test(node.data)) { 
      node.data = newText; 
     } 
    } else if (node.hasChildNodes()) { 
     for (let i = 0, len = node.childNodes.length; i < len; ++i) { 
      replaceTextNodes(node.childNodes[i], newText); 
     } 
    } 
} 

내가 더 필요한 경우 설명 할 수있을 것입니다. 나는 내 말씨가 항상 최고일지도 모른다는 것을 두려워한다. 나는 그 사실을 알고있다.

+0

그래서 문제가 무엇 아니라 자신의는 TextContent, <word> 노드에서 텍스트를 포장 'document.body'을 전달하면됩니까? – trincot

+0

newText로 전달할 것이 없습니다. 나는 그것을 감쌀 수 있고 newText로 전달하기 전에 각 textnode의 내용을 별도로 알아야합니다. body.innerText를 전달하면 전체 본문 텍스트가 포함 된 모든 텍스트 노드가 생성됩니다. –

+0

물론, 그 기능을 모델로만 제공한다고 가정했습니다. 그래서 당신은 우리에게 비슷한 기능을 쓰도록 요구하고 있습니다. 그러나 그것은 포장을 수행합니까? – trincot

답변

1

페이지의 모든 텍스트 노드가 원하는 것처럼 보입니다 ... This question 님의 답변이있을 수 있습니다.

편집 : : 첫 번째 대답에서 기능을 사용
이제 재귀 함수를 사용하는 경우는 마지막에 발표처럼

function textNodesUnder(el){ 
    var n, a=[], walk=document.createTreeWalker(el,NodeFilter.SHOW_TEXT,null,false); 
    while(n=walk.nextNode()) a.push(n); 
    return a; 
} 

exp = /(?:(\W+)|(\w+))/g 

textNodesUnder(document.body) 
    .filter(t => !/^\s*$/.test(t.textContent)) 
    .forEach(t => { 
     let s = t.textContent, match 
     while(match = exp.exec(s)) { 
      let el 
      if(match[1] !== undefined) { 
       el = document.createTextNode(match[1]) 
      } 
      else { 
       el = document.createElement("word") 
       el.textContent = match[2] 
      } 
      t.parentNode.insertBefore(el, t) 
     } 
     t.parentElement.removeChild(t) 
    }) 
+0

'textContent'에 HTML 코드를 할당하는 것이 OP가 찾고있는 것이라고 생각하지 않습니다. – trincot

+0

@trincot 네 말이 맞아. 나는 그것을 지금 얻었다라고 생각한다. –

+0

나는 내일 직장에서 돌아올 때 그것을 확인해 볼 것이다. –