onChange事件与contenteditable

Dan*_*-Br 26 javascript html5

代码如:

...text <span contenteditable="true" onChange="someFunction()">blah blah</span> text...
Run Code Online (Sandbox Code Playgroud)

onChange事件不起作用.(至少在FireFox中)
我不想使用textarea/input标签,因为必须只能更改文本中的特定单词,并且必须以内联方式显示(而不是阻止).

有什么方法可以做到吗?

Tim*_*own 27

并不是的.最近的WebKit浏览器支持元素input上的HTML5 事件contenteditable,这是理想的,但在其他浏览器中不受支持(2012年12月31日更新:Firefox支持此版本14).否则,你可能能够获得通过DOM突变事件 DOMNodeInserted,DOMNodeRemovedDOMCharacterDataModified,但是这有两个缺点:首先,他们没有在IE <9或歌剧的任何版本支持的contenteditable元素,其次,与更换活动一种新的规范是在这些作品意味着它们可能会在未来的浏览器中被替换.

实例:http://jsfiddle.net/MBags/

或者您可以进入较低级别并处理键,鼠标和​​剪贴板事件(cutpaste),这将在所有主流浏览器中起作用,但这意味着您需要检查每次此类事件触发时可编辑内容是否已更改,这将获得滞后并损害大量内容的用户体验.

  • @ Dani-Br:什么?我的回答说只有WebKit支持`input`事件,因此不支持Firefox.其次,当你需要检测可编辑内容的变化时,你的问题根本不清楚*; `input`事件是与表单输入的`change`事件最相似的事件,尽管我承认它们是完全不同的. (4认同)

Blo*_*sie 10

我构建了一个jQuery插件来执行此操作.

(function ($) {
    $.fn.wysiwygEvt = function () {
        return this.each(function () {
            var $this = $(this);
            var htmlOld = $this.html();
            $this.bind('blur keyup paste copy cut mouseup', function () {
                var htmlNew = $this.html();
                if (htmlOld !== htmlNew) {
                    $this.trigger('change');
                    htmlOld = htmlNew;
                }
            })
        })
    }
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

你可以简单地打电话 $('.wysiwyg').wysiwygEvt();

如果您愿意,也可以删除/添加活动


Dav*_*mas 7

Because non-input elements don't have traditional input-like events, you have to sort of mash something together yourself. To that end:

var editable = document.querySelectorAll('div[contentEditable]');

for (var i=0, len = editable.length; i<len; i++){
    editable[i].setAttribute('data-orig',editable[i].innerHTML);

    editable[i].onblur = function(){
        if (this.innerHTML == this.getAttribute('data-orig')) {
            // no change
        }
        else {
            // change has happened, store new value
            this.setAttribute('data-orig',this.innerHTML);
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

JS Fiddle demo.

Though as noted by Tim Down this shouldn't be necessary for too much longer, with the obvious exception of supporting older browsers.


Dan*_*-Br 6

我写的函数:
这个函数的一次调用修复了页面中的所有ContentEditable元素.

function fix_onChange_editable_elements()
{
  var tags = document.querySelectorAll('[contenteditable=true][onChange]');//(requires FF 3.1+, Safari 3.1+, IE8+)
  for (var i=tags.length-1; i>=0; i--) if (typeof(tags[i].onblur)!='function')
  {
    tags[i].onfocus = function()
    {
      this.data_orig=this.innerHTML;
    };
    tags[i].onblur = function()
    {
      if (this.innerHTML != this.data_orig)
        this.onchange();
      delete this.data_orig;
    };
  }
}
Run Code Online (Sandbox Code Playgroud)