React.js:contentEditable的onChange事件

如何监听contentEditable基于控件的更改事件?

var Number = React.createClass({

render: function() {

return <div>

<span contentEditable={true} onChange={this.onChange}>

{this.state.value}

</span>

=

{this.state.value}

</div>;

},

onChange: function(v) {

// Doesn't fire :(

console.log('changed', v);

},

getInitialState: function() {

return {value: '123'}

}

});

React.renderComponent(<Number />, document.body);

http://jsfiddle.net/NV/kb3gN/1621/

回答:

请参阅SebastienLorber的答案,该答案修复了我的实现中的错误。

编辑06/2016:我刚刚遇到了一个新问题,当浏览器尝试“重新格式化”刚刚给他的html时,会导致组件始终重新呈现,这会出现一个新问题。看到

编辑07/2016:这是我的生产contentEditable实现。它有一些react-contenteditable您可能想要的其他选项,包括:

锁定

命令式API允许嵌入html片段

重新格式化内容的能力

摘要:

在我遇到新问题之前,FakeRainBrigand的解决方案对我来说已经工作了一段时间。ContentEditables很痛苦,而且很难与React一起处理。

这个JSFiddle演示了这个问题。

如您所见,当您键入一些字符并单击时Clear,不会清除内容。这是因为我们尝试将contenteditable重置为最后一个已知的虚拟dom值。

因此看来:

您需要shouldComponentUpdate防止插入符位置跳动

如果使用shouldComponentUpdate这种方式,则不能依赖React的VDOM差异算法。

因此,您需要额外的一行,以便每当shouldComponentUpdate返回yes时,就可以确保DOM内容实际上已更新。

因此,此处的版本添加了componentDidUpdate,变为:

var ContentEditable = React.createClass({

render: function(){

return <div id="contenteditable"

onInput={this.emitChange}

onBlur={this.emitChange}

contentEditable

dangerouslySetInnerHTML={{__html: this.props.html}}></div>;

},

shouldComponentUpdate: function(nextProps){

return nextProps.html !== this.getDOMNode().innerHTML;

},

componentDidUpdate: function() {

if ( this.props.html !== this.getDOMNode().innerHTML ) {

this.getDOMNode().innerHTML = this.props.html;

}

},

emitChange: function(){

var html = this.getDOMNode().innerHTML;

if (this.props.onChange && html !== this.lastHtml) {

this.props.onChange({

target: {

value: html

}

});

}

this.lastHtml = html;

}

});

虚拟dom仍然过时了,它可能不是最有效的代码,但至少它确实有效:) 我的错误已解决

细节:

1)如果放置了shouldComponentUpdate以避免插入符号跳动,则contenteditable永不放弃(至少在击键时)

2)如果组件从不在按键时重新渲染,那么React会为此内容保留一个过时的虚拟dom。

3)如果React在其虚拟dom树中保留了contenteditable的过时版本,那么如果您尝试将contenteditable重置为虚拟dom中过时的值,那么在虚拟dom diff期间,React将计算出对申请DOM!

这种情况通常发生在以下情况:

您最初具有一个可编辑的空内容(shouldComponentUpdate = true,prop =“”,先前的vdom = N / A),

用户键入一些文本,然后阻止渲染(shouldComponentUpdate = false,prop = text,先前的vdom =“”)

用户单击验证按钮后,您想清空该字段(shouldComponentUpdate = false,prop =“”,上一个vdom =“”)

由于新产生的vdom和旧的vdom均为“”,因此React不会接触dom。


使用onInput事件,也可以使用onBlur作为后备。您可能需要保存以前的内容,以防止发送额外的事件。

我个人将其作为渲染功能。

var handleChange = function(event){

this.setState({html: event.target.value});

}.bind(this);

return (<ContentEditable html={this.state.html} onChange={handleChange} />);

回答:

后者在contentEditable周围使用了这个简单的包装器。

var ContentEditable = React.createClass({

render: function(){

return <div

onInput={this.emitChange}

onBlur={this.emitChange}

contentEditable

dangerouslySetInnerHTML={{__html: this.props.html}}></div>;

},

shouldComponentUpdate: function(nextProps){

return nextProps.html !== this.getDOMNode().innerHTML;

},

emitChange: function(){

var html = this.getDOMNode().innerHTML;

if (this.props.onChange && html !== this.lastHtml) {

this.props.onChange({

target: {

value: html

}

});

}

this.lastHtml = html;

}

});

以上是 React.js:contentEditable的onChange事件 的全部内容, 来源链接: utcz.com/qa/401127.html

回到顶部