代码如:
...text <span contenteditable="true" onChange="someFunction()">blah blah</span> text...
onChange 事件不起作用。(至少在 FireFox 中)
我不想使用 textarea/input 标签,因为必须可以只更改文本中的特定单词,并且必须内联显示(而不是块)。
有没有办法做到这一点?
代码如:
...text <span contenteditable="true" onChange="someFunction()">blah blah</span> text...
onChange 事件不起作用。(至少在 FireFox 中)
我不想使用 textarea/input 标签,因为必须可以只更改文本中的特定单词,并且必须内联显示(而不是块)。
有没有办法做到这一点?
并不真地。最近的 WebKit 浏览器支持元素input
上的 HTML5事件contenteditable
,这是理想的,但在其他浏览器中不支持(更新 2012 年 12 月 31 日:Firefox 从版本 14 开始支持此功能)。否则,您可能可以使用DOM 突变事件 DOMNodeInserted
,DOMNodeRemoved
和DOMCharacterDataModified
,但它们有两个缺点:首先,它们在 IE < 9 或任何版本的 Opera 中不支持contenteditable
元素,其次,具有替换事件的新规范在作品,这意味着它们可能会在未来的浏览器中被替换。
现场示例:http : //jsfiddle.net/MBags/
或者,您可以转到较低级别并处理键、鼠标和剪贴板事件(cut
和paste
),这将适用于所有主要浏览器,但这意味着您需要在每次触发此类事件时检查可编辑内容是否已更改,这将得到大量内容的滞后和损害用户体验。
我构建了一个 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;
};
}
}
因为非输入元素没有传统的类似输入的事件,所以您必须自己将一些东西混合在一起。为此:
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);
}
};
}
尽管正如Tim Down所指出的那样,这应该不需要太长时间,但支持旧浏览器的明显例外。