Javascript 为每个悬停的元素呈现唯一的div
最小可复制示例: 我目前有一个新元素被渲染时,其他两个元素中的任何一个被悬停。但我想根据悬停的元素呈现不同的东西 在下面的示例和代码笔中,有2个可悬停div被渲染;将其悬停在上方时,会更改状态并渲染另一个div。我想让HoverMe2 div呈现文本hello2。目前,无论我将鼠标悬停在hoverme1还是2上,它们都只是呈现文本helloJavascript 为每个悬停的元素呈现唯一的div,javascript,reactjs,Javascript,Reactjs,最小可复制示例: 我目前有一个新元素被渲染时,其他两个元素中的任何一个被悬停。但我想根据悬停的元素呈现不同的东西 在下面的示例和代码笔中,有2个可悬停div被渲染;将其悬停在上方时,会更改状态并渲染另一个div。我想让HoverMe2 div呈现文本hello2。目前,无论我将鼠标悬停在hoverme1还是2上,它们都只是呈现文本hello import React, { Component } from "react"; import { render } from "react-dom";
import React, { Component } from "react";
import { render } from "react-dom";
class HoverExample extends Component {
constructor(props) {
super(props);
this.handleMouseHover = this.handleMouseHover.bind(this);
this.state = {
isHovering: false
};
}
handleMouseHover() {
this.setState(this.toggleHoverState);
}
toggleHoverState(state) {
return {
isHovering: !state.isHovering
};
}
render() {
return (
<div>
<div
onMouseEnter={this.handleMouseHover}
onMouseLeave={this.handleMouseHover}
>
Hover Me
</div>
<div
onMouseEnter={this.handleMouseHover}
onMouseLeave={this.handleMouseHover}
>
Hover Me2
</div>
{this.state.isHovering && <div>hello</div>}
</div>
);
}
}
render(<HoverExample />, document.getElementById("root"));
正如@CevaComic所指出的,您可以通过CSS实现这一点。但是,如果您想使用React,例如,因为您的实际问题更复杂,下面是答案 您需要一种方法来区分这两个元素。这可以通过一些巧妙的技巧来完成,比如为每个元素设置一个唯一的id,传递一个自定义参数,或者其他什么 但是我建议不要使用很酷的技巧,因为它更难理解正在发生的事情,而且代码更容易出错。我认为最好的方法是使用一种愚蠢的方法,对独特的元素使用独特的函数 每个onMouseCenter和onMouseLeave都必须是一个唯一的函数,例如handleMouseHover1和handleMouseHover2,并且这些函数中的每一个都需要控制唯一的状态,例如isHovering1和isHovering2。然后必须根据状态渲染所需的元素。当然,对于真实世界的代码,您可能希望使用更具描述性的名称,以使代码更易于理解。完整的代码如下所示
class HoverExample extends Component {
state = {
isHovering1: false,
isHovering2: false
};
handleMouseHover1 = () => {
this.setState(({ isHovering1 }) => ({ isHovering1: !isHovering1 }));
};
handleMouseHover2 = () => {
this.setState(({ isHovering2 }) => ({ isHovering2: !isHovering2 }));
};
render() {
const { isHovering1, isHovering2 } = this.state;
return (
<div>
<div
onMouseEnter={this.handleMouseHover1}
onMouseLeave={this.handleMouseHover1}
>
Hover Me1
</div>
<div
onMouseEnter={this.handleMouseHover2}
onMouseLeave={this.handleMouseHover2}
>
Hover Me2
</div>
{isHovering1 && <div>hello1</div>}
{isHovering2 && <div>hello2</div>}
</div>
);
}
}
此外,更新的示例:
注意:我还对代码进行了编辑,添加了一些新ECMAScript版本中存在的语法。您可以使用箭头函数格式代替绑定函数,例如fn==>{…}。arrow函数表示此上下文自动绑定到该函数,因此不必手动执行。此外,您不必在构造函数中初始化this.state,您可以将其定义为类实例属性。将这两件事结合在一起,您根本不需要构造函数,而且它使代码更简洁 正如@CevaComic所指出的,你可以用CSS来实现这一点。但是,如果您想使用React,例如,因为您的实际问题更复杂,下面是答案 您需要一种方法来区分这两个元素。这可以通过一些巧妙的技巧来完成,比如为每个元素设置一个唯一的id,传递一个自定义参数,或者其他什么 但是我建议不要使用很酷的技巧,因为它更难理解正在发生的事情,而且代码更容易出错。我认为最好的方法是使用一种愚蠢的方法,对独特的元素使用独特的函数 每个onMouseCenter和onMouseLeave都必须是一个唯一的函数,例如handleMouseHover1和handleMouseHover2,并且这些函数中的每一个都需要控制唯一的状态,例如isHovering1和isHovering2。然后必须根据状态渲染所需的元素。当然,对于真实世界的代码,您可能希望使用更具描述性的名称,以使代码更易于理解。完整的代码如下所示
class HoverExample extends Component {
state = {
isHovering1: false,
isHovering2: false
};
handleMouseHover1 = () => {
this.setState(({ isHovering1 }) => ({ isHovering1: !isHovering1 }));
};
handleMouseHover2 = () => {
this.setState(({ isHovering2 }) => ({ isHovering2: !isHovering2 }));
};
render() {
const { isHovering1, isHovering2 } = this.state;
return (
<div>
<div
onMouseEnter={this.handleMouseHover1}
onMouseLeave={this.handleMouseHover1}
>
Hover Me1
</div>
<div
onMouseEnter={this.handleMouseHover2}
onMouseLeave={this.handleMouseHover2}
>
Hover Me2
</div>
{isHovering1 && <div>hello1</div>}
{isHovering2 && <div>hello2</div>}
</div>
);
}
}
此外,更新的示例:
注意:我还对代码进行了编辑,添加了一些新ECMAScript版本中存在的语法。您可以使用箭头函数格式代替绑定函数,例如fn==>{…}。arrow函数表示此上下文自动绑定到该函数,因此不必手动执行。此外,您不必在构造函数中初始化this.state,您可以将其定义为类实例属性。将这两件事结合在一起,您根本不需要构造函数,而且它使代码更简洁 您需要保持您悬停的项目的状态,这是肯定的 const{Component,useState,useffect}=React; 类示例扩展组件{ 构造器{ 超级作物; this.handlemousehave=this.handlemousehave.bindthis; 此.state={ isHovering:错, 值:['hello','hello2'], 值:“你好” }; } handleMouseHover{target:{dataset:{id}}{ this.setStatestate=>{ 返回{ 状态 Ishoring:!state.Ishoring, value:state.values[id] }; }; } 渲染{ 回来 盘旋我 悬停Me2 {this.state.isHovering&&{this.state.value} ; } } ReactDOM.render , document.getElementById'root' ;
您需要保持您悬停的项目的状态,这是肯定的 const{Component,useState,useffect}=React; 类示例扩展组件{ 构造器{ 超级作物; this.handlemousehave=this.handlemousehave.bindthis; 此.state={ isHovering:错, 值:['hello','hello2'], 值:'你好 ' }; } handleMouseHover{target:{dataset:{id}}{ this.setStatestate=>{ 返回{ 状态 Ishoring:!state.Ishoring, value:state.values[id] }; }; } 渲染{ 回来 盘旋我 悬停Me2 {this.state.isHovering&&{this.state.value} ; } } ReactDOM.render , document.getElementById'root' ;
您可以传递上下文文本,如示例所示。这是工作代码:
import React, { Component } from "react";
import { render } from "react-dom";
// Drive this using some configuration. You can set based on your requirement.
export const HOVER_Hello1 = "Hello1";
export const HOVER_Hello2 = "Hello2";
class HoverExample extends Component {
constructor(props) {
super(props);
this.handleMouseHover = this.handleMouseHover.bind(this);
this.state = {
isHovering: false,
contextText: ""
};
}
handleMouseHover = (e, currentText) => {
this.setState({
isHovering: !this.state.isHovering,
contextText: currentText
});
}
toggleHoverState(state) {
//
}
render() {
return (
<div>
<div
onMouseEnter={e => this.handleMouseHover(e, HOVER_Hello1)}
onMouseLeave={e => this.handleMouseHover(e, HOVER_Hello1)}
>
Hover Me
</div>
<div
onMouseEnter={e => this.handleMouseHover(e, HOVER_Hello2)}
onMouseLeave={e => this.handleMouseHover(e, HOVER_Hello2)}
>
Hover Me2
</div>
{this.state.isHovering && <div>{this.state.contextText}</div>}
</div>
);
}
}
export default HoverExample;
您可以传递上下文文本,如示例所示。这是工作代码:
import React, { Component } from "react";
import { render } from "react-dom";
// Drive this using some configuration. You can set based on your requirement.
export const HOVER_Hello1 = "Hello1";
export const HOVER_Hello2 = "Hello2";
class HoverExample extends Component {
constructor(props) {
super(props);
this.handleMouseHover = this.handleMouseHover.bind(this);
this.state = {
isHovering: false,
contextText: ""
};
}
handleMouseHover = (e, currentText) => {
this.setState({
isHovering: !this.state.isHovering,
contextText: currentText
});
}
toggleHoverState(state) {
//
}
render() {
return (
<div>
<div
onMouseEnter={e => this.handleMouseHover(e, HOVER_Hello1)}
onMouseLeave={e => this.handleMouseHover(e, HOVER_Hello1)}
>
Hover Me
</div>
<div
onMouseEnter={e => this.handleMouseHover(e, HOVER_Hello2)}
onMouseLeave={e => this.handleMouseHover(e, HOVER_Hello2)}
>
Hover Me2
</div>
{this.state.isHovering && <div>{this.state.contextText}</div>}
</div>
);
}
}
export default HoverExample;
如果重点是将消息动态链接到您悬停的JSX元素,那么您可以将该绑定存储在对象中 渲染时,只需在自定义属性data-*中传递一些锚定,例如对应对象的id属性,以便以后可以检索该锚定,查找匹配对象,将链接消息置于状态并渲染消息 以下是一个快速演示: 常数{Component}=React, {render}=ReactDOM, rootNode=document.getElementById'root' 常数数据=[ {id:0,文本:“悬停我”,消息:“谢谢悬停”}, {id:1,文本:“也让我停下来”,消息:“干得好”} ] 类HoverableDivs扩展组件{ 状态={ messageToShow:null } enterHandler={target:{dataset:{id:recordId}}}=>{ const{message}=this.props.data.find{id}=>id==recordId this.setState{messageToShow:message} } leaveHandler=>this.setState{messageToShow:null} 渲染{ 回来 { this.props.data.map{text,id}=> {text} } { this.state.messageToShow&&{this.state.messageToShow} } } } 提供 , 根节点
如果重点是将消息动态链接到您悬停的JSX元素,那么您可以将该绑定存储在对象中 渲染时,只需在自定义属性data-*中传递一些锚定,例如对应对象的id属性,以便以后可以检索该锚定,查找匹配对象,将链接消息置于状态并渲染消息 以下是一个快速演示: 常数{Component}=React, {render}=ReactDOM, rootNode=document.getElementById'root' 常数数据=[ {id:0,文本:“悬停我”,消息:“谢谢悬停”}, {id:1,文本:“也让我停下来”,消息:“干得好”} ] 类HoverableDivs扩展组件{ 状态={ messageToShow:null } enterHandler={target:{dataset:{id:recordId}}}=>{ const{message}=this.props.data.find{id}=>id==recordId this.setState{messageToShow:message} } leaveHandler=>this.setState{messageToShow:null} 渲染{ 回来 { this.props.data.map{text,id}=> {text} } { this.state.messageToShow&&{this.state.messageToShow} } } } 提供 , 根节点
您可以通过仅使用css来实现这一点:您可以通过仅使用css来实现这一点:关于此代码的一个重要注意事项是,组件状态耦合到数据id属性。如果将handleMouseHover添加到缺少该属性的节点,代码将失败。此外,它还将UI数据连接到状态。在我看来,更好的方法是构建一个id->isHovering的映射,然后通过选中此.state.isHoveringMap[id]来确定要在呈现函数中显示的值。关于此代码的一个重要注意事项是组件状态与数据id属性相耦合。如果将handleMouseHover添加到缺少该属性的节点,代码将失败。此外,它还将UI数据连接到状态。在我看来,更好的方法是建立一个id->isHovering的映射,然后通过选中此项来确定要在呈现函数中显示的值。state.isHoveringMap[id]。当开始为变量名编号时,几乎肯定需要一个数据结构,如列表或对象。@Code peedient First,不,您不需要一个数据结构来表示2个标志,这只是一种过度使用。此外,这是按照OP的模式,以显示一个示例。正如我在回答中指出的那样:当然,对于真实世界的代码,您可能希望使用更具描述性的名称,以使代码更易于理解。例如,hover1将替换为hoverLogo,hover2将替换为hoverHelpIcon。但是,当您不知道它代表什么时,很难想出更好的名称。当您开始为变量名编号时,几乎肯定需要一个数据结构,例如列表或对象。@Code Peedient First,不,您不需要一个数据结构来表示两个标志,这只是过火了。此外,这是按照OP的模式,以显示一个示例。正如我在答复中指出的那样:当然 当然,对于真实世界的代码,您可能希望使用更具描述性的名称,以使代码更易于理解。例如,hover1将替换为hoverLogo,hover2将替换为hoverHelpIcon。但当你不知道它代表什么时,很难想出一个更好的名字。