当前位置: 首页 > 面试题库 >

React.js:contentEditable的onChange事件

高晋
2023-03-14
问题内容

如何监听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} />);

jsbin

后者在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;
    }
});


 类似资料:
  • 问题内容: 我正在用Mocha和Enzyme测试反应成分。这是组件(为简化起见,已简化): 这是测试: 我期望当用户在框中键入文本时,将调用该方法。上面的测试失败了: 我究竟做错了什么? 我应该澄清一下,我的目标是测试该方法是否被调用。我怎样才能做到这一点? 问题答案: 您可以直接通过原型直接监视该方法。 另外,您可以在实例的方法上使用间谍,但是您必须进行强制更新,因为在调用mount之后该组件已

  • 问题内容: 我正在使用事件委托来侦听DOM中较低级的事件,但不适用于选择框上的onchange事件。onchange事件会传播还是冒充DOM? 谷歌搜索未能找到结论性的答案。 问题答案: 根据规范,,,应该气泡和和不应该泡沫。 此行为是正确实现在所有web浏览器除了IE <9,即,,,做适当气泡在IE> = 9。

  • 本文向大家介绍jsp中select的onchange事件用法实例,包括了jsp中select的onchange事件用法实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了jsp中select的onchange事件用法。分享给大家供大家参考,具体如下: 希望本文所述对大家JSP程序设计有所帮助。

  • 本文向大家介绍jQuery Datepicker onchange事件如何工作?,包括了jQuery Datepicker onchange事件如何工作?的使用技巧和注意事项,需要的朋友参考一下 要使用jQuery Datepicker onchange(),请使用datepicker onSelect 事件。这将显示我们当前添加和更改的日期。 示例 您可以尝试运行以下代码,以了解jQuery D

  • 问题内容: 从和/或内部,如何确定复选框的新状态? 问题答案: 简短的答案: 使用该事件,直到值更新后才会触发,并在您希望它触发时触发: 更长的答案: 该事件处理函数不是调用,直到状态已经更新,但因为(蒂姆·布泰在评论中指出)IE不火,直到选框失去焦点的事件,你没有得到主动通知。更糟的是,与IE浏览器,如果你点击一个标签的复选框(而不是复选框本身)进行更新,你可以得到的印象是。这是因为如果复选框具

  • 本文向大家介绍input的onblur和onchange事件区别是什么?相关面试题,主要包含被问及input的onblur和onchange事件区别是什么?时的应答技巧和注意事项,需要的朋友参考一下 在 失去焦点时候触发。与之对应的是 事件。无论 是否有值、值是否有变化,都会触发。 在 发生变化然后在失去焦点的时候触发。且先于 触发。 只有在 的值必须与前一次输入不同才会触发。 一个简单的小例子: