DOM

2017-10-10 8 views
2

からテキストを抽出し、交換する汎用的な方法は、私は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)を実行すると、異なるテキストノード間にあった要素が(明らかに)置き換えられ、ウェブサイト(の視覚的部分)が破損します。私は、その要素に関する何かを知らなくても、テキストのまわりで最も近い要素を見つける方法を探しています。したがって、Webサイトを変更することなくラップされたものと置き換えることができます。

私はいくつかの例を見つけましたが、最も深い子に行きますが、それらはすべて、拡張機能が知ることのできない何か(ノードまたは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

明日は仕事に戻ります。 –