firefox - 在 Safari 和 Firefox 中的 React 中重新渲染时插入符号位置恢复到 contenteditable 跨度的开始

标签 firefox reactjs safari contenteditable caret

在 Safari 或 Firefox 中将文本输入到 contenteditable 范围时,插入符号会在每次按键时移到开头。这似乎只在 React 重新/渲染组件时发生。

Chrome 工作得很好。没有测试过IE。
| 的示例是插入符号并键入 Hello :
| |H |eH |leH |lleH |olleH
这是我的组件的简化版本:

import React, { Component } from 'react';

class ContentEditable extends Component {
    constructor(props) {
        super(props);

        this.state = {
            value: props.value
        };
    }

    createMarkup() {
        return { __html: this.state.value };
    }

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

    isValid() {
        let bestLength = 3;

        return this.state.value.length > bestLength;
    }

    render() {
        let className = '';
        if (this.isValid()) {
            className = 'is-valid';
        }

        return (
            <span
                contentEditable="true"
                onInput={ this.handleInput.bind(this) }
                className={ className }
                dangerouslySetInnerHTML={ this.createMarkup() }
            >
            </span>
        );
    }
}

ContentEditable.propTypes = {
    value: React.PropTypes.string.isRequired
};

export default ContentEditable;

有人遇到过这个吗?

最佳答案

您可以实现contenteditable通过将处理程序添加到 HTML 标记。
问题是每次重新渲染内容时,光标的位置都会重置。您正在触发 setStatespan的内容被编辑,这是重置光标位置。
您宁愿存储对 span 的引用标记并更新其值,而不是触发状态更改。
一个 ref可以存储这将在跨度中注入(inject)值。

class ContentEditable extends Component {
  constructor(props) {
    super(props);
    this.spanRef = React.createRef();
    this.val = props.value;
  }

  handleInput(event) {
    const { innerText } = event.target;
    if (this.val !== innerText) {
      this.spanRef.innerText = innerText;
      this.val = innerText;
    }
  }

  render() {
    return (
      <span
        contentEditable="true"
        className={"is-valid"}
        onInput={this.handleInput.bind(this)}
        ref={this.spanRef}
        suppressContentEditableWarning={true}
      >
        {this.val}
      </span>
    );
  }
}
Running code

关于firefox - 在 Safari 和 Firefox 中的 React 中重新渲染时插入符号位置恢复到 contenteditable 跨度的开始,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40537746/

相关文章:

javascript - 如何在不使用 Flux 的情况下将状态从深层节点传播到嵌套树的根?

javascript - 如何使用 Firebug 调试 Firefox 扩展?

asp.net - 如何防止 Google Chrome 在 ASP.NET MVC 中保存密码?

twitter-bootstrap - 使用 Bootstrap 3.1 修复 Firefox 文件输入问题?

css - 位置 :absolute in FireFox 有点奇怪

reactjs - redux-saga-test-plan put 效果不匹配,但实际和预期的有效载荷相等

javascript - 如何管理带有父字段和子字段的表单的显示

javascript - window.open 始终在 iPad 的 Mobile Safari 中打开新选项卡

javascript - 在 Safari 中从 iOS 10 webapp 打开网站

javascript - 如何将这个非常简单的 pageAction Chrome 扩展程序移植到 Firefox 和 Safari 上运行