html2canvas中onclone修改后截图的垂直裁剪问题
解决方案:获取克隆文档高度动态调整截图范围
html2canvas无法直接在onclone钩子中修改初始配置的height,但可以通过先完整渲染克隆文档,再裁剪到目标范围的方式解决你的问题:
修改后的代码
function generate_screenshot() { let clonedBodyHeight; // 存储克隆文档的实际内容高度 html2canvas($("body")[0], { y: 55, // 保留顶部裁剪起点 onclone: (clonedDocument) => { // 替换textarea为div(原逻辑不变) Array.from(clonedDocument.querySelectorAll("textarea")).forEach((textArea) => { if (textArea && textArea.value.length > 30) { const labelFor = textArea.getAttribute("id") const label = clonedDocument.querySelector(`label[for="${labelFor}"]`) const div = clonedDocument.createElement("div") div.innerText = textArea.value div.style.border = "1px solid #d3d3d3" div.style.padding = "10px 10px 10px 10px" div.style.width = "100%" div.style.borderRadius = "5px" div.style.boxSizing = "border-box"; div.style.margin = "0"; div.style.backgroundColor = "white" textArea.style.display = "none" textArea.parentElement.append(label, div); } }) // 替换多选select为列表(原逻辑不变) Array.from(clonedDocument.querySelectorAll('select[multiple]')).forEach((msel) => { const multiSelect = document.querySelector("#" + msel.getAttribute("id")); if (multiSelect && multiSelect.selectedOptions.length > 1) { const clonedMultiSelect = clonedDocument.querySelector("#" + msel.getAttribute("id")); const list = clonedDocument.createElement('ul') Array.from(multiSelect.selectedOptions).forEach((option) => { const item = clonedDocument.createElement('li') item.innerHTML = option.value item.style = "list-style: none; padding-left: 0.5em" item.style.width = "100%" list.appendChild(item) }) list.style.border = "1px solid #d3d3d3" list.style.padding = "5px 5px 5px 5px" list.style.width = "100%" list.style.backgroundColor = "white" list.style.borderRadius = "5px" clonedMultiSelect.style.display = "none" clonedMultiSelect.parentElement.appendChild(list) } }); // 记录克隆文档处理后的实际滚动高度 clonedBodyHeight = clonedDocument.body.scrollHeight; }, ignoreElements: function(el) { return el.classList.contains("navbar-inverse") || el.classList.contains("dropdown-menu"); } }).then(canvas => { // 根据克隆文档的高度裁剪canvas const croppedHeight = clonedBodyHeight - 55; // 减去顶部裁剪的55px const croppedCanvas = document.createElement('canvas'); croppedCanvas.width = canvas.width; croppedCanvas.height = croppedHeight; // 从原canvas截取目标区域绘制到新canvas const ctx = croppedCanvas.getContext('2d'); ctx.drawImage(canvas, 0, 55, canvas.width, croppedHeight, 0, 0, canvas.width, croppedHeight); // 更新预览图 var img = document.createElement("img"); img.src = croppedCanvas.toDataURL("png"); img.width = croppedCanvas.width; img.height = croppedCanvas.height; $("#screenshot_preview").empty(); $("#screenshot_preview").append(img); }); }
核心逻辑说明
- 移除固定height配置:让html2canvas完整渲染
onclone修改后的克隆文档,避免因初始高度不匹配导致的截断或空白 - 记录克隆文档高度:在
onclone处理完所有DOM修改后,获取克隆文档的body.scrollHeight,这就是修改后的实际内容高度 - 裁剪canvas到目标范围:利用Canvas API的
drawImage方法,从原canvas的y=55位置开始,截取高度为克隆后高度-55的区域,得到精确匹配内容的截图
这种方案完全适配页面动态变化的尺寸,不需要设置固定高度,同时解决了textarea和多选框的截图问题。
内容的提问来源于stack exchange,提问作者Vincent
相关产品推荐
相关产品推荐

