实现自己写的小程序富文本编辑以及展示,不跟PC端的兼容,但是可以在pc端显示以及修改,一旦修改,小程序不再做解析

富文本结构:

 1 <div class="detail_box">
 2                             <ul>
 3                                 <li v-for="(item4,index4) in detailAry" :key="index4">
 4                                     <!-- 文字 -->
 5                                     <div class="detail_list">
 6                                         <div class="list_t">
 7                                             <div class="list_l">
 8                                                 <span>{{item4.title}}</span>
 9                                             </div>
10                                             <div class="list_r">
11                                                 <div class="r_left">
12                                                     <img v-if="index4 == 0" src="https://img.xingxio.com/Group 7@2x (1).png" alt="">
13                                                     <img v-else @click="changeIndexL(index4)" src="https://img.xingxio.com/Group 7@2x.png" alt="">
14                                                     <img v-if="index4 == detailAry.length-1 && index4 != 0" src="https://img.xingxio.com/Group 11@2x.png" alt="">
15                                                     <img v-else @click="changeIndexR(index4)" src="https://img.xingxio.com/Group 8@2x.png" alt="">
16                                                 </div>
17                                                 <div class="r_right">
18                                                     <img @click="delDetailAry(index4)" v-show="index4 >0" class="del_img" src="https://img.xingxio.com/close_icon.png" alt="">
19                                                 </div>
20                                             </div>
21                                         </div>
22                                         <div class="inp_box" v-if="item4.type == 1">
23                                             <!-- <input type="text" v-model="item4.text" placeholder="请输入文字"> -->
24                                             <textarea v-show="isChange"  class="textarea" maxlength="1000" v-model="item4.text" placeholder="填写多行,可以换行,最多填写1000字"></textarea>
25                                         </div>
26                                         <!-- <div class="inp_box" v-if="item4.type == 2"> -->
27                                             <div class="img_box" v-if="item4.type == 2">
28                                                 <img class="img" :src="item4.src"  alt="" mode="aspectFit">
29                                             </div>
30                                             <div class="img_box" v-if="item4.type == 3">
31                                                 <video :controls="controls" :autoplay="false" :src="item4.src"></video>
32                                                 <div class="v_tips">苹果手机暂不支持播放视频</div>
33                                                 <!-- <img class="img" :src="item4.src"  alt="" mode="aspectFit"> -->
34                                             </div>
35                                         <!-- </div> -->
36                                     </div>
37                                     <!-- 图片 -->
38                                     <!-- <div class="detail_list img_list" v-if="item4.type == 2">
39                                         <div class="list_t">
40                                             <div class="list_l">
41                                                 <span>{{item4.title}}</span>
42                                             </div>
43                                             <div class="list_r">
44                                                 <img  src="https://img.xingxio.com/Group 7@2x (1).png" alt="">
45                                                 <img src="https://img.xingxio.com/Group 7@2x.png" alt="">
46                                                 <img src="https://img.xingxio.com/Group 8@2x.png" alt="">
47                                                 <img src="https://img.xingxio.com/Group 11@2x.png" alt="">
48                                                 <img class="del_img" src="https://img.xingxio.com/close_icon.png" alt="">
49                                             </div>
50                                         </div>
51                                         <div class="inp_box">
52                                             <div class="img_box">
53                                                 <img class="img" :src="item4.src"  alt="" mode="aspectFill">
54                                             </div>
55                                         </div>
56                                     </div> -->
57                                     <!-- 视频 -->
58                                     <!-- <div class="detail_list img_list">
59                                         <div class="list_t">
60                                             <div class="list_l">
61                                                 <span>视频</span>
62                                             </div>
63                                             <div class="list_r">
64                                                 <img class="del_img" src="https://img.xingxio.com/close_icon.png" alt="">
65                                             </div>
66                                         </div>
67                                         <div class="inp_box">
68                                             <div class="img_box">
69                                                 <video></video>
70                                             </div>
71                                         </div>
72                                     </div> -->
73                                 </li>
74                             </ul>
75                             <div class="detail_f">
76                                 <div class="f_list" @click="addDetailAry(1,'文字')">
77                                     <img  src="https://img.xingxio.com/text_icon.png" alt="">
78                                     <span>文字</span>
79                                 </div>
80                                 <div class="f_list" @click="updateImg(6)">
81                                     <img class="p_img" src="https://img.xingxio.com/image_icon.png" alt="">
82                                     <span>图片</span>
83                                 </div>
84                                 <div class="f_list" v-if="false" >
85                                     <img class="yuyin_img" src="https://img.xingxio.com/yuyin_icon.png" alt="">
86                                     <span>语音</span>
87                                 </div>
88                                 <div class="f_list"  @click="uploadVideo">
89                                     <img  src="https://img.xingxio.com/video_icon.png" alt="">
90                                     <span>视频</span>
91                                 </div>
92                             </div>
93                         </div>

富文本样式:

  1 .detail_box {
  2                 width: 100%;
  3                 padding: 20rpx;
  4                 box-sizing: border-box;
  5                 ul {
  6                     width: 100%;
  7                     margin-bottom: 100rpx;
  8                     height: auto;
  9                     li{
 10                         width: 100%;
 11                         height: auto;
 12                         .detail_list {
 13                             width: 100%;
 14                             .list_t {
 15                                 width: 100%;
 16                                 height: 80rpx;
 17                                 display: flex;
 18                                 align-items: center;
 19                                 justify-content: space-between;
 20                                 .list_l {
 21                                     color: #4A4A4A;
 22                                     font-size: 32rpx;
 23                                 }
 24                                 .list_r {
 25                                     width: 200rpx;
 26                                     height: 100%;
 27                                     display: flex;
 28                                     align-items: center;
 29                                     justify-content: space-between;
 30                                     .r_left {
 31                                         width: 122rpx;
 32                                         display: flex;
 33                                         align-items: center;
 34                                         justify-content: space-between;
 35                                         img {
 36                                             width: 36rpx;
 37                                             height: 36rpx;
 38                                         }
 39                                     }
 40                                     .r_right {
 41                                         display: flex;
 42                                         align-items: center;
 43                                         img {
 44                                             width: 36rpx;
 45                                             height: 36rpx;
 46                                         }
 47                                     }
 48                                 }
 49                             }
 50                             .inp_box {
 51                                 margin-top: 20rpx;
 52                                 width: 100%;
 53                                 height: 300rpx;
 54                                 input {
 55                                     width: 100%;
 56                                     line-height: 80rpx;
 57                                     border: 0px;
 58                                     padding-left: 20rpx;
 59                                     box-sizing: border-box;
 60                                     font-size: 28rpx;
 61                                 }
 62                                 .textarea {
 63                                     width: 100%;
 64                                     height: 280rpx;
 65                                     border: 0px;
 66                                     padding-left: 20rpx;
 67                                     box-sizing: border-box;
 68                                     font-size: 28rpx;
 69                                 }
 70 
 71                             }
 72                             .img_box {
 73                                 width: 100%;
 74                                 height: 300rpx;
 75                                 padding: 20rpx;
 76                                 box-sizing: border-box;
 77                                 img {
 78                                     width: 100%;
 79                                     height: 100%;
 80                                 }
 81                                 video {
 82                                     width: 280rpx;
 83                                     height: 180rpx;
 84                                 }
 85                                 .v_tips {
 86                                     margin-top: 20rpx;
 87                                     font-size: 28rpx;
 88                                     color: #9B9B9B;
 89                                     text-align: center;
 90                                     // line-height: 100%;
 91                                 }
 92                             }
 93                         }
 94 
 95                     }
 96                 }
 97 
 98                 .detail_f {
 99                     width: 100%;
100                     height: 100rpx;
101                     border-radius: 6rpx;
102                     color: rgba(16, 16, 16, 1);
103                     font-size: 28rpx;
104 
105                     // box-shadow: 0px 0px 8rpx 2rpx rgba(0, 0, 0, 0.07);
106                     font-family: Arial;
107                     // border: 1px solid rgba(231, 236, 242, 1);
108                     display: flex;
109                     align-items: center;
110                     padding: 0px 30rpx;
111                     box-sizing: border-box;
112                     justify-content: space-between;
113                     .f_list {
114                         height: 100%;
115                         display: flex;
116                         align-items:center;
117                         justify-content: center;
118                         flex-direction: column;
119                         img {
120                             width: 32rpx;
121                             height: 32rpx;
122 
123                         }
124                         .p_img {
125                             width: 34rpx;
126                         }
127                         .yuyin_img {
128                             width: 34rpx;
129                             height: 34rpx;
130                         }
131                         span {
132                             margin-top: 12rpx;
133                             color: #9B9B9B;
134                             font-size: 28rpx;
135                             // margin-left: 10rpx;
136                         }
137                     }
138 
139                 }
140 
141             }

效果图:

既然要兼容到pc端上的编辑器(本pc项目使用的是百度编辑器),所以存数据的时候带上标签传给后台

/**
             *  处理详情的图文
             */
            handleDetail(){
                console.log(this.detailAry)
                let ary = []
                for (let i = 0; i < this.detailAry.length; i++) {
                    if(this.detailAry[i].type == 1){
                        let arr2 = []
                        arr2.push(this.detailAry[i].text)
                        // this.detailAry[i].text =arr2.join(`<br/>`)
                        this.detailAry[i].text = this.detailAry[i].text.replace(/\n/g,"<br/>")
                        console.log(this.detailAry[i].text)
                        let text = `<div data-type="${1}">${this.detailAry[i].text}</div>`
                        ary.push(text)
                    }else if(this.detailAry[i].type == 2){
                        let imgs = `<div data-type="${2}"><img src="${this.detailAry[i].src}" alt=""></div>`
                        ary.push(imgs)
                    }else if(this.detailAry[i].type == 3){
                        console.log(this.detailAry[i].src)
                        let video = `<div data-type="${3}"><video controls='true' src="${this.detailAry[i].src}"></video></div>`
                        ary.push(video)
                    }
                }
                console.log(ary)
                this.txt = ary.join('\n')
                console.log(this.txt)
            },

然而数据返回也是一个json的格式,所以解析方法,这是一个封装的方法,中间引用到一个插件的  

xmldom是一个解析标签的,因为小程序么有dom元素,也没有js中获取某某某的id啊  百度搜索xmldom就可以找到了 支持npm下载
/**
 * 解析富文本
 */
export const txtResolve = function(txt){
  if (txt) {
    console.log(txt)
    let doc = new DOMParser().parseFromString(txt)
    console.log(doc)
    let ary1 = doc.documentElement.getElementsByTagName('div')
    let detailAry = []
    console.log(ary1)
    if(ary1.length > 0){
      for (let i = 0; i < ary1.length; i++) {
        if(ary1[i].attributes[0].nodeValue == 1){
          let arr2 = ary1[i].childNodes
          let arr3 = []
          let str = ''
          for (let j = 0; j < arr2.length; j++) {
            if(arr2[j].nodeValue){
              arr3.push(`${arr2[j].nodeValue}`)
            }else {
              arr3.push(`\n`)
            }
          }
          str = arr3.join('')
          let obj = {
            type: 1,
            title: '文字',
            text: str
          }
          detailAry.push(obj)
        }
        if(ary1[i].attributes[0].nodeValue == 2){
          let obj = {
            type: 2,
            title: '图片',
            src: ary1[i].firstChild.getAttribute('src')
          }
          detailAry.push(obj)
        }
        if(ary1[i].attributes[0].nodeValue == 3){
          let obj = {
            type: 3,
            title: '视频',
            src: ary1[i].firstChild.getAttribute('src')
          }
          detailAry.push(obj)
        }
        if(ary1[i].attributes[0].nodeValue == 4){
            let srcs = []
            // console.log(ary1[i].childNodes)
            for (let k = 0; k < ary1[i].childNodes.length; k++) {
                // console.log(ary1[i].childNodes[k].getAttribute('src'))
                srcs.push(ary1[i].childNodes[k].getAttribute('src'))
            }
            // console.log(srcs)
            let obj = {
                type: 4,
                title: '多图',
                srcs: srcs
            }
            detailAry.push(obj)
        }
      }
    }
    console.log(detailAry)
    return detailAry
  } else {
    return []
  }
}

 

注释: 每一个编辑的文本或者图片都是一个对象,数组循环,还有点击上下可以改变顺序,上下顺序的执行方法

/**
             * 控制详情排序
             */
            changeIndexL(index){  // 上升
                // console.log(index)
                // console.log(this.detailAry)
               if(index != 0){
                   this.swapArray(this.detailAry,index,index-1)
               }else {
                   return false;
               }

            },
            changeIndexR(index){ // 下降
                // console.log(index)
               if(index != this.detailAry.length){
                   this.swapArray(this.detailAry,index,index+1)
               }else {
                   return false;
               }
            },
            swapArray(arr,index1,index2){
                arr[index1] = arr.splice(index2,1,arr[index1])[0];
                // console.log(arr)
                return arr
            },

 

posted @ 2019-07-08 18:13  PinkYun  阅读(685)  评论(0编辑  收藏  举报