在vue项目开发中,遇到一个对纯html合同文本进行在线编辑保存的需求,自己用JQuery和iframe摸索着封装了一个组件,遇到相同需求的前端友人可以参考一下,后续还要完善。(贴出完整代码)
/封装的组件contractS.vue/

<template><div class="Isecontent"><div class="Iframes" :style="{'height':clientHeight+'px !important'}"><div class="iframe-con"><img src="../assets/images/revise.png" class="iframe-revise iframe-img" @click="irevise" /><img src="../assets/images/plus.png" class="iframe-plus iframe-img" @click="iplus" /><iframe id="con-iframe" name="con-iframe" :src="iframeUrl" class="in-iframe"></iframe></div><div class="right-ul" v-if="isshows"><el-tabs v-model="activeName2" type="card" @tab-click="handleClick"><el-tab-pane label="填空列表" name="first"><div class="conspan" :id="item.id" v-for="(item,index) in tableData" :key="index"><span class="con-tent">{{item.name}}</span><el-button type="text" @click="itemi(item.id)" class="con-btn">编辑</el-button></div></el-tab-pane><el-tab-pane label="修订记录" name="second"><div class="conspan" :id="item.id" v-for="(item,index) in revisionArr" :key="index"><span class="con-tent">{{item.name}}</span><el-button type="text" @click="withdraw(index)" class="con-btn">撤回</el-button></div><p v-if="revisionArr==0 || !revisionArr"style="text-align:center">暂无修订记录</p></el-tab-pane></el-tabs></div></div><el-dialog title="编辑" width="40%" :visible.sync="dialogFormVisible"><el-form :model="form"><el-form-item label="请输入内容"><el-input v-model="form.name"></el-input></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false">取 消</el-button><el-button type="primary" @click="close()">保 存</el-button></div></el-dialog><el-dialog title="修订" :visible.sync="iseditors" width="40%" @close="closedia"><quill-editorv-model="conval"ref="myQuillEditor"style="height: 220px;margin-bottom:20px":options="editorOption"@change="onEditorChange($event)"></quill-editor><span slot="footer" class="dialog-footer"><el-button type="primary" @click="saveHtml">保 存</el-button></span></el-dialog></div>
</template>
<script>
import { quillEditor } from "vue-quill-editor";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
import $ from "jquery";
// editor工具栏配置
const toolbarOptions = [["bold"], // 加粗 斜体 下划线 删除线 -----['bold', 'italic', 'underline', 'strike']// ['blockquote', 'code-block'], // 引用  代码块-----['blockquote', 'code-block']// [{ header: 1 }, { header: 2 }], // 1、2 级标题-----[{ header: 1 }, { header: 2 }]// [{ list: 'ordered' }, { list: 'bullet' }], // 有序、无序列表-----[{ list: 'ordered' }, { list: 'bullet' }]// [{ script: 'sub' }, { script: 'super' }], // 上标/下标-----[{ script: 'sub' }, { script: 'super' }]// [{ indent: '-1' }, { indent: '+1' }], // 缩进-----[{ indent: '-1' }, { indent: '+1' }]// [{'direction': 'rtl'}], // 文本方向-----[{'direction': 'rtl'}]// [{ size: ['small', false, 'large', 'huge'] }], // 字体大小-----[{ size: ['small', false, 'large', 'huge'] }]// [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题-----[{ header: [1, 2, 3, 4, 5, 6, false] }]// [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色-----[{ color: [] }, { background: [] }]// [{ font: [] }], // 字体种类-----[{ font: [] }]// [{ align: [] }], // 对齐方式-----[{ align: [] }]// ['clean'], // 清除文本格式-----['clean']["image"] // 链接、图片、视频-----['link', 'image', 'video']
];
export default {data() {return {tableData: [], //编辑列表dialogFormVisible: false,form: {name: ""},activeName2: "first",clientHeight: null,isshows: true,conval: null,editorOption: {placeholder: "请输入内容",theme: "snow", // or 'bubble'modules: {toolbar: {container: toolbarOptions}}},iseditors: false,inputId: null,newHtml: "",revisionArr: [], //修订记录数组oldRecord: "",selectedHtml: "",settext: false};},props: {iframeUrl: {type: String,default: ""}},computed: {},methods: {// editor值改变事件onEditorChange(e) {console.log(e.html, e.text);if (e.html.indexOf("<strong") > -1) {console.log('1')// 文本加粗this.settext = true;this.selectedHtml = e.html;this.selectedval = e.text;} else if (e.html.indexOf("<img") > -1) {// 图片上传this.settext = true;}else{console.log('2')this.settext = true;this.selectedHtml = e.html;this.selectedval = e.text;}},//editor修订保存saveHtml() {if (this.settext) {console.log('3')var container = $("#con-iframe").contents()[0];var documentFragment = null;if (container.getSelection) {console.log('4')this.oldRecord = container.getSelection().toString();var range = container.getSelection().getRangeAt(0);documentFragment = container.getSelection().getRangeAt(0).cloneContents();//   documentFragment = container.selection.createRange().HtmlText;// var range = container.selection.createRange();if (container.getSelection().rangeCount == 0) {console.log('5')container.getSelection().addRange(fullSelectedRange);}}var ins = container.createElement("span");       for (var i = 0; i < documentFragment.childNodes.length; i++) {var childNode = documentFragment.childNodes[i];if (childNode.nodeType == 3) {// Text 节点// this.selectedHtml += childNode.nodeValue;console.log('6')} else {console.log('7')var nodeHtml = childNode.outerHTML;this.selectedHtml += nodeHtml;}}var originalSource = null;if (this.selectedHtml.indexOf("<span") > -1) {console.log('8')ins.setAttribute("originalSource",$(this.selectedHtml).attr("originalSource"));ins.setAttribute("id", $(this.selectedHtml).attr("id"));console.log('9')} else {console.log('10')ins.setAttribute("originalSource", this.selectedval);var newId = new Date().getTime() + "" + parseInt(Math.random() * 100);ins.setAttribute("id", newId);ins.innerHTML = this.selectedHtml;ins.style = "background:#F9B500;display:inline-block;";this.revisionArr.push({name: this.selectedval,oldtext: this.oldRecord,id: newId});}range.deleteContents();range.insertNode(ins);this.iseditors = false;// this.conval = null;} else {this.$message({message: "文本选中后编辑",type: "none"});}},//编辑弹窗保存close() {if (this.form.name) {var container = $("#con-iframe").contents()[0];$(".conspan[id=" + this.inputId + "] .con-tent").html(this.form.name);$(container).find(".input-comm[id=" + this.inputId + "]").html(this.form.name);this.dialogFormVisible = false;setTimeout(function() {$(container).find("[input-edit]").css("background-color", "rgb(203, 203, 203)");$(".conspan").removeClass("active");}, 5000);}},// 生成右侧编辑列表getspan() {// iframe 初始化var container = $("#con-iframe").contents()[0]; // iframe container// 初始化 iframe中 input-edit 默认样式$(container).find("[input-edit]").css({ "min-height": "16px" });// 刷新 填空列表let that = this;that.tableData = [];$(container).find("[input-edit]").each(function(index, value) {var id = $(this).attr("id");that.tableData.push({id: id,name: $(this).html()});});},// 右侧菜单切换handleClick(tab, event) {console.log(tab, event);},// 合同编辑 ******iframe右侧编辑******itemi(id) {this.form.name = "";this.inputId = id;// console.log(Ytop, id);var container = $("#con-iframe").contents()[0];var Ytop = parseInt($(container).find(".input-comm[id=" + id + "]").offset().top);$(container).find("[input-edit]").css("background-color", "rgb(203, 203, 203)");$(container).find(".input-comm").removeClass("active");$(".conspan").removeClass("active");$(".conspan[id=" + id + "]").addClass("active");$(container).find("[input-edit]").css("background-color", "rgb(203, 203, 203)");$(container).find(".input-comm[id=" + id + "]").css("background-color", "#18b0e2");frames["con-iframe"].document.documentElement.scrollTop = Ytop - 20;let val = $(container).find(".input-comm[id=" + id + "]").html();if (val) {this.form.name = val;}this.dialogFormVisible = true;},//修订撤回withdraw(i) {var container = $("#con-iframe").contents()[0];let lid = this.revisionArr[i].id;$(container).find("span[id=" + lid + "]").html(this.revisionArr[i].oldtext);$(container).find("span[id=" + lid + "]").css({ "background-color": "#fff", "font-weight": "100" });this.revisionArr.splice(i, 1);},//修订弹窗irevise() {var word = document.getElementById("con-iframe").contentWindow.getSelection().toString();// window.getSelection?window.getSelection():document.selection.createRange().text;// window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();if (word) {this.conval = word;this.iseditors = true;} else {this.$message({message: "鼠标未选中内容!",type: "none"});}},//修订弹窗关闭closedia() {this.conval = null;},//iframe放大iplus() {this.isshows = !this.isshows;}},created(){window.itemi = this.itemi},mounted() {this.contitle = this.$route.query;let self = this;setTimeout(() => {self.getspan();}, 1500);this.clientHeight = document.body.clientHeight - 470;},components: {quillEditor}
};
//******绑定 iframe 中 input-edit 点击事件*******
$(function() {var container = $("#con-iframe").contents()[0];// 单击事件$(container).on("click", "[input-edit]", function(e) {e.stopPropagation();e.preventDefault();if(!$(this).html()){$(container).find("[input-edit]").css("background-color", "rgb(203, 203, 203)");$(this).css("background-color", "#18b0e2");var id = $(this).attr("id");$(".conspan").removeClass("active");$(".conspan[id=" + id + "]").addClass("active");}});// 双击事件$(container).on("dblclick", "[input-edit]", function(e) {e.stopPropagation();e.preventDefault();    if(!$(this).html()){$(container).find("[input-edit]").css("background-color", "rgb(203, 203, 203)");$(this).css("background-color", "#18b0e2");var id = $(this).attr("id");$(".conspan").removeClass("active");$(".conspan[id=" + id + "]").addClass("active");// $(".el-dialog__wrapper").css({"z-index":"2003","display":"block"})parent.itemi(id)}});});
</script>
<style scoped lang="scss">
.Isecontent {.Iframes {display: flex;overflow: hidden;.iframe-con {position: relative;flex: 1;height: 100%;.iframe-img {position: absolute;top: 20px;width: 40px;z-index: 999;}.iframe-revise {right: 100px;top: 24px;height: 36px;}.iframe-plus {right: 40px;height: 40px;}.in-iframe {border: 0;width: 100%;height: 100vh;position: absolute;top: 0;overflow-y: scroll;}}.right-ul {width: 500px;.conspan {display: flex;border-bottom: 1px solid #e4e5ea;height: 30px;line-height: 30px;padding: 10px;.con-tent {flex: 1;font-size: 16px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;}.con-btn {cursor: pointer;color: #18b0e2;width: 80px;}}.active {border-left: 4px solid #18b0e2;}.el-tab-pane {overflow-y: scroll;height: 100vh;}}}.el-dialog {display: none;}
}
</style>

//大家觉得哪里有问题可以评论,共同进步,哈哈
在页面中使用组件
// xxxx.vue(组件导入和url赋值 省略)

<contractS :iframeUrl="'/static/'+name+'.htm'"></contractS>

//希望小小的分享能帮助到你们,快乐来源于技术分享,点个赞再走呗

vue中实现及封装html合同文本在线编辑保存的功能相关推荐

  1. axios 超时_聊聊 Vue 中 axios 的封装

    axios 是 Vue 官方推荐的一个 HTTP 库,用 axios 官方简介来介绍它,就是: Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中. 作为一 ...

  2. vue中添加附件以及表单内表格动态添加的功能实现

    vue前端表单自动生成地址 form-generator vue中添加附件以及表单内表格动态添加的功能实现 页面展示 <el-col :span="12"><el ...

  3. vue中Axios的封装与API接口的管理详解

    一:axios的封装 vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是promise的http库,可运行在浏览器端和node.js中. 安装 npm install axios ...

  4. vue中axios的封装以及使用

    Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中.axios 在src下新建 network 文件夹 network文件夹: 网络模块 放网络请求 ind ...

  5. 高德地图中加载three.js(vue中)(封装

    这几天公司有一个要结合高德地图的智慧园区的项目(大致就是在3d地图中加载自己的three.js模型) 1.首先要引入高德地图 官方文档给出来的引用方法 <template><div ...

  6. 在vue中element ui 结合frappe-gantt实现一个简单的甘特图功能

    在vue中创建甘特图步骤请参考: https://editor.csdn.net/md/?articleId=130145782 2. 结合element ui 实现甘特图功能 实现效果: 2.1 下 ...

  7. vue中使用kindeditor编辑器_vue富文本编辑器组件vue-quill-edit使用教程

    这篇文章主要为大家详细介绍了vue富文本编辑器组件vue-quill-edit使用教程,具有一定的参考价值,可以用来参考一下. 感兴趣的小伙伴,下面一起跟随512笔记的小编两巴掌来看看吧! 之前使用的 ...

  8. vue中的axios封装

    import axios from 'axios'; import { Message } from 'element-ui'; axios.defaults.timeout = 5000; axio ...

  9. vue中Router的封装以及使用

    在项目中会有多个vue页面,就会引入许多路由,如果配置的路由都放在router文件夹下的index.js中,要写很多个,而且显得代码量太多. 所以我们需要 单独写出来 . 在router文件夹中新建H ...

最新文章

  1. 大家谈谈公司里的项目经理角色及职责都是干什么的?
  2. IJ中 运行tomcat 配置
  3. hibernate中一对多关系的映射
  4. 分享apache http服务器设置虚拟主机的方法
  5. 腾讯内部产品课:细分用户
  6. IOS基础之NSString,NSMutableString,NSArray的基本使用
  7. 二进制信号量,互斥信号和计数信号量的区别
  8. lamda获取参数集合去空_(转)Java8使用lambda表达式进行集合的遍历
  9. 解决:ngxin做http强制跳转https,接口的POST请求变成GET
  10. Ms sql pivot unpivot
  11. 【第四课】UAV倾斜摄影测量三维建模技术软件——Smart 3d
  12. Sql Server2014 安装Northwind数据库
  13. GoLand每次切换,光标跑到行首
  14. 一个人九月份开始考北邮的经验
  15. 数据库查询简单练习(五)
  16. 漂亮,这张 动态可视化 交互大屏图,也是用Python实现的!
  17. 8-数据可视化-地图可视化
  18. 爬虫爬取京东产品数据
  19. Django——admin功能、注册模型类、模型管理类
  20. bga bond焊盘 wire_封装模式: FC-BGA VS. WireBond ,谁是封装工艺中的真英雄?(图)

热门文章

  1. 环境搭建(windows): 1.rabbitmq安装 2.web GUI管理插件安装 3.erlang版本和rabbitmq版本之间对应关系
  2. 麦克风控制LED,控制喇叭
  3. 人物肖像速写_肖像学的基础
  4. 【没有anaconda powershell prompt】Anaconda安装后开始菜单没有Anaconda Powershell Prompt
  5. 作为java程序员针对未来3年的深思
  6. 哪位大大帮看下spring boot server.port不起作用
  7. 浪花淘尽英雄 --《浪潮之巅》读书笔记壹
  8. 相比传统专线网络,爱快、飞连等主流SD-WAN方案好在哪里?
  9. 身为一个男人,我觉得我连狗都不如!
  10. ARCGIS/MAPGIS/MAPINFO/CAD配准方法汇总