在之前的文章中,我们有讲过,如何使用扩展字段来此入HTML代码并添加预览功能。
文章链接可查看:https://www.hmgs.com.cn/News1/883.html
然后我们今天突然想给发布文章的详情也增加这样一个功能。
开始干活,第一步,由于我们使用的是layui的拟态窗口,所以我们先强制一下大小,这个宽度一般以前端详情页的宽度为准。方便后期生成的预览和前端宽度差不多大。
<style>
.layui-layer-page{
max-width: 960px
}
</style>第二步:在后台的content.html中,我们找到新发布文章的内容详情位置:如下代码,
{if([$field_editor])}
<div class="layui-form-item">
<label class="layui-form-label">内容详情</label>
{fun=editor_toolbar('editor', '内容详情')}
<div class="layui-input-block hide">
<script id="editor" name="content" type="text/html" style="width:100%"></script>
</div>
</div>
{/if}然后我们在中间添加如下的代码,,即可判断语句结束前插入代码。
由于使用了 {fun=editor_toolbar('editor', '内容详情')},说明用的是 UEditor 编辑器,编辑器的内容不是通过 .val() 获取的,而是通过 UEditor 提供的 JS API 获取的。
<a class="layui-btn layui-btn-normal" id="previewBtn" style="margin-top:10px; margin-left: 130px;">预览HTML</a>
<script>
$(document).ready(function () {
$("#previewBtn").click(function () {
// 1. 获取编辑器内容
var htmlContent = UE.getEditor('editor').getContent();
// 2. 构造 iframe 容器
var previewHtml = `
<iframe id="previewFrame" style="width:100%;height:100%;border:none; max-width:960px;"></iframe>
`;
// 3. 打开 Layui 弹窗
layer.open({
type: 1,
title: 'HTML预览',
area: ['90%', '90%'],
content: previewHtml,
success: function(layero, index) {
var iframe = document.getElementById('previewFrame');
var doc = iframe.contentDocument || iframe.contentWindow.document;
// 4. 构造完整 HTML(引入前端 CSS,目的是让他的显示和前端显示的效果相似,如果不引入前端CSS也是可以的,只是显示出来并不是前端的效果。依旧可以预览的。)
var fullHtml = `
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="/template/peoplesj/bootstrap/css/bootstrap.min.css" >
<link rel="stylesheet" href="/template/peoplesj/font-awesome-4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="/template/peoplesj/css/aoyun.css?v=345345" >
<link rel="stylesheet" href="/template/peoplesj/swiper-4.3.5/css/swiper.min.css">
<link rel="stylesheet" href="/template/peoplesj/css/animate.css">
<link rel="stylesheet" href="/template/peoplesj/css/style.css?v=345345" >
<link rel="stylesheet" href="/template/peoplesj/css/media.css?v=345345" >
<style>body { padding: 20px; }</style>
</head>
<body>
${htmlContent}
</body>
</html>
`;
// 5. 写入内容到 iframe
doc.open();
doc.write(fullHtml);
doc.close();
}
});
});
});
</script>第三步:我们需要在修改文章内容的时候,也加入这段代码。
找到修改代码的位置:
{if([$field_editor])}
<div class="layui-form-item">
<label class="layui-form-label">内容详情</label>
{fun=editor_toolbar('editor', '内容详情')}
<div class="layui-input-block hide" >
<script id="editor" name="content" type="text/html" style="width:100%">{fun=decode_string([$content->content])}</script>
</div>
</div>
{/if}在判断语句结束前加入:
<a class="layui-btn layui-btn-normal" id="previewBtn" style="margin-top:10px; margin-left: 130px;">预览HTML</a>
<script>
$(document).ready(function () {
$("#previewBtn").click(function () {
var htmlContent = UE.getEditor('editor').getContent(); // 获取内容
// 构造带有 CSS 的预览 HTML
var previewHtml = `
<iframe id="previewFrame" style="width:100%;height:100%;border:none;"></iframe>
`;
// 打开弹层(弹层里加 iframe 容器)
layer.open({
type: 1,
title: 'HTML预览',
area: ['90%', '90%'],
content: previewHtml,
success: function(layero, index) {
// 获取 iframe 的 document
var iframe = document.getElementById('previewFrame');
var doc = iframe.contentDocument || iframe.contentWindow.document;
// 构造完整 HTML(引入 CSS)
var fullHtml = `
<html>
<head>
<link rel="stylesheet" href="/template/peoplesj/bootstrap/css/bootstrap.min.css" >
<link rel="stylesheet" href="/template/peoplesj/font-awesome-4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="/template/peoplesj/css/aoyun.css?v=345345" >
<link rel="stylesheet" href="/template/peoplesj/swiper-4.3.5/css/swiper.min.css">
<link rel="stylesheet" href="/template/peoplesj/css/animate.css">
<link rel="stylesheet" href="/template/peoplesj/css/style.css?v=345345" >
<link rel="stylesheet" href="/template/peoplesj/css/media.css?v=345345" >
<style>
body { padding: 20px; }
</style>
</head>
<body>
${htmlContent}
</body>
</html>
`;
// 写入 iframe
doc.open();
doc.write(fullHtml);
doc.close();
}
});
});
});
</script>然后代码工程就结束了。
我们来看一下效果。前提是发布文章的时候,不是复制别的地方的文章带有CSS,才会显示前端的CSS效果,如果本身复制进来的文章又自带了CSS,一般就是看哪一个样式的优先级别更高了。

缺点就是目前要引入前端CSS的时候,我是把路径写死了。平时自己做一个网站两个网站并无所谓,自己修改一下代码即可,但是如果网站多,就要想想如何解决来得方便一些。
目前我们想到的一个方案就是在后台添加一个字段用于填写不同网站的前端CSS。例如:
我们给数据库中的ay_config添加一个字段为:htmlcss, 由于默认的字段值只有200的宽度,所以还需要修改其值的大小。
然后在后台的stystem中的config.html中找一个自己想放的位置,添加一段代码:
<div class="layui-form-item">
<label class="layui-form-label">前端CSS</label>
<div class="layui-input-inline" style="width: calc(100% - 400px)">
<textarea name="htmlcss" placeholder="请输入前端CSS的路径,方便后台预览文章时可读取前端样式" class="layui-textarea">{$configs.htmlcss.value}</textarea>
</div>
<span class="layui-icon layui-icon-about tips" data-content="请输入前端CSS的路径,方便后台预览文章时可读取前端样式"></span>
</div>这样我们就可以通过后台来修改前端的CSS了。不同的网站到时候就方便修改这个了。

然后在后台的发布文章的预览功能位置我们将上面预览HTML的代码部分中的引入CSS部分可以直接使用:
{$configs.htmlcss.value}但是如果直接调用的话,发现很多符号被转义了,导致无法正常显示。
所以我们需要修改代码,改成如下的代码,进行重新解码。
<script>
$(document).ready(function () {
$("#previewBtn").click(function () {
var htmlContent = UE.getEditor('editor').getContent(); // 获取内容
var encodedHtml = `{$configs.htmlcss.value}`;
// 解码
var tempDiv = document.createElement("div");
tempDiv.innerHTML = encodedHtml;
var decodedHtml = tempDiv.innerText || tempDiv.textContent;
// 重新赋值为 HTML
tempDiv.innerHTML = decodedHtml;
decodedHtml = tempDiv.innerHTML;
var previewHtml = `
<iframe id="previewFrame" style="width:100%;height:100%;border:none;"></iframe>
`;
layer.open({
type: 1,
title: 'HTML预览',
area: ['90%', '90%'],
content: previewHtml,
success: function (layero, index) {
var iframe = document.getElementById('previewFrame');
var doc = iframe.contentDocument || iframe.contentWindow.document;
var fullHtml = `
<html>
<head>
${decodedHtml}
<style>
body { padding: 20px; }
</style>
</head>
<body>
${htmlContent}
</body>
</html>
`;
doc.open();
doc.write(fullHtml);
doc.close();
}
});
});
});
</script>这样修改之后就可以正常使用了。
我们的网站后台默认有一个留言的提醒数据:但是如果要有多个留言表单,那么我们自定义的留言表单却没有这个...
在之前的文章中,我们有讲过,如何使用扩展字段来此入HTML代码并添加预览功能。文章链接可查看:https://ww...
以下内容来源于PB交流QQ群。第一:NGINX配置。#拦截常见敏感后台路径访问(例如dede、admin、wp-login等),...
在外贸网站建设中,我们会遇到有客户说需要用户前端留言的时候可以上传自定义的文件或者图片等资料。那么这...