答案 0 :(得分:11)
您可以使用正在使用的元素上的mousedown
事件而不是按钮来保存选择,并在将{ed click
事件中的editable元素聚焦后再次将其恢复。
我修改了示例代码:http://jsbin.com/atike/40/edit。这是代码:
function saveSelection() {
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
var ranges = [];
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
ranges.push(sel.getRangeAt(i));
}
return ranges;
}
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange();
}
return null;
}
function restoreSelection(savedSel) {
if (savedSel) {
if (window.getSelection) {
sel = window.getSelection();
sel.removeAllRanges();
for (var i = 0, len = savedSel.length; i < len; ++i) {
sel.addRange(savedSel[i]);
}
} else if (document.selection && savedSel.select) {
savedSel.select();
}
}
}
$(function() {
var savedSel;
$('.bold').mousedown(function () {
savedSel = saveSelection();
});
$('.bold').click(function () {
$('#hello').focus();
if (savedSel) {
restoreSelection(savedSel);
}
document.execCommand("bold", false, null);
});
});
答案 1 :(得分:1)
大多数(如果不是全部)WYSIWYG编辑器都使用iframe
元素,以免丢失选择。另一种方法,虽然我还没有尝试过,但是会在mouseup
事件触发后存储在该页面上做出的每个选择。
请查看此页面,了解Gecko内置的富文本编辑器Midas。
答案 2 :(得分:1)
当您单击文本节点时,浏览器想要选择该文本。按钮不是文本流的一部分,因此不会触发新的选择。
您所要做的就是阻止浏览器执行重新选择。当您正在观察的click
事件运行时,选择已经发生并且为时已晚。该操作开始在mousedown
上针对所有期望MSIE的浏览器进行,其中MSIE具有特殊选择事件。
这适用于各种浏览器:
jQuery('.bold')
.attr('unselectable','on') // prevents selection in MSIE
.bind('mousedown',function (e) {
document.execCommand("bold", false, null);
e.preventDefault(); // prevents selection in all but MSIE
});
使用MSIE的选择事件(例如必须阻止拖动)也有一些复杂性,因此更容易将您正在使用的元素的可选性作为具有专用属性{{1}的按钮来淘汰}(需要值“on”)。
您显然仍然可以在unselectable
个事件中执行execCommand
处理,只需对所有打算作为“按钮”的元素运行选择预防代码:
click
答案 3 :(得分:0)
NicEdit使用了多种方法。
大多数工具栏元素都具有“不可选择的”属性集 - 这适用于Internet Explorer。
在相同的元素上,它注册“mousedown”事件并覆盖默认操作 - 这会阻止文本解决方案和焦点。这仅适用于IE以外的浏览器。
某些工具栏元素需要能够接收文本焦点并进行选择,例如用于插入链接或图像的字段。对于这些,它会在编辑器失去焦点之前保存选择,然后在用户完成编辑后进行恢复,并且需要进行更改。
有关如何实现它,请检查NicEdit的代码。搜索函数名称:
...
这使用浏览器的getSelection()或document.selection来获取选择,getRangeAt()将其转换为范围,使用addRange()或select()将该范围恢复为选择。