【问题标题】:onChange event with contenteditable [duplicate]onChange 事件与 contenteditable [重复]
【发布时间】:2012-01-01 16:11:56
【问题描述】:

代码如下:

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

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

有什么办法吗?

【问题讨论】:

  • 为什么不使用 input 元素并设置边框/填充样式并使用 display:inlinedisplay:inline-block

标签: javascript html


【解决方案1】:

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

您还可以根据需要删除/添加事件

【讨论】:

    【解决方案2】:

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

    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 Fiddle demo.

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

    【讨论】:

      【解决方案3】:

      不是真的。最近的 WebKit 浏览器支持contenteditable 元素上的 HTML5 input 事件,这是理想的,但在其他浏览器中不支持(2012 年 12 月 31 日更新:Firefox 从版本 14 开始支持此功能)。否则你可以使用DOM mutation eventsDOMNodeInsertedDOMNodeRemovedDOMCharacterDataModified,但它们有两个缺点:首先,它们在 IE contenteditable 元素,其次,带有替换事件的新规范正在制定中,这意味着它们很可能在未来的浏览器中被替换。

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

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

      【讨论】:

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

      我写的函数:
      一次调用此函数即可修复页面中的所有 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;
          };
        }
      }
      

      【讨论】:

      • 如果您需要了解“实时”更改,可以调整上述原理以在setInterval 下工作(具有合理的间隔设置和最终的clearInterval)。
      猜你喜欢
      • 1970-01-01
      • 2014-01-05
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 2013-11-18
      • 2019-01-12
      • 1970-01-01
      相关资源
      最近更新 更多