如何在ReactJS中突出显示树中的焦点节点?

时间:2018-07-06 07:46:58

标签: reactjs

假设我们有一个渲染到DOM树的树结构,如下所示:

<ul>
    <li>Outer
        <ul>
            <li>Inner
                <ul>
                    <li>Inner Inner</li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

我们要突出显示“焦点”(鼠标悬停)节点,这里的重点是,当“内部”节点被突出显示时,其父项不应被突出显示。

使用jQuery,您可以访问父节点,解决方案非常简单http://jsfiddle.net/D7jwq/2/

$("li").mouseover(function(e) {
    $(this).addClass("red").parents().removeClass("red");
    e.stopPropagation();
}).mouseout(function(e) {
    $(this).removeClass("red");
});

但是如何在ReactJS中获得类似的效果?

3 个答案:

答案 0 :(得分:0)

您根本不需要javascript,它可以(必须)使用CSS来解决

li:hover {
    background-color: #f00;
}

有关更多详细信息,请参见https://www.w3schools.com/cssref/sel_hover.asp

答案 1 :(得分:0)

React还具有鼠标悬停和鼠标移出事件https://reactjs.org/docs/events.html

jquery $("li")将这些事件隐式设置为所有<li>元素。

在React中,您必须将这些事件显式设置为<li>元素。

答案 2 :(得分:0)

为此,我为每个节点管理了一个“聚焦”状态,并在触发鼠标事件overout时更新了此状态。请注意,当您从父节点移到子节点时,leave不会被触发,您可以观察到控制台输出中这些事件之间的不同。

使用ev.stopPropagation()来确保同一时间只聚焦一个节点

与jQuery方法不同,您无法访问节点的父节点,因此必须管理每个节点的状态。

App.tsx

import * as React from 'react';

class MouseEventTest extends React.Component {
  public render() {

    class Echo extends React.Component<{title}, {focused}> {
      constructor(props) {
        super(props)
        this.state = {focused: false}
        this.echo = this.echo.bind(this)
      }
      public echo(title, evName) {
        return (ev) => {
          ev.preventDefault()
          ev.stopPropagation()
          console.log(title, evName, ev)
          if (['over', 'out'].indexOf(evName) >= 0) {
            this.setState({focused: (['enter', 'over'].indexOf(evName) >= 0)})
          }
        }
      }
      public render() {
        const title = this.props.title
        return (
          <div style={{display: "block", color: (this.state.focused ? "red" : "inherit"), background: '#3bdb7b50'}}
            onClick={this.echo(title, 'click')}
            onMouseEnter={this.echo(title, 'enter')}
            onMouseOver={this.echo(title, 'over')}
            onMouseOut={this.echo(title, 'out')}
            onMouseLeave={this.echo(title, 'leave')}
          >
            {"(" + title + " "}
            {this.props.children}
            {" " + title + ")"}
          </div>
        )
      }
    }

    return (
      <Echo title="Lv1">
        <Echo title="Lv2">
          <Echo title="Lv3">
            abc
          </Echo>
        </Echo>
      </Echo>
    )
  }
}

class App extends React.Component {
  public render() {
    return (
      <div className="App">
        <header className="App-header">
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <MouseEventTest />
      </div>
    );
  }
}

export default App;

要执行上述代码,可以运行create-react-app my-app --scripts-version=react-scripts-ts来初始化目录,并将src/App.tsx替换为以上代码。也许需要以下配置。

tslint.json

{
  "rules": {
    "no-console": false,
    "max-classes-per-file": false,
    "comment-format": false,
    "jsdoc-format": false
  }
}

tsconfig.json

{
  "compilerOptions": {
    "noImplicitAny": false,
    "noUnusedLocals": false,
  }
}