我使用 ruby 注释将假名添加到日文文本中:
<ruby><rb>漢</rb><rt>かん</rt></ruby><ruby><rb>字</rb><rt>じ</rt></ruby>
当我尝试选择汉字并在 Safari 或 Chrome 中复制时,剪贴板如下所示:
漢
かん
字
我也无法从 OS X 的字典中查找这个词。
有什么方法可以防止选择假名吗?rt { -webkit-user-select: none; }
似乎不起作用。
我使用 ruby 注释将假名添加到日文文本中:
<ruby><rb>漢</rb><rt>かん</rt></ruby><ruby><rb>字</rb><rt>じ</rt></ruby>
当我尝试选择汉字并在 Safari 或 Chrome 中复制时,剪贴板如下所示:
漢
かん
字
我也无法从 OS X 的字典中查找这个词。
有什么方法可以防止选择假名吗?rt { -webkit-user-select: none; }
似乎不起作用。
看来,如果将它们包装在一个<ruby>
元素中,如下所示:
<ruby>
<rb>漢</rb><rt>かん</rt>
<rb>字</rb><rt>じ</rt>
</ruby>
这样就可以在不选择汉字的情况下选择汉字。
更新:
对于像间に合わせる这样的汉字假名混合文本,您可以:
使用空<rt>
元素,如下所示:
<ruby>
<rb>間</rb><rt>ま</rt>
<rb>に</rb><rt></rt>
<rb>合</rb><rt>あ</rt>
<rb>わせる</rb><rt></rt>
</ruby>
编写一些 javascript,利用剪贴板事件* †:
HTML:
<ruby>
<rb>間</rb><rt>ま</rt>
</ruby>
に
<ruby>
<rb>合</rb><rt>あ</rt>
</ruby>
わせる
Javascript:
$(document).on('copy', function (e) {
e.preventDefault(); // the clipboard data will be set manually later
// hide <rt> elements so that they won't be selected
$('rt').css('visibility', 'hidden');
// copy text from selection
e.originalEvent.clipboardData.setData('text', window.getSelection().toString());
// restore visibility
$('rt').css('visibility', 'visible');
});
这是一个演示页面‡:http: //jsfiddle.net/vJK3e/1/
* 在 Safari 6.0.3 上测试 OK †可能需要更新的浏览器
版本
rt::selection { display: none; }
这是执行此操作的香草 javascript 方式:
// hide furigana before sending and reenable after
document.addEventListener('copy', function (e) {
e.preventDefault();
var furis = document.getElementsByTagName('rt');
for (var i = 0; i < furis.length; i++) {
furis[i].style.display = 'none';
}
e.clipboardData.setData('text', window.getSelection().toString());
for (var i = 0; i < furis.length; i++) {
furis[i].style.removeProperty('display');
}
});
如上所述,添加.replace(/\n/g, '')
afterwindow.getSelection().toString()
将删除任何仍以某种方式挂起的新行。 .replace(' ', '')
如果您不希望用户最终得到额外的空格,也可能很有用。这些对于您的用例可能合适,也可能不合适。
基于 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;
}
}
}
});