我创建了一个脚本,该脚本在父容器上的鼠标悬停时激活,并且应该将其子元素从鼠标移开。我目前已经让它工作了,但代码的某些部分似乎与 REACT 代码的外观相矛盾。特别是两部分。
我在渲染函数中使用了一个计数器,以便每个跨度都能获得正确的自定义属性,state.customProperties该自定义属性是一个数组,该数组在父元素鼠标悬停时更新自定义属性。
render() {
let counter = 0;
const returnCustomProp = function(that) {
counter++;
let x = 0;
if (that.state.customProperties[counter - 1]) {
x = that.state.customProperties[counter - 1].x;
}
let y = 0;
if (that.state.customProperties[counter - 1]) {
y = that.state.customProperties[counter - 1].y;
}
return "customProperty(" + x + " " + y + ")";
}
return (
<div onMouseMove={this._testFunction} id="ParentContainer">
<section custom={returnCustomProp(this)}>
<b>Custom content for part 1</b>
<i>Could be way different from all the other elements</i>
</section>
<section custom={returnCustomProp(this)}>
2
</section>
<section custom={returnCustomProp(this)}>
<div>
All content can differ internally so I'm unable to create a generic element and loop trough that
</div>
</section>
<section custom={returnCustomProp(this)}>
4
</section>
<section custom={returnCustomProp(this)}>
5
</section>
<section custom={returnCustomProp(this)}>
<div>
<b>
This is just test data, the actualy data has no divs nested inside secions
</b>
<h1>
6
</h1>
</div>
</section>
<section custom={returnCustomProp(this)}>
7
</section>
<section custom={returnCustomProp(this)}>
8
</section>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)在 mousemove 函数中,我使用document.getElementById和querySelectorAll获取所有截面元素并将鼠标的鼠标坐标与截面元素坐标进行比较。
var mouseX = e.pageX;
var mouseY = e.pageY;
var spans = document.getElementById('ParentContainer').querySelectorAll('section');
var theRangeSquared = 10 * 10;
var maxOffset = 5;
var newCustomProperties = [];
for (var i = 0; i < spans.length; i++) {
var position = spans[i].getBoundingClientRect();
var widthMod = position.width / 2;
var heightMod = position.height / 2;
var coordX = position.x + widthMod;
var coordY = position.y + heightMod + window.scrollY;
// Distance from mouse
var dx = coordX - mouseX;
var dy = coordY - mouseY;
var distanceSquared = (dx * dx + dy * dy);
var tx = 0,
ty = 0;
if (distanceSquared < theRangeSquared && distanceSquared !== 0) {
// Calculate shift scale (inverse of distance)
var shift = maxOffset * (theRangeSquared - distanceSquared) / theRangeSquared;
var distance = Math.sqrt(distanceSquared);
tx = shift * dx / distance;
ty = shift * dy / distance;
}
newCustomProperties.push({
x: tx,
y: ty
});
}
Run Code Online (Sandbox Code Playgroud)我有一种感觉,我将这一切都错了。我不确定如何在保留通用returnCustomProp函数以返回所述元素的属性的同时避免使用计数器(在实时代码中,我有大约 200 个这些元素,因此手动为它们设置数组项编号效率不高) .
第二部分通过实际组件内的 ID 定位元素感觉很糟糕。我觉得我应该能够在不遍历 DOM 的情况下定位它。引用 section 元素可能是一个解决方案,但我相信引用应该保持在最低限度,正如所述,实际代码由数百个这样的部分组成。
代码不会比更新custom="customProperty(0 0)"属性做更多的 atm 。您可以通过鼠标悬停时的元素检查器看到这种情况。
我可以让这个功能工作而不必计算<section>渲染函数中的元素而不必使用document.querySelectorAll吗?
如何在 React 组件中定位 DOM 元素?
根据 React 的官方文档,您可以使用 refs 访问 dom 元素。您必须使用React.createRef()调用创建一个引用。
我应该完全避免针对 DOM 元素吗?
遍历 dom 以获取特定的 dom 元素对于 React 来说不是一个好习惯,因为它会导致性能问题。但是,react 允许通过使用createRef().
我可以在不必计算渲染函数内的元素并且不必使用 document.querySelectorAll 的情况下使此功能工作吗?
是的,请考虑以下步骤来实现这一点:
在构造函数中,为 parentContainer 创建一个 ref,如下所示:
this.ParentContainer=React.createRef();
Run Code Online (Sandbox Code Playgroud)
然后在渲染中使用 parentContainer ref:
<div onMouseMove={this._testFunction} id="ParentContainer"
ref={this.ParentContainer} >
Run Code Online (Sandbox Code Playgroud)
在测试组件中,使用 this.parentContainer 作为:
//replace this
//var spans = document.getElementById('ParentContainer').querySelectorAll('section');
//with this
var spans = this.parentContainer.current.childNodes;
Run Code Online (Sandbox Code Playgroud)
你可以在这里查看
编辑
关于如何解决不得不在渲染函数中使用 let 计数器的任何想法
您可以returnCustomProp像这样定义外部渲染:(在这里您需要传递每个部分的索引而不是this引用)
returnCustomProp = (index)=> {
let x = 0;
if(this.state.customProperties[index]) {
x = this.state.customProperties[index].x;
}
let y = 0;
if(this.state.customProperties[index]) {
y = this.state.customProperties[index].y;
}
return "customProperty("+x+" "+y+")";
}
Run Code Online (Sandbox Code Playgroud)
并将其与这样的部分一起使用:
<section custom={returnCustomProp(0)}>
<b>Custom content for part 1</b>
<i>Could be way different from all the other elements</i>
</section>
<section custom={returnCustomProp(1)}>
2
</section>
<section custom={returnCustomProp(2)}>
<div>
All content can differ internally so I'm unable to create a generic element and loop trough that
</div>
</section>
<section custom={returnCustomProp(3)}>
4
</section>
<section custom={returnCustomProp(4)}>
5
</section>
<section custom={returnCustomProp(5)}>
<div>
<b>
This is just test data, the actual data has no divs nested inside sections
</b>
<h1>
6
</h1>
</div>
</section>
<section custom={returnCustomProp(6)}>
7
</section>
<section custom={returnCustomProp(7)}>
8
</section>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
727 次 |
| 最近记录: |