2017-06-22 4 views
0

実際のレンダリングされたテキストをブラウザから取得する方法はありますか(右から左のテキストの方向で)?正確なブラウザレンダリングテキスト(RTLとLTR方向のミックス)

<html dir="rtl"> 
<body> 
    <p id='ko'>Hello (world)</p> 
    <p id='ok'>Hello <bdo dir='ltr'>(world)</bdo></p> 
</body> 
</html> 

がレンダリングされます:Firefoxの

    クロムで

enter image description here

  • enter image description here

    しかし、両方 document.getElementById('ok').textContent === document.getElementById('ko').textContentdocument.getElementById('ok').innerText === document.getElementById('ko').innerTextは(両方のブラウザ用)trueです。

    ウェブページに表示される実際のテキストを取得する方法はありますか?

    https://jsfiddle.net/019kvo56/1/

答えて

1

ありますが、例えばgetComputedStyle(elem)からつかむことができdirection CSSプロパティがあるが、これは唯一の要素レベルであるので、あなたはブラウザがtextNodesをレンダリングしました正確にどのように知ることができません。

だから、あなたが何をする必要があるかは、次のとおりです。

  • 最初のグラブあなたのコンテナからすべてのtextNodes(最高はTreeWalkerで行われます)。
  • Range object
  • の各文字を選択すると、RangeのgetBoundingClientRect()メソッドによって各文字の現在の位置が取得されます。
  • ソートそれら
  • そのテキストがここ

がライブデモで値取り戻す:今

function getDisplayedText(container) { 
 

 
    var r = document.createRange(); // to get our nodes positions 
 

 
    var nodes = []; // first grab all the nodes 
 
    var treeWalker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT, null, false); 
 
    while (treeWalker.nextNode()) nodes.push(treeWalker.currentNode); 
 

 
    var chars = []; // then get all its contained characters 
 
    nodes.forEach(n => { 
 
    n.data.split('').forEach((c, i) => { 
 
     r.setStart(n, i); // move the range to this character 
 
     r.setEnd(n, i+1); 
 
     chars.push({ 
 
     text: c, 
 
     rect: r.getBoundingClientRect() // save our range's DOMRect 
 
     }) 
 
    }) 
 
    }); 
 

 
    return chars.filter(c => c.rect.height) // keep only the displayed ones (i.e no script textContent) 
 
    .sort((a, b) => { // sort ttb ltr 
 
     if (a.rect.top === b.rect.top) { 
 
     return a.rect.left - b.rect.left; 
 
     } 
 
     return a.rect.top - b.rect.top; 
 
    }) 
 
    .map(n => n.text) 
 
    .join(''); 
 
} 
 

 
console.log('ko : ', getDisplayedText(ko)); 
 
console.log('ok : ', getDisplayedText(ok));
<div dir="rtl"> 
 
    <p id='ko'>Hello (world)</p> 
 
    <p id='ok'>Hello <bdo dir='ltr'>(world)</bdo></p> 
 
</div>

そして、WebKitのは最後)をレンダリングしない理由としてフリップして、最初に...私は彼らが正しいかどうかは分かりません...

関連する問題