如果使用按钮,我可以轻松地对 contenteditable 选择执行 execcommand。但是,使用任何其他元素都会失败。
为什么会这样以及如何使用 div 元素使其工作。
谢谢。
如果使用按钮,我可以轻松地对 contenteditable 选择执行 execcommand。但是,使用任何其他元素都会失败。
为什么会这样以及如何使用 div 元素使其工作。
谢谢。
您可以通过使用mousedown
正在使用的元素上的事件而不是按钮来保存选择,并在关注事件中的可编辑元素后再次恢复它click
。
我修改了示例代码: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);
});
});
大多数(如果不是全部)所见即所得的编辑器都使用一个iframe
元素来避免丢失选择。另一种方法(虽然我没有尝试过)是在mouseup
事件触发后存储在该页面上所做的每个选择。
看看这个关于Midas的页面,Gecko 的内置富文本编辑器。
发生的情况是,当您单击文本节点时,浏览器想要选择该文本。按钮不是文本流的一部分,因此不会触发新的选择。
您所要做的就是阻止浏览器执行重新选择。当click
您当前正在观察的事件运行时,选择已经发生并且为时已晚。该动作开始发生在mousedown
除 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 的选择事件有一些复杂性(例如还必须阻止拖动),因此只需使用专用属性unselectable
(需要值“on” )取消您用作按钮的元素的可选择性更容易)。
您显然仍然可以execCommand
在事件中执行处理click
,只需在所有作为“按钮”的元素上运行选择预防代码:
jQuery('.buttonlike')
.attr('unselectable','on') // prevents selection in MSIE
.bind('mousedown',function (e) {
e.preventDefault(); // prevents selection in all but MSIE
});
jQuery('#edit-bold').click(function(){
document.execCommand("bold", false, null);
});
NicEdit使用多种方法。
大多数工具栏元素都设置了“不可选择”属性 - 这适用于 Internet Explorer。
在相同的元素上,它注册“mousedown”事件并覆盖默认操作 - 这会阻止文本解决方案和焦点。这仅适用于 IE 以外的浏览器。
一些工具栏元素需要能够接收文本焦点并进行选择,例如用于插入链接或图像的字段。对于这些,它会在编辑器失去焦点之前保存选择,然后在用户完成编辑并需要进行更改后恢复它。
有关如何实现它,请查看 NicEdit 的代码。搜索函数名称:
...
这使用浏览器的 getSelection() 或 document.selection 来获取选择,getRangeAt() 将其转换为范围,并使用 addRange() 或 select() 将该范围恢复为选择。