- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试制作一个屏幕截图扩展,通过使用scrollTo移动窗口并在弹出窗口中将 Canvas 上的图像拼接在一起来截取整个页面的屏幕截图。然而,我的问题是,我返回的所有图像都没有被绘制/没有显示在 Canvas 上。
popup.js
function draw(ctx, image, x ,y) {
console.log(image);
var img = new Image();
img.src = image;
img.onload = function() {
ctx.drawImage(img, x, y);
console.log('x',x);
console.log('y',y);
};
}
function screenshot(response) {
console.log('screenshot');
var canvas = document.getElementById('imagecanvas'),
fullHeight = response.height,
fullWidth = response.width,
visibleHeight = response.visibleHeight,
visibleWidth = response.visibleWidth,
x = 0,
y = 0;
canvas.height = fullHeight;
canvas.width = fullWidth;
var ctx = canvas.getContext('2d');
// console.log('canvas', canvas);
// console.log('context', ctx);
//start at the top
window.scrollTo(0, 0);
while (y <= fullHeight) {
chrome.tabs.captureVisibleTab(null, {
format: 'png'
}, function (image) {
draw(ctx, image, x, y);
});
// console.log('x',x);
// console.log('y',y);
y += visibleHeight;
window.scrollTo(x, y);
}
}
chrome.tabs.query({
'active': true,
'currentWindow':true
}, function(tab){
console.log('sending message');
chrome.tabs.sendMessage(tab[0].id, {
message: 'dom'
}, function(response){
console.log('response', response);
screenshot(response);
});
});
popup.html
<!doctype html>
<html>
<head>
<title>Chrome Snapshot</title>
<style>
#imagecanvas {
z-index: 100;
}
</style>
<script src="jquery-2.0.2.min.js"></script>
<script src="popup.js"></script>
</head>
<body>
<canvas id="imagecanvas"> </canvas>
</body>
</html>
内容.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.message === 'dom') {
sendResponse({
height: document.height,
width: document.width,
visibleHeight: window.innerHeight,
visibleWidth: window.innerWidth
});
}
});
list .json
{
"manifest_version": 2,
"name": "test",
"description": "Save images and screenshots of sites to Dropbox.",
"version": "1.0",
"permissions": [
"<all_urls>",
"tabs"
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"background": {
"scripts": [
"jquery-2.0.2.min.js"
],
"persistent": false
},
"content_scripts" : [{
"all_frames": true,
"matches" : ["*://*/*"],
"js" : ["content.js"],
"run_at": "document_end"
}]
}
编辑以回应 Rob 的评论
这是我到目前为止所得到的:我可以看到页面正在滚动,但是现在,captureVisibleTab 中的图像返回为未定义。
popup.js
var ctx,
fullHeight,
fullWidth,
x,
y,
visibleHeight,
visibleWidth;
function draw(ctx, image, x ,y) {
console.log(image);
var img = new Image();
img.src = image;
img.onload = function() {
ctx.drawImage(img, x, y);
// console.log('x',x);
// console.log('y',y);
};
}
function next(tabID) {
chrome.tabs.captureVisibleTab(null, {
format: 'png'
}, function(image) {
console.log(image);
draw(ctx, image, x, y);
y += visibleHeight;
if (y < fullHeight) {
chrome.tabs.sendMessage(tabID, {
message: 'scroll',
x: x,
y: y
}, function() {
next(tabID);
});
}
});
}
function screenshot(response, tabID) {
console.log('screenshot');
var canvas = document.getElementById('imagecanvas');
fullHeight = response.height;
fullWidth = response.width;
visibleHeight = response.visibleHeight,
visibleWidth = response.visibleWidth;
x = 0,
y = 0;
canvas.height = fullHeight;
canvas.width = fullWidth;
ctx = canvas.getContext('2d');
chrome.tabs.sendMessage(tabID, {
message: 'scroll',
x: x,
y: y
}, function() {
next(tabID);
});
}
chrome.tabs.query({
active:true,
lastFocusedWindow:true
}, function(tab){
var tabID = tab[0].id;
console.log('sending message', tabID);
chrome.tabs.sendMessage(tabID, {
message: 'dom'
}, function(response){
console.log('dom info', response);
screenshot(response, tabID);
});
});
内容.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.message === 'dom') {
sendResponse({
height: document.height,
width: document.width,
visibleHeight: window.innerHeight,
visibleWidth: window.innerWidth
});
} else if (request.message == 'scroll') {
window.scrollTo(request.x, request.y);
sendResponse();
}
});
最佳答案
您的代码有两个重大问题。
第一个问题是您假设 window.scrollTo(0, 0);
滚动选项卡的内容。这不是真的,它会滚动弹出窗口的文档。
第二个问题是您在循环中调用异步方法,该方法会更改 y
每次迭代的变量。在这个captureVisibleTab
的回调中,您正在阅读y
再次变量,但由于循环结束时调用所有回调,因此它始终是相同的值。
顺便说一句,这个值也是错误的。您将循环直到 y <= fullHeight
。这实际上应该是 y < fullHeight
,因为一旦到达页面底部,就无需再进行屏幕截图。
至少,您需要将循环更改为一组(递归)回调。
// popup.js
function next() {
chrome.tabs.captureVisibleTab(null, {
format: 'png'
}, function (image) {
draw(ctx, image, x, y);
y += visibleHeight;
window.scrollTo(x, y); // TODO
next();
});
}
// Initialize recursion
next();
这个方法稍微好一点,至少你看到 Canvas 上正在画东西。但这仍然不正确,因为您仍在调用 window.scrollTo
在弹出脚本中。解决此问题的正确方法是委托(delegate) scrollTo
方法到内容脚本,并使用 message passing调用卷轴。例如:
// popup.js
//window.scrollTo(x, y); // TODO
//next();
chrome.tabs.sendMessage(null, {
request: 'scroll',
x: x,
y: y
}, next);
// contentscript.js
chrome.runtime.onMessage.addListener(function(message, sender,sendResponse) {
if (message.request == 'scroll') {
window.scrollTo(message.x, message.y);
sendResponse();
}
});
最后一个建议:我建议使用activeTab permission,而不是在所有选项卡中插入内容脚本。和 chrome.tabs.executeScript
在需要时插入内容脚本。这可以减轻您的扩展的重量,并且无需 <all_urls>
许可。
关于canvas - chrome扩展 Canvas 不在循环内绘制图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17519325/
我是 magento 的新手,目前我在 magento 安装期间遇到“必须加载 PHP 扩展 curl ”错误。你能帮帮我吗? 最佳答案 如果您的服务器上没有安装 curl,您可以键入以下命令之一来安
我在 macOS Mojave/macOS Big Sur/macOS Monterey/macOS Ventura 上使用最新的 php 版本 7.2 并收到类似错误 $composer requ
这个问题已经有答案了: Why generic type is not applicable for argument extends super class for both? (5 个回答) 已关
我正在使用 NightWatch.js 并进行一些 UI 测试,我想用一些额外的 desiredCapabilities 启动默认浏览器实例(即启用扩展并应用一些特定值)。 p> 注意:我可以执行这些
有人知道为什么我在 java 8 中使用此代码时没有服务器扩展名称吗: try { URL url = new URL(urlString); URLC
扩展提供给我的类(class)。为现有的类提供新功能。或扩展现有的mixin s 或虚拟类,任何东西都可以工作。 也许是这样的: class FlatButton {} // maybe no
我有一个关于使用 c 代码和 mod_wsgi 扩展 python 的问题。 我在 apache 服务器中有一个 django 应用程序,它查询 postgresql 数据库以生成报告。在某些报告中,
testcafe支持在Chrome浏览器中加载crx扩展吗? 如果是这样,请告诉我需要尝试什么方法。 我尝试了下面的代码,但没有成功 await t.eval(new Function(fs.read
这个问题已经有答案了: What is a raw type and why shouldn't we use it? (16 个回答) 已关闭 3 年前。 有什么区别: // 1 class A c
我正在编写一个 chrome 扩展来记录单击开始按钮后触发的请求。 这是我的文件:1. list .json { "manifest_version": 2, "name": "recorde
我每天都在使用 vim 和 perforce 现在我的问题是,如果我想查看 perforce 文件修订版,则从命令模式下的 vim :!p4 打印文件#1 vim 试图让我获得缓冲区 #1。有没有办法
大家好,我有一个关于 NUnit 扩展(2.5.10)的问题。 我想做的是向 数据库。为此,我使用 Event 创建了 NUnit 扩展 听众。 我遇到的问题是公共(public)无效 TestFin
我有弹出窗口,而不是模态窗口。 如何通过单击页面的其他部分(不在窗口中)来关闭此窗口? 最佳答案 像这样的东西: function closeWin(e, t) { var el = win.
我通常非常谨慎地使用扩展方法。当我确实觉得有必要编写一个扩展方法时,有时我想重载该方法。我的问题是,您对调用其他扩展方法的扩展方法有何看法?不好的做法?感觉不对,但我无法真正定义原因。 例如,第二个
扩展 Ant Ant带有一组预定义的任务,但是你可以创建自己的任务,如下面的例子所示。 定制Ant 任务应扩展 org.apache.tools.ant.Task 类,同时也应该拓展 execut
我想要一个重定向所有请求的扩展: http://website.com/foo.js 到: http://localhost/myfoo.js 我无法使用主机文件将主机从 website.com 编辑
对于为什么 QChartView 放在 QTabWidget 中时会扩展,我有点迷惑。 这是 QChartView 未展开(因为它被隐藏)时应用程序的图片。 应用程序的黑色部分是 QOpenGLWid
如果在连接条件中使用 OR 运算符,如何优化以下查询以避免 SQL 调优方面的 OR 扩展? SELECT t1.A, t2.B, t1.C, t1.D, t2.E FROM t1 LEFT J
一旦加载插件的问题得到解决(在 .NET 中通过 MEF 的情况下),下一步要解决的是与它们的通信。简单的方法是实现一个接口(interface),使用插件实现,但有时插件只需要扩展应用程序的工作方式
在我的 Symfony2 包中,我需要检查是否定义了一个函数(一个扩展)。更具体地说,如果安装了 KnpMenuBundle,我会在我的包中使用那个,否则我将自己渲染插件。 我试过了,但这当然不起作用
我是一名优秀的程序员,十分优秀!