diff --git a/public/static/js/phone-image.js b/public/static/js/phone-image.js index 35a448e..50d1ab7 100644 --- a/public/static/js/phone-image.js +++ b/public/static/js/phone-image.js @@ -92,6 +92,9 @@ var PhoneImageEngine = (function () { $.extend(config, userConfig); } + // 清空缓存,避免旧数据干扰 + convertedBlockCache = {}; + // 内容流事件委托(只绑定一次) $(document).off('click', '.break-inserter-btn'); $(document).off('click', '.remove-break-btn'); @@ -142,6 +145,12 @@ var PhoneImageEngine = (function () { var cleanHtml = preprocessContent(postData.content_html); var blocks = parseHtmlToBlocks(cleanHtml); + // 缓存清理:如果缓存条目过多则清空,防止内存膨胀 + var cacheKeys = Object.keys(convertedBlockCache); + if (cacheKeys.length > blocks.length * 3) { + convertedBlockCache = {}; + } + // 先渲染内容流(DOM) - 用于实测高度 renderContentFlow(blocks); @@ -181,7 +190,9 @@ var PhoneImageEngine = (function () { // 如果渲染期间有新的渲染请求排队,自动触发 if (render._pending) { render._pending = false; - render(); + render().catch(function () { + // 静默处理递归渲染失败 + }); } deferred.resolve(pages); }).catch(function (err) { @@ -553,13 +564,25 @@ var PhoneImageEngine = (function () { return [block]; } - // 按句子拆分:句号、问号、叹号、换行 - var sentences = text.split(/(?<=[。!?\n])/); + // 按句子拆分:句号、问号、叹号、换行(兼容不支持 lookbehind 的浏览器) + var effectiveFontSize = parseInt(config.fontSize, 10) || 14; + var parts = text.split(/([。!?\n])/); + var sentences = []; + var current = ''; + for (var si = 0; si < parts.length; si++) { + current += parts[si]; + if (/[。!?\n]/.test(parts[si]) && current.length > 0) { + sentences.push(current); + current = ''; + } + } + if (current) sentences.push(current); + if (sentences.length <= 1) { // 无法按句子拆分,按固定字符数拆分 sentences = []; - var chunkSize = Math.floor(getContentWidth() / config.fontSize) * - Math.floor(pageHeight / (config.fontSize * 1.8)); + var chunkSize = Math.floor(getContentWidth() / effectiveFontSize) * + Math.floor(pageHeight / (effectiveFontSize * 1.8)); if (chunkSize < 10) chunkSize = 10; for (var ci = 0; ci < text.length; ci += chunkSize) { sentences.push(text.substring(ci, ci + chunkSize)); @@ -570,7 +593,7 @@ var PhoneImageEngine = (function () { for (var j = 0; j < sentences.length; j++) { var s = sentences[j].trim(); if (!s) continue; - var h = estimateTextHeight(s, config.fontSize); + var h = estimateTextHeight(s, effectiveFontSize); result.push({ type: wrapperTag === 'blockquote' ? 'blockquote' : 'p', html: '<' + wrapperTag + '>' + s + '', @@ -610,7 +633,7 @@ var PhoneImageEngine = (function () { html += '" style="width:' + sizeConfig.width + 'px;height:' + sizeConfig.height + 'px;">'; if (hasCover) { - html += ''; + html += ''; html += '
' + escapeHtml(postData.title) + '
'; if (postData.desc) { html += '
' + escapeHtml(postData.desc) + '
'; @@ -825,7 +848,9 @@ var PhoneImageEngine = (function () { ? document.fonts.ready : $.Deferred().resolve().promise(); - fontsReady.then(function () { + fontsReady.catch(function () { + // 字体加载失败不影响截图,继续执行 + }).then(function () { requestAnimationFrame(function () { // html2canvas会跳过visibility:hidden的元素,临时切换为可见 $staging.css({ visibility: 'visible' }); @@ -1163,9 +1188,16 @@ var PhoneImageEngine = (function () { function insertPageBreak(blockIndex) { // 如果正在渲染,延迟重试 if (render._locked) { + insertPageBreak._retryCount = (insertPageBreak._retryCount || 0) + 1; + if (insertPageBreak._retryCount >= 15) { + insertPageBreak._retryCount = 0; + layer.msg('操作超时,请重试'); + return; + } setTimeout(function () { insertPageBreak(blockIndex); }, 200); return; } + insertPageBreak._retryCount = 0; var cleanHtml = preprocessContent(postData.content_html); var $temp = $('
').html(cleanHtml); @@ -1191,9 +1223,16 @@ var PhoneImageEngine = (function () { function removePageBreak(blockIndex) { // 如果正在渲染,延迟重试 if (render._locked) { + removePageBreak._retryCount = (removePageBreak._retryCount || 0) + 1; + if (removePageBreak._retryCount >= 15) { + removePageBreak._retryCount = 0; + layer.msg('操作超时,请重试'); + return; + } setTimeout(function () { removePageBreak(blockIndex); }, 200); return; } + removePageBreak._retryCount = 0; // 统计这是第几个 page-break var cleanHtml = preprocessContent(postData.content_html); diff --git a/view/admin/post/phone_image.html b/view/admin/post/phone_image.html index f16b420..a11e6b9 100644 --- a/view/admin/post/phone_image.html +++ b/view/admin/post/phone_image.html @@ -187,13 +187,13 @@ var postData = { postId: {$post.id}, - title: '{$post.title|raw}', - desc: '{$post.desc|default=""}', - coverText: '{$post->getData("cover_text")|default=""}', + title: title ?? ''); ?>, + desc: desc ?? ''); ?>, + coverText: getData('cover_text') ?? ''); ?>, contentHtml: $('#post-content-html').html(), - poster: '{$post.poster|default=""}', - authorName: '{$post.author_name|default=""}', - createTime: '{$post.create_time_text|default=""}', + poster: poster ?? ''); ?>, + authorName: author_name ?? ''); ?>, + createTime: create_time_text ?? ''); ?>, categoryName: '' };