更新 这是一些演示
contentEditable demo-需要双击才能使H1变为可编辑状态
replace with input demo-采用event.target
样式,但在渲染时使UI“抽搐”
所以我有一些功能组件,比如:
component1.js
import React from 'react';
const component1 = props => (
<div>
<h1>Title</h1>
</div>
);
export { component1 };
它们是可变的。 event.target
可以是任何带有文本的内容,因此,段落,标题都可以。我试图让用户通过单击内容来内联编辑内容,因此我将一个函数editMode
传递给这些功能组件,这将通过编辑信息来更新父状态,就像这样:
<h1 onClick={event => {editMode(event, props.name, props.title, 'title')}}>title</h1>
这会将父本地状态更改为具有所有必要信息,以便从redux获取值,定义目标等。在此示例中,props.name
是组件的名称,props.title
是值,而'title'
是redux中的对象键。
因此,我将添加一些内容到 component1.js 中,并使它看起来像这样:
import React from 'react';
const component1 = props => (
<div>
{props.editState === 'true' &&
<EditLayout
name={props.name}
target={props.target}
value={props.value}
onChange={event => someFunc(event)}
/>
}
<h1>Title</h1>
</div>
);
export { component1 };
现在这可以正常工作,只是无法缩放。在这种情况下,EditLayout
将仅返回具有正确值的输入。我需要做的是适应单击的内容,获取字体大小,背景,填充,边距,位置。我这样做对吗?我尝试的每种方式都遇到了巨大的问题:
想法1-将EditLayout
组件移到功能组件之外
问题:定位
因此,我将把EditLayout移到同时包含component1.js
和EditLayout
的父组件中。这将使我能够从功能组件内部进行操作,而不必在所有位置都包含它。然后,我将像这样从event.target
获取坐标和其他重要信息:
const coords = event.target.getBoundingClientRect();
const offsetX = coords.left;
const offsetY = coords.top;
const childHeight = coords.height;
const childWidth = coords.width;
const childClass = event.target.className;
然后我将包装EditLayout
以返回一个包含输入的容器,并将尺寸/坐标应用于绝对定位的容器。这将产生一个输入会被随机像素偏移的问题,具体取决于event.target
的大小/位置。
想法2-将相关的计算样式传递给EditLayout
问题:在渲染时抽搐,我必须为每个可能的EditLayout
添加event.target
,并对其渲染条件进行限制
所以我将抓住所有重要的计算样式,如下所示:
const computedTarget = window.getComputedStyle(event.target);
const childMargins = computedTarget.marginBottom;
const childPaddings = computedTarget.padding;
const childFontSize = computedTarget.fontSize;
const childTextAlign = computedTarget.textAlign;
并将其传递到component1.js
,然后将其传递到EditLayout
event.target内的component1.js. I'll then condition the
组件以隐藏它是否被编辑,如下面这样:
<h1 className={ props.target === 'title' ? 'd-none' : ''}>Title</h1>
并设置EditLayout
仅在需要时显示:
{props.target === 'title' && <EditLayout />}
在此示例中,单击h1将显示输入,但是布局本身在渲染时带有抽搐。输入将具有与h1或event.target
完全相同的页边距和字体大小,但它会显得更大并扩展布局。演示:
想法3-使用条件内容可编辑
问题:需要双击才能启用,在safari中不起作用,不允许我预先选择值
这是所有人中最奇怪的。我认为这很简单,可以在功能组件render中执行以下操作:
<h1 contentEditable={props.target === 'title'} onClick={event => props.setTarget(event)}>Title</h1>
但是,我必须双击以启用它。我不知道为什么,如果每次触发onClick
时都附加一个控制台日志,我将获得正确的输出,我也将获得正确的目标值。我已经尝试了多种方法,但是只需要双击即可。甚至尝试在功能组件内部处理此问题,因为大多数内容都是由父组件处理的,没有任何区别。
我简化了示例,因此可以安全地假设/理解以下内容:
EditLayout
是样式化的组件
它接受道具并将其变成CSS,例如:font-size: ${props
=> props.fontSize};
getComputedStyle()
或getBoundingClientRect()
返回的任何内容答案 0 :(得分:0)
因此,有一个巧妙的解决方案,contentEditable
需要两次单击而不是单击,而不是绑定onClick
并传递以启用contentEditable
,只需保持contentEditable
为真并处理即可随你喜欢而改变。这是一个有效的h1
,与演示中的点击不同,无需点击两次即可启用contentEditable
<h1
className="display-4 text-center"
contentEditable
suppressContentEditableWarning
onBlur={event => updateValues(event)}
>
Title
</h1>
触发器更新的可用方法可以是onBlur
或onInput
。