mirror of
https://gitee.com/ulthon/ulthon_information.git
synced 2026-07-01 18:32:48 +08:00
fix(phoneimage): 修复渲染分页截断 - 测高包含margin并等待图片加载
This commit is contained in:
@@ -98,6 +98,9 @@ var PhoneImageEngine = (function () {
|
|||||||
// 从预览区读取已预处理的内容
|
// 从预览区读取已预处理的内容
|
||||||
syncPreview();
|
syncPreview();
|
||||||
var previewEl = document.getElementById('render-preview');
|
var previewEl = document.getElementById('render-preview');
|
||||||
|
|
||||||
|
// 等待预览区内所有图片加载完成,否则 getBoundingClientRect 测高为0
|
||||||
|
waitForImages(previewEl).then(function () {
|
||||||
var cleanHtml = previewEl ? previewEl.innerHTML : '';
|
var cleanHtml = previewEl ? previewEl.innerHTML : '';
|
||||||
var blocks = parseHtmlToBlocks(cleanHtml);
|
var blocks = parseHtmlToBlocks(cleanHtml);
|
||||||
|
|
||||||
@@ -111,7 +114,7 @@ var PhoneImageEngine = (function () {
|
|||||||
// 封面页
|
// 封面页
|
||||||
pages.push(generateCoverPage(sizeConfig));
|
pages.push(generateCoverPage(sizeConfig));
|
||||||
|
|
||||||
// 内容分页(使用 captureEditorBlocks,T3 会完善截图逻辑)
|
// 内容分页
|
||||||
captureEditorBlocks(cleanHtml, blocks, contentAreaHeight, sizeConfig).then(function(contentPages) {
|
captureEditorBlocks(cleanHtml, blocks, contentAreaHeight, sizeConfig).then(function(contentPages) {
|
||||||
pages = pages.concat(contentPages);
|
pages = pages.concat(contentPages);
|
||||||
|
|
||||||
@@ -145,6 +148,7 @@ var PhoneImageEngine = (function () {
|
|||||||
render._locked = false;
|
render._locked = false;
|
||||||
deferred.reject(err);
|
deferred.reject(err);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
@@ -204,6 +208,44 @@ var PhoneImageEngine = (function () {
|
|||||||
$('#render-preview').html(cleanHtml);
|
$('#render-preview').html(cleanHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 等待容器内所有图片加载完成
|
||||||
|
* 图片未加载时 getBoundingClientRect() 高度为0,导致分页计算错误
|
||||||
|
* @param {HTMLElement} containerEl
|
||||||
|
* @returns {jQuery Deferred}
|
||||||
|
*/
|
||||||
|
function waitForImages(containerEl) {
|
||||||
|
var deferred = $.Deferred();
|
||||||
|
var imgs = containerEl ? containerEl.querySelectorAll('img') : [];
|
||||||
|
if (imgs.length === 0) {
|
||||||
|
return deferred.resolve().promise();
|
||||||
|
}
|
||||||
|
var loaded = 0;
|
||||||
|
var total = imgs.length;
|
||||||
|
var timer = setTimeout(function () {
|
||||||
|
// 超时保底:3秒后强制继续
|
||||||
|
deferred.resolve();
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
function checkDone() {
|
||||||
|
loaded++;
|
||||||
|
if (loaded >= total) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < imgs.length; i++) {
|
||||||
|
if (imgs[i].complete && imgs[i].naturalHeight > 0) {
|
||||||
|
checkDone();
|
||||||
|
} else {
|
||||||
|
imgs[i].onload = checkDone;
|
||||||
|
imgs[i].onerror = checkDone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将HTML解析为块级元素数组
|
* 将HTML解析为块级元素数组
|
||||||
* 每个块: { type, html, estimatedHeight }
|
* 每个块: { type, html, estimatedHeight }
|
||||||
@@ -392,30 +434,21 @@ var PhoneImageEngine = (function () {
|
|||||||
|
|
||||||
var previewChildren = Array.prototype.slice.call(previewEl.children);
|
var previewChildren = Array.prototype.slice.call(previewEl.children);
|
||||||
|
|
||||||
// 逐组测高
|
// 逐 block 精确测高(包含 margin,否则分页偏小导致内容溢出)
|
||||||
for (var gi = 0; gi < groups.length; gi++) {
|
for (var gi = 0; gi < groups.length; gi++) {
|
||||||
var group = groups[gi];
|
var group = groups[gi];
|
||||||
var groupHeight = 0;
|
|
||||||
|
|
||||||
for (var j = 0; j < group.domIndices.length; j++) {
|
for (var j = 0; j < group.blocks.length; j++) {
|
||||||
var di = group.domIndices[j];
|
var di = group.domIndices[j];
|
||||||
if (di < previewChildren.length) {
|
if (di < previewChildren.length) {
|
||||||
var rect = previewChildren[di].getBoundingClientRect();
|
var el = previewChildren[di];
|
||||||
groupHeight += Math.round(rect.height);
|
var rect = el.getBoundingClientRect();
|
||||||
|
var cs = window.getComputedStyle(el);
|
||||||
|
var mt = parseFloat(cs.marginTop) || 0;
|
||||||
|
var mb = parseFloat(cs.marginBottom) || 0;
|
||||||
|
group.blocks[j].estimatedHeight = Math.round(rect.height + mt + mb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groupHeight === 0) groupHeight = group.blocks.length * 40;
|
|
||||||
|
|
||||||
// 按比例分配测量的实际高度给组内各个 block
|
|
||||||
var totalEstimated = 0;
|
|
||||||
for (var k = 0; k < group.blocks.length; k++) {
|
|
||||||
totalEstimated += (group.blocks[k].estimatedHeight || 40);
|
|
||||||
}
|
|
||||||
for (var k = 0; k < group.blocks.length; k++) {
|
|
||||||
var ratio = (group.blocks[k].estimatedHeight || 40) / (totalEstimated || 1);
|
|
||||||
group.blocks[k].estimatedHeight = Math.round(groupHeight * ratio);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 给尚未设置高度的 block 设默认值
|
// 给尚未设置高度的 block 设默认值
|
||||||
|
|||||||
Reference in New Issue
Block a user