gpt4 book ai didi

javascript - 文本区域调整大小的移动浏览器问题

转载 作者:技术小花猫 更新时间:2023-10-29 12:12:14 25 4
gpt4 key购买 nike

我在 React.js 中工作,并且有 textarea 元素可以根据用户输入的大小动态扩展和收缩。预期功能如下:

Working correctly in a desktop context

这在桌面上下文中可以正常工作。但是,在现代浏览器(经过测试的 Safari、Chrome 和 Firefox)中的任何手机或平板电脑上,textarea 元素只会扩展,当内容被删除时它不会收缩。

起初我认为它可能与我使用的 onChange 处理程序有关,但是,当将它换成 onInput 处理程序时,同样的问题仍然存在。所以我认为问题在于 resize() 方法。

有人知道我为什么会遇到这个问题吗?

我创建了一个无样式的 fiddle 来与您分享基本功能。有趣的是,该错误不会出现在移动设备上的 JSFiddle 模拟器中,但如果您将相同的代码放在另一个 React 环境中,该错误就会出现在现代浏览器的移动设备上。

class Application extends React.Component {
render() {
return (
<div>
<Textarea value="This is a test" maxLength={500}/>
</div>
);
}
}


class Textarea extends React.Component {

constructor(props) {
super(props);

this.state = {
value: this.props.value
? this.props.maxLength && this.props.maxLength > 0
? this.props.value.length < this.props.maxLength
? this.props.value
: this.props.value.substring(0, this.props.maxLength)
: this.props.value
: '',
remaining: this.props.value
? this.props.value.length < this.props.maxLength
? this.props.maxLength - this.props.value.length
: 0
: this.props.maxLength
};

this.textAreaRef = React.createRef();

this.textAreaHeight = null;
this.textAreaoffSetHeight = null;
}


componentDidMount() {
window.addEventListener('resize', this.resize);
this.resize();
}

componentWillUnmount() {
window.removeEventListener('resize', this.resize);
}

handleChange = event => {
const target = event.target || event.srcElement;

this.setState({
value: target.value,
remaining: target.value
? target.value.length < this.props.maxLength
? this.props.maxLength - target.value.length
: 0
: this.props.maxLength
});

this.resize();
};

resize = () => {
const node = this.textAreaRef.current;

node.style.height = '';

const style = window.getComputedStyle(node, null);

let heightOffset =
parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);

this.textAreaoffSetHeight = node.offsetTop;

this.textAreaHeight = node.scrollHeight + heightOffset;

node.style.height = this.textAreaHeight + 'px';

this.resizeBorder();
this.resizeParentNode();
};

resizeBorder = () => {
const textAreaSize = this.textAreaHeight;
const node = this.textAreaRef.current;
const borderNode = node.parentNode.querySelector(
'.textarea__border'
);

if (borderNode !== null) {
borderNode.style.top =
this.textAreaoffSetHeight + textAreaSize - 1 + 'px';
}
};

resizeParentNode = () => {
const node = this.textAreaRef.current;
const parentNode = node.parentNode;

if (parentNode !== null) {
parentNode.style.height = this.textAreaHeight + 40 + 'px';
}
};

render() {
return (
<div className={'textarea'}>
<textarea
ref={this.textAreaRef}
className={
!this.state.value
? 'textarea__input'
: 'textarea__input active'
}
value={this.state.value}
maxLength={
this.props.maxLength && this.props.maxLength > 0 ? this.props.maxLength : null
}
onChange={this.handleChange}
/>
<div className={'textarea__message'}>
{this.state.remaining <= 0
? `You've reached ${this.props.maxLength} characters`
: `${this.state.remaining} characters remaining`}
</div>
</div>
);
}
}


ReactDOM.render(
<Application />,
document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<main id="app">
<!-- This element's contents will be replaced with your component. -->
</main>

最佳答案

问题是您正在直接(或尝试)修改 DOM,而不是修改状态并允许 React 正常流动。您在 resize() 中修改 DOM 元素属性,然后任何输入更改都将立即调用 handleChange(e) 并重新流动您的 DOM 以覆盖修改。

切勿将 REACT 与 DOM TOUCHING 混合!!!

更改您的 resize 函数使其表现得像您的 handleChange(e) 函数,并在 render()

关于javascript - 文本区域调整大小的移动浏览器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54451545/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com