Javascript 内容可编辑的 onChange 事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8694054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
onChange event with contenteditable
提问by Dani-Br
Code like:
代码如:
...text <span contenteditable="true" onChange="someFunction()">blah blah</span> text...
The onChange event doesn't work. (at least in FireFox)
I don't want to use textarea/input tags, because there must be available to change only particular words in text, and must be displayed inline (not block).
onChange 事件不起作用。(至少在 FireFox 中)
我不想使用 textarea/input 标签,因为必须可以仅更改文本中的特定单词,并且必须内联显示(而不是块)。
Is there any way how to do that ?
有没有办法做到这一点?
采纳答案by Dani-Br
The function that I wrote:
One call of this function fixes all ContentEditable elements in the page.
我编写的函数:
一次调用此函数即可修复页面中的所有 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;
};
}
}
回答by Tim Down
Not really. Recent WebKit browsers support the HTML5 input
event on contenteditable
elements, which is ideal, but not supported in other browsers (UPDATE 31 December 2012: Firefox supports this as of version 14). Otherwise you may be able to get by with DOM mutation eventsDOMNodeInserted
, DOMNodeRemoved
and DOMCharacterDataModified
, but these have two disadvantages: firstly, they are not supported in IE < 9 or any version of Opera for contenteditable
elements, and secondly, a new spec with replacement events is in the works, meaning they are likely to be replaced in future browsers.
并不真地。最近的 WebKit 浏览器支持元素input
上的 HTML5事件contenteditable
,这是理想的,但在其他浏览器中不支持(2012 年 12 月 31 日更新:Firefox 从版本 14 开始支持此功能)。否则,您可能可以使用DOM 突变事件DOMNodeInserted
, DOMNodeRemoved
and DOMCharacterDataModified
,但它们有两个缺点:首先,它们在 IE < 9 或任何版本的 Opera 中不支持contenteditable
元素,其次,具有替换事件的新规范在作品,这意味着它们可能会在未来的浏览器中被替换。
Live example: http://jsfiddle.net/MBags/
现场示例:http: //jsfiddle.net/MBags/
Or you could go lower level and handle key, mouse and clipboard events (cut
and paste
), which will work in all major browsers but will mean you'll need to check whether the editable content has changed each time such an event fires, which will get laggy and harm user experience for large pieces of content.
或者,您可以转到较低级别并处理键、鼠标和剪贴板事件(cut
和paste
),这将适用于所有主要浏览器,但这意味着您每次触发此类事件时都需要检查可编辑内容是否已更改,这将得到大量内容的滞后和损害用户体验。
回答by Blowsie
I built a jQuery plugin to do this.
我构建了一个 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);
You can simply call $('.wysiwyg').wysiwygEvt();
你可以简单地打电话 $('.wysiwyg').wysiwygEvt();
You can also remove / add events if you wish
如果您愿意,您还可以删除/添加事件
回答by David says reinstate Monica
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);
}
};
}
Though as noted by Tim Downthis shouldn't be necessary for too much longer, with the obvious exception of supporting older browsers.
尽管正如Tim Down所指出的那样,这应该不需要太长时间,除了支持旧浏览器的明显例外。