Chrome Selection.addRange()没有选择(execCommand('copy')用例)

fau*_*ant 5 javascript clipboard google-chrome execcommand

在Chrome中编写一个微小的浏览器扩展程序,将特定网页中的某些特定文本复制到剪贴板.在HTML格式中,人们可以将其粘贴到word,outlook等办公程序中.

document.execCommand('copy')是我使用的命令,它由一个document.onkeydown组合键(Alt + 1)触发,它工作正常 - 但只是第一次.如果您尝试再次按下组合键,它将不执行任何操作.

我找到了它的原因,document.queryCommandEnabled("copy")第一次返回true,任何额外的尝试都返回false.如果我重新加载页面,它第一次再次返回true.此外,如果我在加载页面后点击浏览器窗口外部,然后在浏览器中单击并使用组合键,则会立即返回false,即使是第一次.

function copy(text) {
  var sel = document.createElement("div"); // Creating temporary holder for text to copy

  sel.style.opacity = 0;             sel.style.position = "absolute";  // These are not really required,
  sel.style.pointerEvents = "none";  sel.style.zIndex = -1;            // at least for Chrome

  sel.innerHTML = text; // Put the text to copy into the temporary holder

  document.body.appendChild(sel); // Add the temporary holder to the page

  var range = document.createRange();     // All this is required to select the text,
  range.selectNode(sel);                  // since the holder is not an editable text
  window.getSelection().addRange(range);  // field and must be treated differently.

  // document.designMode = 'on'; (Tried this, no effect)

  /* Debugging */ alert("Enabled = " + document.queryCommandEnabled("copy") + " Design mode = " + document.designMode);

  try {
    document.execCommand('copy'); // Copy to clipbopard
  }
  catch (err) {
    alert('Unable to copy');
    console.log('Unable to copy'); // Copy failed?!
  }

  // document.designMode = 'off'; (Tried this, no effect)

  document.body.removeChild(sel); // Clean up removing the temporary holder
}

document.onkeydown=function(e){
  if(e.altKey && e.which == 49) { // Alt+1
    copy(link_variable);
    return false;
  }
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

添加清单文件:

{
  "manifest_version": 2,
  "name": "Usage text",
  "version": "0.2",
  "description": "Whatever",
  "content_scripts": [
    {
      "matches": [
        "*://some.specific.site.com/*"
      ],
      "js": ["content.js"]
    }
  ],
  "background": {
    "scripts": ["background.js"]
  },
  "browser_action": {
      "name": "Whatever",
      "default_icon": "icon.png"
  },
  "permissions": [
    "tabs",
    "clipboardWrite"
  ]
}
Run Code Online (Sandbox Code Playgroud)

更新:

将操作从内容脚本转移到后台脚本,无需更改.

try*_*lly 6

尝试Chromium 59问题时的代码记录了此警告:

[Deprecation]已删除Selection.addRange()合并现有Range和指定Range的行为.有关详细信息,请参阅https://www.chromestatus.com/features/6680566019653632.

  1. 引导我看到提到的Chrome状态

    如果文档已经有文本选择并且调用了Selection.addRange(),则Blink会将Range和现有文本选择合并为一个(如果它们有重叠),否则不执行任何操作.我们将对其进行更改,以便Blink始终忽略Range.它与Edge匹配.

    哪一个

  2. 使我在对W3C规范讨论哪些

  3. 让我读了W3C规范.

addRange()如果已经有选择,根据规范应该什么都不做:

  1. 如果rangeCount不为0,则中止这些步骤.

有趣的是,似乎已经有了选择.检查window. getSelection().rangeCount确认了这个.我无法解释为什么会这样,但这是问题中提到的问题的原因.

removeAllRanges()之前打电话addRange()解决了这个问题:

var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
Run Code Online (Sandbox Code Playgroud)