我正在使用bootstrap-wyshtml5(基于wysihtml5)这个令人惊叹的编辑器,它运行良好,每个人都很高兴。但现在我需要在用户输入内容时提供文本建议(比如这个或这个)。这些库需要一个文本区域,wysihtml5使用一个带有<body contenteditable="true">
的iframe。
我所需要的只是在元素内的一些纯文本中自动完成一些单词(或打开一个带有建议的弹出窗口)
在我深入研究之前,有人提出过一个可以在contenteditable="true"
元素中工作的库的建议吗?
编辑1:
我创建了一个基本的库来做我需要的事情,但我想我在这个库上使用了我所有糟糕的js技能。。。它在带有contenteditable=true
的div上工作,但我很难让它在wysihtml5编辑器上工作。一些javascript/wysihtml5/rangy忍者能给我一些帮助吗?
这是我的代码:http://jsfiddle.net/5UQfH/
编辑2:
第一个工作版本:http://jsfiddle.net/X9jBM/1/
编辑3:
稍好(但不漂亮)的版本(在同一页面上使用多个编辑器):http://jsfiddle.net/X9jBM/18/
当建议是多个单词时仍然不能正常工作(当有空格时停止建议)
我仍然希望听到一些对此的反馈。
我最终创建了一个非常简单和基本的lib来做我需要的事情。除了最新的chrome版本之外,它既不完美,也没有在任何方面进行过测试,我可能可以很容易地消除jQuery依赖项,但由于我的项目中已经有了它(旧的借口),现在我将保持原样。
CCD_ 4选择一个单词并且CCD_。http://jsfiddle.net/X9jBM/19/
代码:
if (typeof String.prototype.startsWith != 'function') {
String.prototype.startsWith = function (str) {
return this.indexOf(str) == 0;
};
}
var SuggestMe = function () {
"use strict";
var self = this;
return {
init: init
};
function init(iframe, words) {
self.list = [];
self.currentIndex = 0;
self.currentWord = "";
self.$iframe = iframe;
self.$editor = $(iframe).contents().find(".wysihtml5-editor");
self.$editor.on("keydown", function (event) {
if (event.keyCode === 13) {
var sel = rangy.getIframeSelection(self.$iframe);
if (!sel.isCollapsed) {
var range = sel.getRangeAt(0);
range.collapse(false);
var textNode = document.createTextNode(" ");
range.insertNode(textNode);
sel.collapseToEnd();
event.preventDefault();
return false;
}
}
if (event.keyCode === 9) {
var sel = rangy.getIframeSelection(self.$iframe);
if (!sel.isCollapsed) {
self.currentIndex++;
var word = self.list[self.currentIndex % self.list.length];
var sel = rangy.getIframeSelection(self.$iframe);
var range = sel.getRangeAt(0);
range.deleteContents();
var term = word.slice(self.currentWord.length, word.length);
var textNode = document.createTextNode(term);
range.insertNode(textNode);
range.selectNodeContents(textNode);
rangy.getSelection().setSingleRange(range);
event.preventDefault();
return false;
}
}
});
self.$editor.on("keyup", function (event) {
var c = String.fromCharCode(event.keyCode);
var isWordcharacter = c.match(/w/);
if (isWordcharacter && !event.ctrlKey) {
var $editor = this;
self.currentWord = getLastWord($editor);
if (self.currentWord) {
var sel = rangy.getIframeSelection(self.$iframe);
if (sel.rangeCount > 0) {
self.list = [];
self.currentIndex = 0;
$.each(words, function (a) {
var word = words[a].toLowerCase();
if (word.startsWith(self.currentWord.toLowerCase())) {
self.list.push(word);
}
});
}
if (self.list.length) {
var word = self.list[self.currentIndex];
var sel = rangy.getIframeSelection(self.$iframe);
var range = sel.getRangeAt(0);
var term = word.slice(self.currentWord.length, word.length);
var textNode = document.createTextNode(term);
range.insertNode(textNode);
range.selectNodeContents(textNode);
rangy.getSelection().setSingleRange(range);
}
}
}
});
}
function getLastWord(elm) {
var val = elm.innerText.trim();
val = val.replace(/(rn|n|r)/gm, " ");
var idx = val.lastIndexOf(' ');
var lastWord = val.substring(idx + 1).trim();
console.log(val);
return lastWord;
}
};
用途:
var suggestions = ["hello", "world", "blue dog", "blue cat"];
$('#txt').wysihtml5();
var editor = $('#txt').data("wysihtml5").editor;
editor.on('load', function () {
var sm = new SuggestMe();
sm.init(this.currentView.iframe, suggestions);
});
还有一些重构工作要做,但这是最基本的想法。