9

我使用 ruby​​ 注释将假名添加到日文文本中:

<ruby><rb>漢&lt;/rb><rt>かん</rt></ruby><ruby><rb>字&lt;/rb><rt>じ&lt;/rt></ruby>

当我尝试选择汉字并在 Safari 或 Chrome 中复制时,剪贴板如下所示:

漢
かん
字

我也无法从 OS X 的字典中查找这个词。

有什么方法可以防止选择假名吗?rt { -webkit-user-select: none; }似乎不起作用。

4

3 回答 3

4

看来,如果将它们包装在一个<ruby>元素中,如下所示:

<ruby>
  <rb>漢&lt;/rb><rt>かん</rt>
  <rb>字&lt;/rb><rt>じ&lt;/rt>
</ruby>

这样就可以在不选择汉字的情况下选择汉字。


更新:

对于像间に合わせる这样的汉字假名混合文本,您可以:

  1. 使用空<rt>元素,如下所示:

    <ruby>
        <rb>間&lt;/rb><rt>ま&lt;/rt>
        <rb>に&lt;/rb><rt></rt>
        <rb>合&lt;/rb><rt>あ&lt;/rt>
        <rb>わせる&lt;/rb><r‌​t></rt>
    </ruby>
    
  2. 编写一些 javascript,利用剪贴板事件* †

    • HTML:

      <ruby>
        <rb>間&lt;/rb><rt>ま&lt;/rt>
      </ruby>
      に
      <ruby>
        <rb>合&lt;/rb><rt>あ&lt;/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; }

于 2013-03-30T13:13:33.537 回答
3

这是执行此操作的香草 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(' ', '')如果您不希望用户最终得到额外的空格,也可能很有用。这些对于您的用例可能合适,也可能不合适。

于 2015-12-05T23:55:20.023 回答
1

基于 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>振&lt;/rb><rt>ふ&lt;/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>振&lt;rt>ふ&lt;/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;
      }
    }
  }

});
于 2017-03-18T23:32:23.623 回答