可编辑元素的更改事件

494
我希望在用户编辑具有contenteditable属性的
内容时运行函数。相当于onchange事件的是什么?
我正在使用jQuery,因此任何使用jQuery的解决方案都是首选。谢谢!

3
我通常会这样做:document.getElementById("editor").oninput = function() { ...} - Basj
1
页面下方有一篇很好的答案,发布于2020年:https://dev59.com/N3M_5IYBdhLWcg3waSX9#49287032 - Jack Steam
22个回答

3

在 Angular 2+ 中

<div contentEditable (input)="type($event)">
   Value
</div>


@Component({
  ...
})
export class ContentEditableComponent {

 ...

 type(event) {
   console.log(event.data) // <-- The pressed key
   console.log(event.path[0].innerHTML) // <-- The content of the div 
 }
}



2
这是我最终采用的解决方案,非常有效。我使用$(this).text(),因为我只是使用了一个一行的可编辑div。但你也可以使用.html(),这样就不必担心全局/非全局变量的作用域问题,并且before实际上附加到了编辑器div上。
$('body').delegate('#editor', 'focus', function(){
    $(this).data('before', $(this).html());
});
$('#client_tasks').delegate('.task_text', 'blur', function(){
    if($(this).data('before') != $(this).html()){
        /* do your stuff here - like ajax save */
        alert('I promise, I have changed!');
    }
});

2
为了避免定时器和“保存”按钮,你可以使用失焦事件,该事件在元素失去焦点时触发。但为了确保元素实际上已更改(而不仅仅是获得和失去焦点),应将其内容与最后版本进行比较。或者使用keydown事件在此元素上设置一些“脏标记”。

2
你需要使用事件类型。
演示:
HTML
<div id="editor" contenteditable="true" >Some text here</div>

JS

const input = document.getElementById('editor');


input.addEventListener('input', updateValue);

function updateValue(e) {
  console.log(e.target);
}

know more


1

对我来说,我想要检查输入是否有效。

如果有效,则更新,否则显示错误消息并保持值与之前相同。

技巧:当您完成编辑时,通常会触发模糊事件。

示例

<span contenteditable="true">try input somethings.</span>
<script>
  const elem = document.querySelector(`span`)
  let oldValue = elem.innerText
  elem.onkeydown = (keyboardEvent) => {
    if (keyboardEvent.key === "Enter") {
      elem.blur() // set focusout
    }
  }
  elem.onblur = (e) => {
    const curValue = elem.innerText
    if (curValue === oldValue) {
      return
    }
    if (curValue.length <= 50) { //  Input your conditions.
      //  fail
      elem.innerText = oldValue
      
      // (Optional) Add error message
      elem.insertAdjacentHTML("beforeend", `<span style="margin-left:5px;color:red">error length=${curValue.length}. Must greater than 50. undo to the previous value.</span>`)
      const errMsg = elem.querySelector(`span`)
      setTimeout(() => errMsg.remove(), 3500) // wait 3.5 second, and then remove it.
      return
    }
    //  OK, update
    oldValue = curValue
  }
</script>


0
使用DOMCharacterDataModified under MutationEvents将导致相同的结果。设置超时是为了防止发送错误的值(例如,在Chrome中,我遇到了一些空格键的问题)
var timeoutID;
$('[contenteditable]').bind('DOMCharacterDataModified', function() {
    clearTimeout(timeoutID);
    $that = $(this);
    timeoutID = setTimeout(function() {
        $that.trigger('change')
    }, 50)
});
$('[contentEditable]').bind('change', function() {
    console.log($(this).text());
})

JSFIDDLE 示例


1
+1 - 当用户修改现有文本时,例如应用粗体或斜体时,DOMCharacterDataModified 不会触发。在这种情况下,DOMSubtreeModified 更合适。此外,人们应该记住,旧版浏览器不支持这些事件。 - Andy E
3
请注意,由于性能问题,W3C已经弃用了Mutation Events。有关更多信息,请参阅此Stack Overflow问题 - jrullmann

0
我编写了一个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')
                }
            })
        })
    }
})(jQuery);

您可以简单地调用$('.wysiwyg').wysiwygEvt();

如果需要,您也可以删除/添加事件


2
随着可编辑内容的增加(innerHTML是昂贵的),这将变得缓慢和卡顿。我建议在可能的情况下使用input事件,并回退到类似于此但带有某种去抖动的东西。 - Tim Down

0

为了后人,十年后不需要“保存”按钮,请查看已接受答案的jsfiddle。 - revelt

0
  1. 在可编辑元素上设置输入事件触发器

    document.getElementById("contenteditableElement").addEventListener("input", function() { elementEdited(); }, false);

  2. 在可编辑元素失去焦点时保存值

    jQuery("#contenteditableElement").blur(function(){ //一旦元素失去焦点,您可以保存新值等等.. });


0
一个简单的 JQuery 答案,我刚刚创建了这段代码,认为它对其他人也会有帮助。
    var cont;

    $("div [contenteditable=true]").focus(function() {
        cont=$(this).html();
    });

    $("div [contenteditable=true]").blur(function() {
        if ($(this).html()!=cont) {
           //Here you can write the code to run when the content change
        }           
    });

请注意,$("div [contenteditable=true]")将选择一个div的所有子元素,无论是直接还是间接的,只要它们是可编辑的。 - Bruno Ferreira

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接