代码如:
...text <span contenteditable="true" onChange="someFunction()">blah blah</span> text...
onChange事件不起作用。 (至少在FireFox中)
我不想使用textarea / input标签,因为必须只能更改文本中的特定单词,并且必须以内联方式显示(而不是阻止)。
有什么方法可以做到吗?
答案 0 :(得分:26)
不是真的。最近的WebKit浏览器支持input
元素上的HTML5 contenteditable
事件,这是理想的,但在其他浏览器中不受支持(更新2012年12月31日:Firefox支持此版本14)。否则,您可以使用DOM mutation events DOMNodeInserted
,DOMNodeRemoved
和DOMCharacterDataModified
,但这些有两个缺点:首先,它们在IE&lt; 9或任何版本的Opera contenteditable
元素,其次,带有替换事件的新规范正在开发中,这意味着它们可能会在未来的浏览器中被替换。
或者您可以降低级别并处理关键,鼠标和剪贴板事件(cut
和paste
),这些事件可以在所有主流浏览器中使用,但这意味着您需要检查是否可编辑每次发生此类事件时,内容都会发生变化,这会使得大量内容变得迟钝并损害用户体验。
答案 1 :(得分:9)
我构建了一个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 :(得分:6)
我写的功能:
对此函数的一次调用可修复页面中的所有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;
};
}
}
答案 3 :(得分:4)
因为非输入元素没有传统的类似输入的事件,所以你必须自己混合一些东西。为此:
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所述,这不应该太长,除了支持旧浏览器这一明显的例外。