Range.extractContents()提取并删除选中的Range对象,返回一个document.fragment对象,相当于我们的剪切功能。使用这个方法的话,剪切后跨标签会自动补全开始和闭合标签。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>Web 富文本编辑器 iframe 实现方式</title>
<meta content="black" name="apple-mobile-web-app-status-bar-style" />
<meta content="telephone=no" name="format-detection" />
<style>
html,
body {
height: 100%;
}
</style>
</head>
<body>
源码显示区
<textarea id="txtYuan" style="width:600px;height:200px"> </textarea>
<p>
实时编辑区
<iframe
id="editor"
width="600px"
height="200px"
style="border: solid 1px"
></iframe>
</p>
<input
type="text"
id="path"
value="./da335beafec55b073589aaf536d4d3ef.jpg"
/>
<p>
<input type="button" id="insert_img" value="插入图片" />
<!-- <input type="button" id="preview" value="预览" />
<input type="button" id="btnYuan" value="显示源码" /> -->
<input type="button" id="btnB" value="加粗/正常" />
<!-- <input type="button" id="btnLink" value="添加链接" /> -->
<input type="button" id="btnBg" value="添加背景色" />
<input type="button" id="btnItalic" value="斜体字" />
<input type="button" id="btnUnderline" value="加下划线" />
<input type="button" id="btnOpenType" value="openType字体" />
<input type="button" id="btn2pdf" value="转pdf" />
</p>
预览区
<div style="border: 1px dashed #ccc; padding: 20px" id="preview_area"></div>
canvas视图
<div id="canvasEle"></div>
<script src="//cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.22/pdfmake.min.js"></script>
<script src="//html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<script>
const iframe = document.getElementById("editor");
iframe.contentWindow.document.designMode = "on";
iframe.contentWindow.document.contentEditable = true;
// 在iframe中插入一张图片
document
.getElementById("insert_img")
.addEventListener("click", function () {
// iframe.contentWindow.document.execCommand(
// "insertImage",
// false,
// document.getElementById("path").value
// );
// return;
// 返回插入符号当前位置的selection对象
const selection = iframe.contentWindow.getSelection();
// 获取包含当前节点的文档片段
const range = selection.getRangeAt(0);
// 创建需追加到光标处节点的文档片段
const fragment = range.createContextualFragment(
`<img src="${
document.getElementById("path").value
}" crossOrigin="anonymous" alt="">`
);
// 将创建的文档片段插入到光标处
range.insertNode(fragment.lastChild);
});
// DOM 变动观察器(Mutation observer)
const fun = function () {
document.getElementById("preview_area").innerHTML =
iframe.contentWindow.document.body.innerHTML;
document.getElementById("txtYuan").innerHTML =
iframe.contentWindow.document.body.innerHTML;
};
const observerOptions = {
childList: true, // 观察目标子节点的变化,是否有添加或者删除
attributes: true, // 观察属性变动
subtree: true, // 观察后代节点,默认为 false
characterData: true, //观察文本内容
};
const observer = new MutationObserver(function (MutationRecord) {
console.log("MutationRecord", MutationRecord);
window.requestAnimationFrame(fun);
});
observer.observe(iframe.contentWindow.document.body, observerOptions);
//加粗/正常
document.getElementById("btnB").addEventListener("click", function () {
iframe.contentWindow.document.execCommand("bold", false, null);
});
//加下划线
document
.getElementById("btnUnderline")
.addEventListener("click", function () {
iframe.contentWindow.document.execCommand("underline", false, null);
});
//添加背景色
document.getElementById("btnBg").addEventListener("click", function () {
iframe.contentWindow.document.execCommand(
"hiliteColor",
false,
"#ff0000"
);
});
//斜体字
document
.getElementById("btnItalic")
.addEventListener("click", function () {
iframe.contentWindow.document.execCommand("italic", false, null);
});
//openType字体
document
.getElementById("btnOpenType")
.addEventListener("click", function () {
// 返回插入符号当前位置的selection对象
const selection = iframe.contentWindow.getSelection();
// 获取包含当前节点的文档片段
const range = selection.getRangeAt(0);
// 创建节点
const span = document.createElement("span");
span.style.color = "#f00";
// span标签appendChild添加range.extractContents提取并删除range对象
span.appendChild(range.extractContents());
range.insertNode(span);
});
//转PDF
document.getElementById("btn2pdf").addEventListener("click", function () {
//Convert Table to PDF.
html2canvas(iframe.contentWindow.document.body).then(function (canvas) {
console.log(
'document.getElementById("canvasEle")',
document.getElementById("canvasEle")
);
document.getElementById("canvasEle").appendChild(canvas);
const data = canvas.toDataURL();
const docDefinition = {
content: [
{
image: data,
width: 500,
},
],
};
pdfMake.createPdf(docDefinition).download("JSON.pdf");
});
});
</script>
</body>
</html>