新闻中心 网络推广 网站建设 优化推广 首页>新闻>网站建设

PB后台列表中添加预览HTML功能。

时间:2025-07-03   访问量:0

https://www.zuoan.com.cn/News3/3487.html

https://www.zuoan.com.cn/News3/3490.html

距离上面发布的文章,在发布文章和编辑文章时添加预览HTML的功能之后,我突然又想在列表上直接预览文章。

第一步:

apps/admin/model/content/ContentModel.php

获取文章列表的地方添加:

'a.content',

其他几处也相应添加,要不然后台列表处无法获取到数据。


第二步:在后台模板文件中添加代码,最终形成如下。

  {if($value->status)}                                    
                                        {if(!$value->outlink)}
                                            <input type="hidden" name="urls[[value->id]]" value="{php}echo $link{/php}">
                                            <a href="{php}echo $link{/php}" class="layui-btn layui-btn-xs layui-btn-primary"  target="_blank">查看</a>
                                        {else}
                                            <a href="[value->outlink]" class="layui-btn layui-btn-xs layui-btn-primary"  target="_blank">查看</a>  

                                        {/if}
                                        <!-- 添加的代码  -->
<input type="hidden" name="content[[value->id]]" value="[value->content]">
<a href="javascript:;" class="layui-btn layui-btn-xs btn-preview" data-id="[value->id]">列表预览</a>
<script>
layui.use(['layer', 'jquery'], function () {
    var $ = layui.jquery;
    var layer = layui.layer;

    // 只绑定一次点击事件
    $(document).off('click', '.btn-preview').on('click', '.btn-preview', function () {
        var id = $(this).data('id');
        var $input = $("input[name='content[" + id + "]']");
        if (!$input.length) {
            layer.alert("未找到 ID=" + id + " 的内容!");
            return;
        }
        var rawHtml = $input.val();

        var previewHtml = `<iframe id="previewFrame" style="width:100%;height:100%;border:none;"></iframe>`;

        layer.open({
            type: 1,
            title: '文章内容预览',
            area: ['90%', '90%'],
            content: previewHtml,
            success: function (layero, index) {
                var iframe = document.getElementById('previewFrame');
                var doc = iframe.contentDocument || iframe.contentWindow.document;
                var fullHtml = `
                    <!DOCTYPE html>
                    <html>
                    <head>
                        <meta charset="UTF-8">
                        此处可引入你前端的CSS样式,以便预览的时候显示的是你前端的效果,而不是加载后端的样式。
                        <style>
                            body { padding: 20px; font-family: "微软雅黑", sans-serif; }
                        </style>
                    </head>
                    <body>
                        ${rawHtml}
                    </body>
                    </html>
                `;
                doc.open();
                doc.write(fullHtml);
                doc.close();
            }
        });
    });
});

</script>
  <!-- 添加的代码  -->
 
                                    {else}
                                    <a href="javascript:;" class="layui-btn layui-btn-xs layui-btn-disabled">查看</a>
  
                                    {/if}


最后我们来看效果:


使用上面的方法 呢,可能我们会担心一个问题,就是在一个列表中,用

<input type="hidden" name="content[[value->id]]" value="[value->content]">

去获取的数据会不会太大了。假如列表是15篇文章,那就相当于有15篇文章的内容在这个页面中。会造成这个列表数据庞大,会不会卡顿呢?


1. 页面卡顿可能性

  • 每篇文章内容完整HTML都写在了隐藏input的value属性里,浏览器会把这些内容都加载、解析。

  • 如果内容很长,尤其有大量HTML、图片、样式等,页面源码会变得很大,初始加载时浏览器解析负担会增大,加载时间变长。

  • 隐藏字段的value存放大量HTML其实并不太合适,可能导致:

    • 页面体积变大,加载慢

    • 浏览器渲染缓慢

    • 内存占用增加

    • 如果还有JS对这些字段做操作,性能压力更大


2. 用户体验

  • 首屏加载时间变长,影响用户体验。

  • 如果用户只点击少数几篇文章预览,却加载了所有文章内容,浪费资源。

改进方案    方案A:按需加载内容

  • 页面隐藏域只保存文章的 ID、标题等轻量信息,不保存完整内容。

  • 点击“预览”按钮时,通过 Ajax 请求后台接口,传文章ID,服务器返回该文章完整内容(HTML)。

  • 前端收到内容后,再打开弹窗展示。

  • 这样初始页面只加载少量数据,提升首屏性能,点击时才加载详细内容。



所以我们第一步在后台打开API接口。


image


第二步修改代码。


      <!-- 添加的代码  -->
<input type="hidden" name="content[[value->id]]" >
<a href="javascript:;" class="layui-btn layui-btn-xs btn-preview" data-id="[value->id]">预览</a>

<script>
layui.use(['layer', 'jquery'], function () {
    var $ = layui.jquery;
    var layer = layui.layer;

    $(document).off('click.preview').on('click.preview', '.btn-preview', function () {
        var id = $(this).data('id');

        if (!id) {
            layer.alert("未获取到文章ID!");
            return;
        }

        var url = '/api.php/content/' + id;
        var loading = layer.load(2);

        $.ajax({
            type: 'GET', // 改为GET请求
            url: url,
            dataType: 'json',
            data: {
                appid: "{pboot:appid}",
                timestamp: "{pboot:timestamp}",
                signature: "{pboot:signature}"
            },
            success: function (res) {
                layer.close(loading);

                if (!res || !res.data || !res.data.content) {
                    layer.alert("未获取到文章内容!");
                    return;
                }

                var rawHtml = res.data.content;
                var iframeHtml = '<iframe id="previewFrame" style="width:100%;height:100%;border:none;"></iframe>';

                layer.open({
                    type: 1,
                    title: '文章预览',
                    area: ['90%', '90%'],
                    content: iframeHtml,
                    success: function () {
                        var iframe = document.getElementById('previewFrame');
                        var doc = iframe.contentDocument || iframe.contentWindow.document;

                        var fullHtml = `
                            <!DOCTYPE html>
                            <html>
                            <head>
                                <meta charset="UTF-8">
                                <link rel="stylesheet" href="/template/peoplesj/bootstrap/css/bootstrap.min.css">
                                <link rel="stylesheet" href="/template/peoplesj/css/style.css">
                                <style>body { padding: 20px; font-family: "微软雅黑", sans-serif; }</style>
                            </head>
                            <body>
                                ${rawHtml}
                            </body>
                            </html>
                        `;
                        doc.open();
                        doc.write(fullHtml);
                        doc.close();
                    }
                });
            },
            error: function (xhr, status, error) {
                layer.close(loading);
                console.error("请求失败:", error);
                layer.alert("请求失败:" + error);
            }
        });
    });
});
</script>


按道理,这样我们连MODE都不用修改了。未作测试,诸君可自行测试一下。

但是有一个问题,我在本地测试的时候,获取不到API,只有放在服务器上才可以。



服务咨询
1对1咨询,专业客服为您解疑答惑
联系销售
15899750475
在线咨询
联系在线客服,为您解答所有的疑问
ARE YOU INTERESTED IN ?
感兴趣吗?

有关我们服务的更多信息,请联系项目经理

15899750475 杨先生