contenteditable和非按钮元素

时间:2009-09-25 22:08:48

标签: javascript contenteditable

如果使用按钮,我可以轻松地对一个满足选择的exec命令。但是使用任何其他元素失败。

http://jsbin.com/atike/edit

为什么会这样,以及如何使用div元素使其工作。

感谢。

4 个答案:

答案 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的代码。搜索函数名称:

    • getSel
    • getRng
    • selRng
    • saveRng
    • restoreRng

    ...

    这使用浏览器的getSelection()或document.selection来获取选择,getRangeAt()将其转换为范围,使用addRange()或select()将该范围恢复为选择。