JavaScript click()方法只能在Chrome扩展程序中使用一次 [英] JavaScript click() method only works once in Chrome extension

查看:100
本文介绍了JavaScript click()方法只能在Chrome扩展程序中使用一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Chrome扩展程序中下载多个文件.以下代码创建到文件的虚拟链接,然后触发.click()事件,该事件下载文件. 问题在于只有第一个.click()事件会触发下载.随后的.click()事件将被忽略.

I'm trying to download multiple files in a Chrome extension. The following code creates a dummy link to a file, then triggers the .click() event which downloads the file. The problem is that only the first .click() event triggers a download. Subsequent .click() events are ignored.

这是 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
}

这是 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"});
});

我尝试过:

  • different approaches for downloading files as described in Chrome Extension write to file system using FileSaver.js, with the exact same result, first file is downloaded, second one is not

按照是否有可能在javascript中进行两次.click方法调用,从而导致违反内容安全策略,因此我尝试使用

adding timeouts as described in Is it possible to make two .click method calls in javascript, resulting in content-security-policy violation, which I tried to work around using the approach described in Content-Security-Policy error in google chrome extension making, but without success

使用jQuery .live方法,如中所述jQuery单击事件仅适用一次,也没有成功,但是我不确定100%正确地实现了这一点(如果人们认为这种方法可以解决问题,可以稍后发布代码)

using the jQuery .live method as described in JQuery click event works only once, also without success, but I'm not 100% sure I implemented this one correctly (can post code later if people think this approach should solve it)

惊讶为什么简单地保存多个文件如此困难.感谢任何帮助.

Surprised why it's so hard to simply save multiple files. Appreciate any help.

推荐答案

诀窍不是使用element.click方法,而是创建多个MouseEvent.为此,您需要为每次单击创建一个MouseEvent.

The trick is not to use the element.click method but rather to create multiple MouseEvent. For this to work, you'd need to create one MouseEvent for each time you need a click.

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.

但是在Chrome中使用此方法时,浏览器会显示警告消息,提示"此站点正在尝试下载多个文件.是否要允许此操作?[拒绝] [允许]" .因此,如果在扩展程序的后台页面中执行此操作,则后台页面会收到警告,用户看不到该警告,因此用户无法单击允许".

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]". 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 });

要使其正常工作,扩展名必须在 manifest.json 中以"tabs"作为permission.您可以调整超时以关闭选项卡,但是,如果关闭得太快,则不会进行下载.

For this to work, the extension has to have "tabs" as a permission in the manifest.json. You can tweak the timeout to close the tab, however, if you close it too fast then no download will happen.

这篇关于JavaScript click()方法只能在Chrome扩展程序中使用一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆