5

我正在尝试允许用户编辑列表 (UL)。在我的尝试中,似乎 contenteditable 并没有做任何特别的事情(比如强制执行幕后标记)——它只是为用户提供了一个进入 innerHTML 的窗口。

这会导致问题,如果还没有 LI,并且用户添加了一些东西,它不会被 LI 化。类似地,如果有列表项,但用户删除了它们,则 LI 将被删除,并且添加的任何新文本都没有 LI。请参阅http://jsfiddle.net/JTWSC/。我还发现光标有时可能会“离开”确实存在的 LI,但我无法始终如一地重现。

我必须包含代码,所以这就是“结果”的样子:

<ul>whatever the user typed in</ul>

我该如何解决?我开始使用 $('ul').keyup() 处理程序的路径,该处理程序检查 html 并根据需要进行包装,但我遇到了一些陷阱,比如计时、失去对元素的关注、不得不重新关注正确的地方,等等。我相信如果我在这方面工作是可能的,但我希望有一个更简单的解决方案。

4

1 回答 1

7

我构建了以下 keyup/down 处理程序,以使我的 contenteditable <UL>s 白痴证明。*

它做了两件事:

  1. 当 <UL> 为空时,将 <LI> 添加到 <UL>。我使用在 SO(来自 Tim Down)上找到的一些代码将插入符号放在预期的位置
  2. 清除所有非 LI/非 BR 标记。这基本上是一种快速又脏的膏状清洁剂。

这提高了我对 jquery 和 DOM 操作的舒适度,所以可能有几件事我可以做得更好,但它按原样工作得很好。

//keyup prevented the user from deleting the bullet (by adding one back right after delete), but didn't add in li's on empty ul's, thus keydown added to check
$('ul').on('keyup keydown', function() {
  var $this = $(this);
    if (! $this.html()) {
        var $li = $('&lt;li&gt;&lt;/li&gt;');
        var sel = window.getSelection();
       var range = sel.getRangeAt(0);
        range.collapse(false);
        range.insertNode($li.get(0));
        range = range.cloneRange();
        range.selectNodeContents($li.get(0));
        range.collapse(false);
        sel.removeAllRanges();
        sel.addRange(range);

    } else {
        //are there any tags that AREN'T LIs?
        //this should only occur on a paste
        var $nonLI = $this.find(':not(li, br)');

        if ($nonLI.length) {
            $this.contents().replaceWith(function() {
    //we create a fake div, add the text, then get the html in order to strip out html code. we then clean up a bit by replacing nbsp's with real spaces
return '&lt;li&gt;' + $('&lt;div /&gt;').text($(this).text()).html().replace(/&nbsp;/g, ' ') + '</li>';
            });
            //we could make this better by putting the caret at the end of the last LI, or something similar
        }                   
    }
});

jsfiddle 在http://jsfiddle.net/aVuEk/5/

*我非常不同意 Diodeus 的观点,即培训是所有情况下最好/最简单的解决方案。在我的情况下,我在一个页面上有几个可内容编辑的 <UL>,它们非常内嵌 WYSIWYG(即,tinymce 风格的 chrome 没有太多空间),并且被临时的、初次使用的非高级用户使用。

于 2012-11-14T01:01:16.963 回答