具有 contenteditable 的 onChange 事件

IT技术 javascript html
2021-03-13 19:28:39

代码如:

...text <span contenteditable="true" onChange="someFunction()">blah blah</span> text...

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

有没有办法做到这一点?

4个回答

并不真地。最近的 WebKit 浏览器支持元素input的 HTML5事件contenteditable,这是理想的,但在其他浏览器中不支持(更新 2012 年 12 月 31 日:Firefox 从版本 14 开始支持此功能)否则,您可能可以使用DOM 突变事件 DOMNodeInserted,DOMNodeRemovedDOMCharacterDataModified,但它们有两个缺点:首先,它们在 IE < 9 或任何版本的 Opera 中不支持contenteditable元素,其次,具有替换事件的新规范在作品,这意味着它们可能会在未来的浏览器中被替换。

现场示例:http : //jsfiddle.net/MBags/

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

不幸的是,输入事件对IE 中的contenteditable元素不起作用,甚至在 IE10 中也不起作用
2021-05-03 19:28:39
@Dani-Br:什么?我的回答是该input事件仅在 WebKit 中受支持,因此在 Firefox 中不支持。其次,您的问题根本不清楚何时需要检测可编辑内容的更改;input事件与change表单输入事件最相似,尽管我承认它们完全不同。
2021-05-07 19:28:39
onInput 事件是非常糟糕的解决方案。第一个原因 - 每次用户更改单个字母时都会发生。第二个原因 - 即使在 FireFox 8.0 中也不起作用
2021-05-16 19:28:39

我构建了一个 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);

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

如果您愿意,您还可以删除/添加事件

我编写的函数:
一次调用此函数即可修复页面中的所有 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;
    };
  }
}
如果您需要了解“实时”更改,上述原则可以适用于 a setInterval(具有合理的间隔设置和最终clearInterval)。
2021-04-26 19:28:39

因为非输入元素没有传统的类似输入的事件,所以您必须自己将一些东西混合在一起。为此:

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);
        }
    };
}

JS小提琴演示

尽管正如Tim Down所指出的那样,这应该不需要太长时间,但支持旧浏览器的明显例外。