绿满眶商城微信小程序-uniapp
zxl
2025-07-17 b303b6945a139153688e86635346a621fe0c29b3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// 标识必须独一无二 - 标识是为了使用insertText插入标识文本后,查找到标识所在delta位置的索引
export const linkFlag = '#-*=*-*=*-*=*@-link超链接标识link-@*=*-*=*-*=*-#'
 
export function addLink(editorCtx, attr, callback) {
    // 先插入一段文本内容
    editorCtx.insertText({
        text: linkFlag
    })
    // 获取全文delta内容
    editorCtx.getContents({
        success(res) {
            let options = res.delta.ops
            const findex = options.findIndex(item => {
                return item.insert && typeof item.insert !== 'object' && item.insert?.indexOf(linkFlag) !== -1
            })
            // 根据标识查找到插入的位置
            if (findex > -1) {
                const findOption = options[findex]
                const findAttributes = findOption.attributes
                // 将该findOption分成三部分:前内容 要插入的link 后内容
                const [prefix, suffix] = findOption.insert.split(linkFlag);
                const handleOps = []
                // 前内容
                if (prefix) {
                    const prefixOps = findAttributes ? {
                        insert: prefix,
                        attributes: findAttributes
                    } : {
                        insert: prefix
                    }
                    handleOps.push(prefixOps)
                }
                // 插入的link
                const linkOps = {
                    insert: attr.text,
                    attributes: {
                        link: attr.href,
                        textDecoration: attr.textDecoration || 'none', // 下划线
                        color: attr.color || '#007aff'
                    }
                }
                handleOps.push(linkOps)
                // 后内容
                if (suffix) {
                    const suffixOps = findAttributes ? {
                        insert: suffix,
                        attributes: findAttributes
                    } : {
                        insert: suffix
                    }
                    handleOps.push(suffixOps)
                }
                // 删除原options[findex]并在findex位置插入上述三个ops
                options.splice(findex, 1);
                options.splice(findex, 0, ...handleOps);
                // 最后重新初始化内容,注意该方法会导致光标重置到最开始位置
                editorCtx.setContents({
                    delta: {
                        ops: options
                    }
                })
                // 所以最后建议使富文本光标失焦,让用户手动聚焦光标
                editorCtx.blur()
 
                // 后续回调操作
                if (callback) callback()
            }
        }
    })
 
}
 
/**
 * 将含有特殊图片形式视频的富文本转换成正常视频的富文本
 * @param {String} html 要进行处理的富文本字符串
 * @returns {String} 返回处理结果
 */
export function handleHtmlWithVideo(html) {
    // 正则表达式用于匹配img标签中带有alt属性且alt属性值为视频链接的模式
    const regex = /<img\s+src="[^"]*"\s+alt="([^"]*)"[^>]*>/g
    // 使用replace方法和一个函数回调来替换匹配到的内容
    return html.replace(regex, (match, videoUrl) => {
        // 替换为video标签,并添加controls属性以便用户可以控制播放
        return `<video width="80%" controls><source src="${videoUrl}" type="video/mp4"></video>`
    })
}
 
/**
 * 将img标签中内联style属性中的宽高样式提取出标签width与height属性
 * @param {Object} html 要处理的富文本字符串
 * @returns {Object} 返回处理结果
 */
export function convertImgStylesToAttributes(html) {
    return html.replace(/<img\s+([^>]+)\s*>/g, function(match, attributes) {
        // 分割属性
        const attrs = attributes.split(/\s+/);
 
        // 找到style属性的位置
        const styleIndex = attrs.findIndex(attr => attr.startsWith('style='));
        if (styleIndex === -1) return match; // 如果没有找到style属性,则返回原样
 
        // 提取style属性值
        const styleAttr = attrs.splice(styleIndex, 1)[0];
        const style = styleAttr.match(/"([^"]*)"/)[1];
 
        // 解析 style 属性
        const styleObj = {};
        style.split(';').forEach(function(part) {
            if (part) {
                const [name, value] = part.split(':');
                styleObj[name.trim()] = value.trim();
            }
        });
 
        // 创建新的 img 标签
        let newTag = '<img';
        if (styleObj.width) {
            newTag += ` width="${styleObj.width}"`;
        }
        if (styleObj.height) {
            newTag += ` height="${styleObj.height}"`;
        }
 
        // 添加原有的属性,包括修改过的style属性
        newTag += ` ${styleAttr} ${attrs.join(' ')}`;
 
        // 关闭 img 标签
        newTag += '>';
 
        return newTag;
    });
}