Skip to content

Instantly share code, notes, and snippets.

@ricky9w
Created July 17, 2024 07:23
Show Gist options
  • Save ricky9w/bcae71989c79d11d08dad691d0a2db36 to your computer and use it in GitHub Desktop.
Save ricky9w/bcae71989c79d11d08dad691d0a2db36 to your computer and use it in GitHub Desktop.
Create a long screenshot of all elements in a scrollable container
// ==UserScript==
// @name Long Screenshot Creator for Scrollable Container
// @namespace https://rikko.top
// @version 0.1
// @description Create a long screenshot of all elements in a scrollable container
// @author ricky9w
// @email [email protected]
// @match https://*/*
// @grant none
// @require https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js
// ==/UserScript==
(function() {
'use strict';
// 创建一个按钮来触发截图
const button = document.createElement('button');
button.textContent = '创建长截图';
button.style.position = 'fixed';
button.style.top = '10px';
button.style.right = '10px';
button.style.zIndex = '9999';
document.body.appendChild(button);
button.addEventListener('click', createLongScreenshot);
async function createLongScreenshot() {
// 假设可滚动容器的选择器是 '.scrollable-container'
const scrollableContainer = document.querySelector('div.scroller---esn7');
if (!scrollableContainer) {
alert('找不到可滚动容器');
return;
}
const targetElements = [];
let lastScrollHeight = -1;
while (scrollableContainer.scrollTop < scrollableContainer.scrollHeight) {
// 检查是否到达底部
if (lastScrollHeight === scrollableContainer.scrollHeight) {
break;
}
lastScrollHeight = scrollableContainer.scrollHeight;
// 获取当前可见的目标元素
const visibleElements = Array.from(scrollableContainer.querySelectorAll('div.drag-wrapper---smTQ'))
.filter(el => isElementVisible(el, scrollableContainer));
targetElements.push(...visibleElements);
// 滚动容器
scrollableContainer.scrollTop += scrollableContainer.clientHeight;
// 等待一段时间,以便新内容加载(如果有的话)
await new Promise(resolve => setTimeout(resolve, 1000));
}
// 重置滚动位置
scrollableContainer.scrollTop = 0;
// 创建一个新的容器来存放所有元素
const container = document.createElement('div');
container.style.position = 'absolute';
container.style.left = '-9999px';
container.style.width = scrollableContainer.clientWidth + 'px';
// 复制所有相关的样式表
document.querySelectorAll('style, link[rel="stylesheet"]').forEach(styleSheet => {
container.appendChild(styleSheet.cloneNode(true));
});
// 将所有元素的克隆添加到新容器中
targetElements.forEach(element => {
const clone = element.cloneNode(true);
preserveComputedStyles(element, clone);
container.appendChild(clone);
});
// 将容器添加到文档中
document.body.appendChild(container);
// 使用 html2canvas 创建截图
html2canvas(container, {
allowTaint: true,
useCORS: true,
scale: 2 // 提高分辨率
}).then(canvas => {
// 将 canvas 转换为图片 URL
const imgData = canvas.toDataURL('image/png');
// 创建下载链接
const link = document.createElement('a');
link.href = imgData;
link.download = 'long_screenshot.png';
link.click();
// 清理:移除临时容器
document.body.removeChild(container);
});
}
function isElementVisible(el, container) {
const { top, bottom } = el.getBoundingClientRect();
const containerRect = container.getBoundingClientRect();
return top < containerRect.bottom && bottom > containerRect.top;
}
function preserveComputedStyles(sourceElement, targetElement) {
const computedStyle = window.getComputedStyle(sourceElement);
for (const property of computedStyle) {
targetElement.style[property] = computedStyle.getPropertyValue(property);
}
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment