Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 内容可编辑更改事件_Javascript_Jquery_Html_Contenteditable - Fatal编程技术网

Javascript 内容可编辑更改事件

Javascript 内容可编辑更改事件,javascript,jquery,html,contenteditable,Javascript,Jquery,Html,Contenteditable,我想在用户使用contenteditable属性编辑div的内容时运行一个函数。onchange事件的等价物是什么 我正在使用jQuery,所以任何使用jQuery的解决方案都是首选。谢谢 当具有contentEditable属性的元素发生更改时,onchange事件不会触发,建议的方法是添加一个按钮以保存版本 检查此插件,它以这种方式处理问题: 我建议将监听器附加到可编辑元素触发的关键事件,不过您需要知道,keydown和keypress事件是在内容本身更改之前触发的。这并不能涵盖更改内容的所

我想在用户使用contenteditable属性编辑div的内容时运行一个函数。onchange事件的等价物是什么


我正在使用jQuery,所以任何使用jQuery的解决方案都是首选。谢谢

当具有contentEditable属性的元素发生更改时,onchange事件不会触发,建议的方法是添加一个按钮以保存版本

检查此插件,它以这种方式处理问题:


我建议将监听器附加到可编辑元素触发的关键事件,不过您需要知道,keydown和keypress事件是在内容本身更改之前触发的。这并不能涵盖更改内容的所有可能方法:用户还可以使用“编辑”或“上下文浏览器”菜单中的“剪切”、“复制”和“粘贴”,因此您可能还需要处理“剪切”“复制”和“粘贴”事件。此外,用户还可以删除文本或其他内容,例如mouseup,因此那里有更多的事件。您可能希望轮询元素的内容作为回退

2014年10月29日更新

从长远来看,这就是答案。在撰写本文时,Firefox14和WebKit/Blink浏览器支持当前Mozilla中的contenteditable元素,但IE不支持

演示:

document.getElementByIdeditor.addEventListenerinput,函数{ 已激发console.loginput事件; },假;
请在此处键入内容为了避免计时器和保存按钮,您可以使用模糊事件,当元素失去焦点时会触发模糊事件。但为了确保该元素实际上发生了变化,而不仅仅是聚焦和散焦,它的内容应该与上一个版本进行比较。或者使用keydown事件在此元素上设置一些脏标志。

查看此想法。


我想差不多了。HTML5确实需要将更改事件添加到规范中。唯一的问题是回调函数在$this.HTML中实际更新内容之前计算before==$this.HTML。我不工作,这很可悲。让我知道你的想法。

我已经这样修改了劳万钦的答案,这对我很有用。我使用keyup事件而不是keypress,这非常有效

$('#editor').on('focus', function() {
  before = $(this).html();
}).on('blur keyup paste', function() { 
  if (before != $(this).html()) { $(this).trigger('change'); }
});

$('#editor').on('change', function() {alert('changed')});

以下是对我有效的方法:

   var clicked = {} 
   $("[contenteditable='true']").each(function(){       
        var id = $(this).attr("id");
        $(this).bind('focus', function() {
            // store the original value of element first time it gets focus
            if(!(id in clicked)){
                clicked[id] = $(this).html()
            }
        });
   });

   // then once the user clicks on save
   $("#save").click(function(){
            for(var id in clicked){
                var original = clicked[id];
                var current = $("#"+id).html();
                // check if value changed
                if(original != current) save(id,current);
            }
   });

这是我最终使用的解决方案,效果非常好。我改用$this.text,因为我只使用了内容可编辑的单行div。但是您也可以通过这种方式使用.html,您不必担心全局/非全局变量的范围,并且before实际上附加到editordiv

$('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!');
    }
});

下面是一个更有效的版本,它对所有contenteditables使用on。这是基于这里的顶级答案

$('body').on('focus', '[contenteditable]', function() {
    const $this = $(this);
    $this.data('before', $this.html());
}).on('blur keyup paste input', '[contenteditable]', function() {
    const $this = $(this);
    if ($this.data('before') !== $this.html()) {
        $this.data('before', $this.html());
        $this.trigger('change');
    }
});
项目在这里:

使用将导致相同的结果。设置超时是为了防止发送不正确的值,例如,在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());
})

在我调查这个问题时,这条线索非常有用

我已经将这里提供的一些代码修改为jQuery插件,因此它是一种可重用的形式,主要是为了满足我的需要,但其他人可能会喜欢使用contenteditable标记的简单界面

更新: 由于它越来越受欢迎,该插件已被

发展将从这里继续:

考虑使用。这些观察器旨在对DOM中的更改做出反应,并作为对DOM的性能替代

优点:

当发生任何更改时触发,这很难通过听取其他答案建议的关键事件来实现。例如,所有这些都可以很好地工作:拖放、斜体、通过上下文菜单复制/剪切/粘贴。 设计时考虑到性能。 简单明了的代码。更容易理解和调试侦听一个事件的代码,而不是侦听10个事件的代码。 谷歌有一个很好的解决方案,这使得使用MutationObserver非常容易。 缺点:

需要最新版本的Firefox 14.0+、Chrome 18+或IE 11+。 需要理解的新API 关于最佳实践或案例研究的信息还不多 了解更多信息:

我写了一些比较使用MutationObserers和处理各种事件的文章。我用了巴卢普顿的密码,因为他的投票数最多。 在API上有一个非常好的页面 看看图书馆
为此,我构建了一个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

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

非jQuery快速脏答:


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
        }           
    });
非JQuery答案

function makeEditable(elem){
    elem.setAttribute('contenteditable', 'true');
    elem.addEventListener('blur', function (evt) {
        elem.removeAttribute('contenteditable');
        elem.removeEventListener('blur', evt.target);
    });
    elem.focus();
}
要使用它,请调用id=myHeader的header元素

makeEditable(document.getElementById('myHeader'))

用户现在可以编辑该元素,直到它失去焦点。

根据@balupton的回答:

$document.on'focus','contenteditable',e=>{ 常量self=$e.target self.data'before',self.html } $document.on'blur','contenteditable',e=>{ 常量self=$e.target 如果self.data'before'!==self.html{ 自我。触发“改变” } } 两种选择:

1对于现代evergreen浏览器: 输入事件将充当替代更改事件

2考虑IE11和现代evergreen浏览器: 这将监视div中的元素更改及其内容

const p=document.querySelector'p' const result=document.querySelector'div' const observer=新的mutationobserver mutationrecords=>{ result.textContent=mutationRecords[0]。target.data //result.textContent=p.textContent } 观察者,观察者{ characterData:true, 子树:对, } abc

角度2+

您需要使用输入事件类型

演示

HTML



我还应该补充一点,通过使用浏览器的“编辑”菜单或上下文菜单来剪切、复制或粘贴内容,可以更改可编辑元素,因此您需要在支持IE 5+、Firefox 3.0+、Safari 3+、ChromeYou的浏览器中处理剪切、复制和粘贴事件。您可以使用keyup,并且不会出现计时问题。@Blowsie:Yes,但在事件触发之前,自动重复按键可能会导致很多变化。还有其他更改此答案未考虑的可编辑文本的方法,例如通过“编辑”和上下文菜单进行拖放和编辑。从长远来看,HTML5输入事件应该涵盖这一切。我正在使用debounce进行键控。@AndroidDev I testet Chrome,并且输入事件也会在复制粘贴和剪切时触发,按照规范的要求:+1-当用户修改现有文本时,DOMCharacterDataModified不会触发,例如应用粗体或斜体。在这种情况下,domsubtreemeding更合适。另外,人们应该记住,传统浏览器不支持这些事件。请注意,w3c会因为性能问题而贬低突变事件。更多内容可以在中找到。非常适合我,感谢CoffeeScript和Javascript。在内容模糊之前,此代码不会捕捉到一些更改。例如:拖放、从关联菜单剪切和从浏览器窗口粘贴。我已经设置了一个示例页面,该页面使用此代码,您可以与之交互。@jrullmann是的,我在拖放图像时遇到了此代码问题,因为它不侦听图像加载。在我的case@jrullmann非常好,即使在使用javascript更改值时也可以使用,在控制台中尝试:document.getElementById'editor_input'。innerHTML='ssss'。缺点是它需要IE11@NadavB不应该,因为如果$this.data'before'!=$这个是.html{是因为它与HTML5输入事件不太一样,HTML5输入事件在所有支持变异观察器的WebKit和Mozilla浏览器中都支持contenteditable,因为DOM变异可以通过脚本和用户输入发生,但对于这些浏览器来说,这是一个可行的解决方案。我认为它对性能的损害也可能大于输入事件,但是t我对此没有确凿的证据。+1,但您是否意识到突变事件不会在contenteditable中报告换行的效果?请在您的代码段中按enter键。@citykid:这是因为该代码段仅监视字符数据的更改。也可以观察DOM结构的更改。例如,请参阅Internet Explorer 11+supports。我至少能够在Chrome 43.0.2357.130中验证HTML5输入事件在每种情况下都会触发,特别是通过上下文菜单拖放、斜体、复制/剪切/粘贴。我还测试了粗体w/cmd/ctrl+b,并得到了预期的结果。我还检查并能够验证输入事件不会在progra上触发mmatic更改看起来很明显,但可以说与相关MDN页面上的一些令人困惑的语言相反;请参阅此处页面底部,了解我的意思:尝试使用keyup而不是keypress。随着可编辑内容变长,这将变得缓慢和滞后。innerHTML非常昂贵。我建议在存在输入事件的地方使用输入事件,然后将其删除返回到类似这样的内容,但需要某种程度的去抖动将直接或间接地选择一个div中所有内容可编辑的子元素。呃,为什么没有解释就投反对票?这对写答案的人和以后阅读答案的每个人都是有害的。此代码使元素内容可编辑,直到失去焦点。我认为这不能回答问题。问题on是如何在contenteditable元素更改时运行函数?这是什么删除事件?这看起来很有趣。有人能提供一些解释吗?对于后代,十年以后,不需要保存按钮,请检查接受答案的JSFIDLE。我通常这样做:document.getElementByIdeditor.oninput=function{…}。下面有一个很好的答案:记住,如果你否决了某个答案,你有责任留下评论。解释为什么答案不令人满意,除非有人已经留下了评论 评论,你只是同意他们。只需使用输入事件!如果您需要支持IE11,请使用变异观察者。我喜欢。简明扼要。
makeEditable(document.getElementById('myHeader'))
document.querySelector('div').addEventListener('input', (e) => {
    // Do something with the "change"-like event
});
<div oninput="someFunc(event)"></div>
$('div').on('click', function(e) {
    // Do something with the "change"-like event
});
var div = document.querySelector('div');
var divMO = new window.MutationObserver(function(e) {
    // Do something on change
});
divMO.observe(div, { childList: true, subtree: true, characterData: true });
<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 
 }
}


<div id="editor" contenteditable="true" >Some text here</div>
const input = document.getElementById('editor');


input.addEventListener('input', updateValue);

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