Rox Dorentusの受け入れられた答えに基づいて(そしてjpc-aeの有用なJavascript変換を参照して)、要素のdisplay
スタイルをハッキングすることを含まないアルゴリズムの改善があり<rt>
ます。これは私には壊れやすいと感じます。
代わりに、選択範囲内のすべてのノードへの参照の配列を作成し、タグが付いたノードをフィルタリングして、<rb>
それらを返しますinnerText
。<rb>
漢字をまとめるためにタグが使用されていない場合に備えて、コメントアウトされた代替案も提供します。
document.addEventListener('copy', function (e) {
var nodesInRange = getRangeSelectedNodes(window.getSelection().getRangeAt(0));
/* Takes all <rb> within the selected range, ie. for <ruby><rb>振</rb><rt>ふ</rt></ruby> */
var payload = nodesInRange.filter((node) => node.nodeName === "RB").map((rb) => rb.innerText).join("");
/* Alternative for when <rb> isn't used: take all textNodes within <ruby> elements, ie. for <ruby>振<rt>ふ</rt></ruby> */
// var payload = nodesInRange.filter((node) => node.parentNode.nodeName === "RUBY").map((textNode) => textNode.textContent ).join("");
e.clipboardData.setData('text/plain', payload);
e.preventDefault();
/* Utility function for getting an array of references to all the nodes in the selection area,
* from: http://stackoverflow.com/a/7784176/5951226 */
function getRangeSelectedNodes(range) {
var node = range.startContainer;
var endNode = range.endContainer;
if (node == endNode) return [node];
var rangeNodes = [];
while (node && node != endNode) rangeNodes.push(node = nextNode(node));
node = range.startContainer;
while (node && node != range.commonAncestorContainer) {
rangeNodes.unshift(node);
node = node.parentNode;
}
return rangeNodes;
function nextNode(node) {
if (node.hasChildNodes()) return node.firstChild;
else {
while (node && !node.nextSibling) node = node.parentNode;
if (!node) return null;
return node.nextSibling;
}
}
}
});