简体   繁体   English

JavaScript click()方法仅在Chrome扩展程序中运行一次

[英]JavaScript click() method only works once in Chrome extension

I'm trying to download multiple files in a Chrome extension. 我正在尝试在Chrome扩展程序中下载多个文件。 The following code creates a dummy link to a file, then triggers the .click() event which downloads the file. 以下代码创建指向文件的虚拟链接,然后触发下载文件的.click()事件。 The problem is that only the first .click() event triggers a download. 问题是只有第一个.click()事件才会触发下载。 Subsequent .click() events are ignored. 后续的.click()事件将被忽略。

Here the manifest.json : 这里的manifest.json

{
  "name": "Simple File Downloader",
  "version": "0.1",
  "permissions": ["contextMenus", "http://*/"],
  "background": {
    "persistent": false,
    "scripts": ["sample.js"]
  },
  "content_security_policy": "script-src 'self'; object-src 'self'",
  "manifest_version": 2
}

Here the sample.js : 这里是sample.js

function onClickHandler(info, tab) {
    var a = document.createElement('a');
    a.href = 'http://or.cdn.sstatic.net/chat/so.mp3';
    a.download = 'so.mp3';
    document.body.appendChild(a);
    a.click(); // this click triggers the download
    // this timeout violates content security policy
    // setTimeout(a, 300); 
    a.click(); // this click doesn't do anything
    document.body.removeChild(a);

    a = document.createElement('a');
    a.href = 'http://or.cdn.sstatic.net/chat/so.mp3';
    a.download = 'so.mp3'; 
    document.body.appendChild(a);
    a.click(); // this click doesn't do anything either
    document.body.removeChild(a);
};

chrome.contextMenus.onClicked.addListener(onClickHandler);
chrome.runtime.onInstalled.addListener(function() {
  chrome.contextMenus.create({"title": "Download File", "id":"download_file"});
});

I've tried: 我试过了:

Surprised why it's so hard to simply save multiple files. 很惊讶为什么简单地保存多个文件是如此困难。 Appreciate any help. 感谢任何帮助。

The trick is not to use the element.click method but rather to create multiple MouseEvent . 诀窍不是使用element.click方法而是创建多个MouseEvent For this to work, you'd need to create one MouseEvent for each time you need a click. 为此,您需要在每次需要单击时创建一个MouseEvent

function clicker(el, clickCount) {
  var mousedownEvent;
  while(clickCount--) {
    mousedownEvent = document.createEvent("MouseEvent");
    mousedownEvent.initMouseEvent("click", true, true, window, 0, null, null, null, null, false , false, false, false, 0, null);
    el.dispatchEvent(mousedownEvent);
  }
}

clicker(a, 3);
// your anchor 'a' gets clicked on 3 times.

When using this method in Chrome though, you get a warning from the browser asking "This site is attempting to download multiple files. Do you want to allow this? [Deny] [Allow]" . 但是,在Chrome中使用此方法时,您会收到来自浏览器的警告,询问“此网站正在尝试下载多个文件。您要允许这样做吗?[拒绝] [允许]” So, if you do this inside an extension's background page, the background page receives the warning, the user can't see it, so the user has no way to click "Allow". 因此,如果您在扩展程序的后台页面中执行此操作,则后台页面会收到警告,用户无法看到它,因此用户无法单击“允许”。

A (gross/nasty) workaround is to create a tab that "clicks" the anchor. (粗略/讨厌)解决方法是创建一个“点击”锚点的选项卡。 Something like this: 像这样的东西:

function _anchorDownloader(url, filename) {
  var timeout = 500;
  return 'javascript:\'<!doctype html><html>'+
    '<head></head>' +
    '<script>' +
      'function initDownload() {'+
        'var el = document.getElementById("anchor");'+
        'el.click();' +
        'setTimeout(function() { window.close(); }, ' + timeout + ');' +
      '}'+
    '</script>' +
    '<body onload="initDownload()">' +
      '<a id="anchor" href="' + url + '" download="'+ filename + '"></a>'+
    '</body>' +
    '</html>\'';
};

function downloadResource(info, tab) {
  // ...
  chrome.tabs.create( { 'url' : _anchorDownloader( url, filename ), 'active' : false  } );
  // ...
}

chrome.contextMenus.create({"title": "Save Image…", "contexts":["image"], "onclick": downloadResource });

For this to work, the extension has to have "tabs" as a permission in the manifest.json . 为此,扩展必须将"tabs"作为manifest.json中permission You can tweak the timeout to close the tab, however, if you close it too fast then no download will happen. 您可以调整超时以关闭选项卡,但是,如果您关闭它太快,则不会发生下载。

Instead of using the .live() methode which is no longer recommended try .on() 而不是使用不再推荐的.live()方法,尝试.on()

$(document).on("click", "a", function( event ){
    // do whatever
});

here is the documentation 这是文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM