You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

能否将jquery-textcomplete与TinyMCE集成?使用问题求助

如何实现jQuery-TextComplete与TinyMCE编辑器的集成

我太懂你的困扰了——jquery-textcomplete在原生input、textarea里跑的顺风顺水,但一碰到TinyMCE这种富文本编辑器就彻底失效,官网还没给半点儿富文本集成的示例。别慌,这俩完全可以搭伙干活,核心问题在于TinyMCE并不是直接操作原生textarea,而是在独立的iframe里创建了可编辑内容区域,我们得调整插件的作用目标和文本操作逻辑来适配它。

核心实现思路

  • 放弃直接给原生textarea绑定textcomplete,转而针对TinyMCE生成的可编辑body元素进行绑定
  • 用TinyMCE专属API来获取光标附近文本、处理文本替换,别再依赖原生textarea的value属性
  • 保留你原来的匹配规则和大小写自适应逻辑,只把文本操作的载体换成TinyMCE的接口

完整实现代码

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.textcomplete/1.8.4/jquery.textcomplete.min.js"></script>
<script src="https://cloud.tinymce.com/stable/tinymce.min.js"></script>

<h3>Testing jquery textcomplete in input</h3>
<p><input id="textcomplete" type="text"></p>

<h3>Testing jquery textcomplete in textarea with TinyMCE</h3>
<p><textarea id="tinymce-textarea"></textarea></p>

<script>
// 原生input的textcomplete(保留你原来的逻辑)
$('#textcomplete').textcomplete([{
    words: ['stackoverflow', 'ҳайрат', 'english', 'маҳорат'],
    match: /(^|\S*)([^\u0000-\u007f]{2,}|\w{2,})$/, 
    search: function(term, callback) {
        callback($.map(this.words, function(word) {
            if (word.indexOf(term.toLocaleLowerCase()) !== 0) return null;
            if (term[term.length-1] === term[term.length-1].toLocaleUpperCase()) return word.toLocaleUpperCase();
            if (term[0] === term[0].toLocaleUpperCase()) return word.charAt(0).toLocaleUpperCase() + word.slice(1);
            return word;
        }));
    },
    index: 2,
    replace: function(word) {
        return word + ' ';
    }
}]);

// TinyMCE初始化及与textcomplete的集成
tinymce.init({
    selector: '#tinymce-textarea',
    setup: function(editor) {
        // 编辑器初始化完成后执行绑定逻辑
        editor.on('init', function() {
            // 获取TinyMCE iframe里的可编辑body元素
            const editableBody = editor.getDoc().body;
            
            // 给可编辑body绑定textcomplete
            $(editableBody).textcomplete([{
                words: ['stackoverflow', 'ҳайрат', 'english', 'маҳорат'],
                // 完全复用你原来的匹配规则
                match: /(^|\S*)([^\u0000-\u007f]{2,}|\w{2,})$/,
                search: function(term, callback) {
                    // 保留你原来的大小写自适应逻辑
                    callback($.map(this.words, function(word) {
                        if (word.indexOf(term.toLocaleLowerCase()) !== 0) return null;
                        if (term[term.length-1] === term[term.length-1].toLocaleUpperCase()) return word.toLocaleUpperCase();
                        if (term[0] === term[0].toLocaleUpperCase()) return word.charAt(0).toLocaleUpperCase() + word.slice(1);
                        return word;
                    }));
                },
                index: 2,
                replace: function(word) {
                    // 关键:用TinyMCE API处理文本替换,避免原生操作的兼容性问题
                    const selectedText = editor.selection.getContent({format: 'text'});
                    // 回退光标并删除匹配的原文本
                    editor.selection.setRng(editor.selection.getRng().cloneRange());
                    editor.selection.deleteContent();
                    // 插入带空格的补全词
                    editor.insertContent(word + ' ');
                    return ''; // 这里返回空,因为已经通过API完成替换
                }
            }], {
                appendTo: 'body', // 把补全提示框加到body,防止被iframe遮挡
                maxCount: 10
            });
        });
    }
});
</script>

关键细节说明

  • 目标元素切换:绑定TinyMCE iframe内的body元素,是插件能在富文本编辑器里生效的核心前提
  • 文本替换逻辑:必须用TinyMCE的editor.selectioneditor.insertContent API,才能保证光标位置正确、富文本格式不混乱
  • 提示框位置:设置appendTo: 'body'可以避免补全下拉框被编辑器的iframe遮挡,确保用户能正常看到选项
  • 原有逻辑复用:你原来的匹配规则、大小写自适应逻辑完全保留,只调整了文本操作的实现方式

这样调整后,jquery-textcomplete就能在TinyMCE编辑器里和原生input里的体验保持一致,正常完成补全功能了。

内容的提问来源于stack exchange,提问作者John

火山引擎 最新活动