我正在尝试编写一个使用 <canvas>
的 Tampermonkey 用户脚本。将图片组合成单个图像,然后自动下载。
我的脚本代码:
// ==UserScript==
// @name Picture Download
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Picture Download
// @author Oray
// @match https://www.example.com/*
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js
// @grant unsafeWindow
// ==/UserScript==
(function(){
function GM_wait(){
if(typeof unsafeWindow.jQuery == 'undefined'){
window.setTimeout(GM_wait,100);
}else{
unsafeWindow.jQuery(function() { letsJQuery(unsafeWindow.jQuery); });
}}
GM_wait();
function letsJQuery($){
$('html[lang] > body').prepend('<canvas id="cve"></canvas>');
var img1 = new Image();
var img2 = new Image();
var combined = new Image();
var nloaded = 0;
var combinedx;
var filename;
var e;
function checkload(event){
nloaded++;
if (nloaded < 2){
return;
}
var canvas = document.getElementById('cve');
var context = canvas.getContext('2d');
canvas.width = img1.width;
canvas.height = img1.height + img2.height;
context.drawImage(img1, 0, 0);
context.drawImage(img2, img1.width / 2 - img2.width / 2 , img1.height);
combinedx = canvas.toDataURL('data/gif');
filename = 'myimage.png';
var lnk = document.createElement('a');
lnk.download = filename;
lnk.href = combinedx;
e = document.createEvent("MouseEvents");
e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false,false, 0, null);
lnk.dispatchEvent(e);
}
img1.onload = checkload;
img1.crossOrigin = "Anonymous";
img1.src ="https://images-na.ssl-images-amazon.com/images/I/81pNr82OTgL._SX679_.jpg";
img2.onload = checkload;
img2.crossOrigin = "Anonymous";
img2.src = "https://images-na.ssl-images-amazon.com/images/I/31W%2BDml7GsL.jpg";
}
})();
...在控制台中工作,但不作为 Tampermonkey 脚本。
为什么?
编者注:根据原标题,由于 AJAX 计时( example ),这将是一个非常常见的问题。但这个问题涵盖了具有相同基本症状的不同的、更罕见的原因。
最佳答案
如果您检查浏览器控制台 (Ctrl+Shift+J),您应该会看到如下错误:
Uncaught TypeError: Failed to execute 'initMouseEvent' on 'MouseEvent': parameter 4 is not of type 'Window'.
或者:
TypeError: Argument 4 of MouseEvent.initMouseEvent does not implement interface Window.
这是因为 window
在您的用户脚本中的这一行中具有错误的上下文:
e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false,false, 0, null);
如果您使用了unsafeWindow
,它将在脚本中运行(但不能在控制台中运行)。
如果您使用e.initMouseEvent("click", true, true);
,它将在两者中工作。
但是, initMouseEvent
is deprecated ,最好使用the MouseEvent()
constructor ;请参阅下面的代码。
另外:
- 多年来,
(function(){
一直是多余的困惑。默认情况下,用户脚本会在所有主要脚本引擎上的 jQuery 准备就绪后进行包装和触发。 - 同样,
letsJQuery
的胡言乱语也是完全没有必要的。 - 在像
canvas = document.getElementById('cve');
这样的调用之后,您需要确保在使用变量之前已定义该变量。请参阅下面的代码。
因此,这是经过这些调整的工作用户脚本:
// ==UserScript==
// @name Picture Download
// @match *://YOUR_SERVER.COM/YOUR_PATH/*
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js
// @grant GM_addStyle
// @grant GM.getValue
// ==/UserScript==
//- The @grant directives are needed to restore the proper sandbox.
/* global $ */
//$('html[lang] > body').prepend ('<canvas id="cve"></canvas>');
$('html > body').prepend ('<canvas id="cve"></canvas>');
var img1 = new Image ();
var img2 = new Image ();
var combined = new Image ();
var nloaded = 0;
var combinedx;
var filename;
var e;
img1.onload = checkload;
img1.crossOrigin = "Anonymous";
img1.src = "https://images-na.ssl-images-amazon.com/images/I/81pNr82OTgL._SX679_.jpg";
img2.onload = checkload;
img2.crossOrigin = "Anonymous";
img2.src = "https://images-na.ssl-images-amazon.com/images/I/31W%2BDml7GsL.jpg";
function checkload (event) {
nloaded++;
if (nloaded < 2) {
return;
}
var canvas = document.getElementById ('cve');
if (!canvas) {
console.warn ("No canvas.");
return;
}
var context = canvas.getContext ('2d');
canvas.width = img1.width;
canvas.height = img1.height + img2.height;
context.drawImage (img1, 0, 0);
context.drawImage (img2, img1.width / 2 - img2.width / 2, img1.height);
combinedx = canvas.toDataURL ('data/gif');
filename = 'myimage.png';
var lnk = document.createElement ('a');
lnk.download = filename;
lnk.href = combinedx;
e = new MouseEvent ("click");
lnk.dispatchEvent (e);
}
关于javascript - 我的代码可以在 Firefox 控制台中运行,但不能在 Tampermonkey 中运行? (不是时间问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54064213/