Подтвердить что ты не робот

Как вы наведете ReactJS? - onMouseLeave не регистрируется во время быстрого наведения

Как вы можете достичь либо события зависания, либо активного события в ReactJS, когда вы встраиваете стиль?

Я обнаружил, что метод onMouseEnter, onMouseLeave не работает, поэтому надеется, что есть другой способ сделать это.

В частности, если вы быстро наведите указатель мыши на компонент, регистрируется только событие onMouseEnter. OnMouseLeave никогда не срабатывает и, следовательно, не может обновить состояние... оставив компонент таким, как будто он все еще завис. Я заметил то же самое, если вы попытаетесь воспроизвести псевдо-класс ": active" css. Если вы нажмете очень быстро, зарегистрируется только событие onMouseDown. Событие onMouseUp будет проигнорировано... оставив компонент активным.

Вот JSFiddle, показывающий проблему: https://jsfiddle.net/y9swecyu/5/

Видео JSFiddle с проблемой: https://vid.me/ZJEO

Код:

var Hover = React.createClass({
    getInitialState: function() {
        return {
            hover: false
        };
    },
    onMouseEnterHandler: function() {
        this.setState({
            hover: true
        });
        console.log('enter');
    },
    onMouseLeaveHandler: function() {
        this.setState({
            hover: false
        });
        console.log('leave');
    },
    render: function() {
        var inner = normal;
        if(this.state.hover) {
            inner = hover;
        }

        return (
            <div style={outer}>
                <div style={inner}
                    onMouseEnter={this.onMouseEnterHandler}
                    onMouseLeave={this.onMouseLeaveHandler} >
                    {this.props.children}
                </div>
            </div>
        );
    }
});

var outer = {
    height: '120px',
    width: '200px',
    margin: '100px',
    backgroundColor: 'green',
    cursor: 'pointer',
    position: 'relative'
}

var normal = {
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    backgroundColor: 'red',
    opacity: 0
}

var hover = {
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    backgroundColor: 'red',
    opacity: 1
}

React.render(
    <Hover></Hover>,         
    document.getElementById('container')
)
4b9b3361

Ответ 1

Вы пробовали что-нибудь из этого?

onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp

SyntheticEvent

также упоминается следующее:

React нормализует события, чтобы они имели согласованные свойства в разных браузерах.

Приведенные ниже обработчики событий запускаются событием в фазе пузырьков. Чтобы зарегистрировать обработчик события для фазы захвата, добавьте Capture к имени события; например, вместо использования onClick вы должны использовать onClickCapture для обработки события click на этапе захвата.

Ответ 2

Предыдущие ответы довольно сбивают с толку. Вы не нуждаетесь в состоянии реакции, чтобы решить эту проблему, и никакой специальной внешней lib. Это может быть достигнуто с помощью чистого css/sass:

Стиль:

.hover {
  position: relative;

  &:hover &__no-hover {
    opacity: 0;
  }

  &:hover &__hover {
    opacity: 1;
  }

  &__hover {
    position: absolute;
    top: 0;
    opacity: 0;
  }

  &__no-hover {
    opacity: 1;
  }
}

Реактивный компонент

Простая функция Hover Pure-Rendering-Function:

const Hover = ({ onHover, children }) => (
    <div className="hover">
        <div className="hover__no-hover">{children}</div>
        <div className="hover__hover">{onHover}</div>
    </div>
)

Использование

Затем используйте его следующим образом:

    <Hover onHover={<div> Show this on hover </div>}>
        <div> Show on no hover </div>
    </Hover>

Ответ 3

Если вы можете создать небольшую демонстрацию, показывающую ошибку onMouseEnter/onMouseLeave или onMouseDown/onMouseUp, было бы целесообразно опубликовать ее на странице проблем ReactJS или в списке рассылки, просто чтобы задать вопрос и узнать, что разработчики должны сказать о он.

В вашем случае использования вы, похоже, подразумеваете, что CSS: hover и: active state будут достаточно для ваших целей, поэтому я предлагаю вам использовать их. CSS на порядок быстрее и надежнее, чем Javascript, потому что он непосредственно реализован в браузере.

Однако: hover и: активные состояния не могут быть указаны в встроенных стилях. Вы можете назначить идентификатор или имя класса для своих элементов и написать свои стили либо в таблице стилей, если они несколько постоянные в вашем приложении, либо в динамически сгенерированном теге <style>.

Вот пример последнего метода: https://jsfiddle.net/ors1vos9/

Ответ 4

вы можете использовать onMouseOver={this.onToggleOpen} и onMouseOut={this.onToggleOpen} для onMouseOut={this.onToggleOpen} над компонентом

Ответ 5

Я только что столкнулся с этой проблемой при прослушивании событий onMouseLeave на отключенной кнопке. Я работал вокруг него, слушая родное событие mouseleave на элементе, который обертывает отключенную кнопку.

componentDidMount() {
    this.watchForNativeMouseLeave();
},
componentDidUpdate() {
    this.watchForNativeMouseLeave();
},
// onMouseLeave doesn't work well on disabled elements
// https://github.com/facebook/react/issues/4251
watchForNativeMouseLeave() {
    this.refs.hoverElement.addEventListener('mouseleave', () => {
        if (this.props.disabled) {
            this.handleMouseOut();
        }
    });
},
render() {
    return (
        <span ref='hoverElement'
            onMouseEnter={this.handleMouseEnter}
            onMouseLeave={this.handleMouseLeave}
        >
            <button disabled={this.props.disabled}>Submit</button>
        </span>
    );
}

Здесь сценарий https://jsfiddle.net/qfLzkz5x/8/

Ответ 6

Примечание. Этот ответ был для предыдущей версии этого вопроса, где задающий вопрос пытался использовать JavaScript для применения стилей CSS... что можно просто сделать с помощью CSS.

Простое решение css -only.

Для применения базовых стилей CSS проще и эффективнее, чем решения JS в 99% случаев. (Хотя более современные решения CSS-in-JS - например, React Components и т.д. - возможно, более удобны в обслуживании.)

Запустите этот фрагмент кода, чтобы увидеть его в действии…

.hover-button .hover-button--on,
.hover-button:hover .hover-button--off {
  display: none;
}

.hover-button:hover .hover-button--on {
  display: inline;
}
<button class='hover-button'>
  <span class='hover-button--off'>Default</span>
  <span class='hover-button--on'>Hover!</span>
</button>

Ответ 7

Пакет под названием styled-components может решить эту проблему ELEGANT.

Ссылка

  1. Глен Маддерн - Styling React Apps со стилизованными компонентами

Пример

const styled = styled.default
const Square = styled.div'
  height: 120px;
  width: 200px;
  margin: 100px;
  background-color: green;
  cursor: pointer;
  position: relative;
  &:hover {
    background-color: red;
  };
'
class Application extends React.Component {
  render() {
    return (
      <Square>
      </Square>
    )
  }
}

/*
 * Render the above component into the div#app
 */
ReactDOM.render(<Application />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>
<script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>
<div id='app'></div>

Ответ 8

Вы не можете использовать встроенный стиль. Не рекомендуется переопределять функции CSS в JavaScript. У нас уже есть язык, который чрезвычайно мощный и невероятно быстрый для этого варианта использования - CSS. Так что используйте его! Сделано Стиль It, чтобы помочь.

npm install style-it --save

Функциональный синтаксис (JSFIDDLE)

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return Style.it(`
      .intro:hover {
        color: red;
      }

    `,
      <p className="intro">CSS-in-JS made simple -- just Style It.</p>
    );
  }
}

export default Intro;

Синтаксис JSX (JSFIDDLE)

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return (
      <Style>
      {`
        .intro:hover {
          color: red;
        }
      `}

      <p className="intro">CSS-in-JS made simple -- just Style It.</p>
    </Style>
  }
}

export default Intro;

Ответ 9

Используйте Radium!

Ниже приведен пример с их сайта:

var Radium = require('radium');
var React = require('react');
var color = require('color');

@Radium
class Button extends React.Component {
  static propTypes = {
    kind: React.PropTypes.oneOf(['primary', 'warning']).isRequired
  };

  render() {
    // Radium extends the style attribute to accept an array. It will merge
    // the styles in order. We use this feature here to apply the primary
    // or warning styles depending on the value of the `kind` prop. Since its
    // all just JavaScript, you can use whatever logic you want to decide which
    // styles are applied (props, state, context, etc).
    return (
      <button
        style={[
          styles.base,
          styles[this.props.kind]
        ]}>
        {this.props.children}
      </button>
    );
  }
}

// You can create your style objects dynamically or share them for
// every instance of the component.
var styles = {
  base: {
    color: '#fff',

    // Adding interactive state couldn't be easier! Add a special key to your
    // style object (:hover, :focus, :active, or @media) with the additional rules.
    ':hover': {
      background: color('#0074d9').lighten(0.2).hexString()
    }
  },

  primary: {
    background: '#0074D9'
  },

  warning: {
    background: '#FF4136'
  }
};

Ответ 10

У меня была аналогичная проблема при вызове onMouseEnter, но иногда соответствующее событие onMouseLeave не запускалось, вот обходной путь, который хорошо работает для меня (он частично зависит от jQuery):

var Hover = React.createClass({
    getInitialState: function() {
        return {
            hover: false
        };
    },
    onMouseEnterHandler: function(e) {
        this.setState({
            hover: true
        });
        console.log('enter');

        $(e.currentTarget).one("mouseleave", function (e) {
            this.onMouseLeaveHandler();
        }.bind(this));

    },
    onMouseLeaveHandler: function() {
        this.setState({
            hover: false
        });
        console.log('leave');
    },
    render: function() {
        var inner = normal;
        if(this.state.hover) {
            inner = hover;
        }

        return (
            <div style={outer}>
                <div style={inner}
                    onMouseEnter={this.onMouseEnterHandler} >
                    {this.props.children}
                </div>
            </div>
        );
    }
});

Смотрите на jsfiddle: http://jsfiddle.net/qtbr5cg6/1/


Почему это произошло (в моем случае): при нажатии на элемент я запускаю анимацию прокрутки jQuery (через $('#item').animate({ scrollTop: 0 })). Поэтому курсор не оставляет элемент "естественно", но во время анимации, управляемой JavaScript... и в этом случае onMouseLeave не был правильно запущен React (React 15.3.0, Chrome 51, Desktop)

Ответ 11

Я знаю. Прошло некоторое время с тех пор, как был задан этот вопрос, но я просто столкнулся с той же проблемой несогласованности с onMouseLeave() То, что я сделал, это использовать onMouseOut() для выпадающего списка и оставить мышь для всего меню, он надежный и работает каждый раз, когда я его тестировал. Я видел события здесь в документах: https://facebook.github.io/react/docs/events.html#mouse-events вот пример, используя https://www.w3schools.com/bootstrap/bootstrap_dropdowns.asp:

handleHoverOff(event){
  //do what ever, for example I use it to collapse the dropdown
  let collapsing = true;
  this.setState({dropDownCollapsed : collapsing });
}

render{
  return(
    <div class="dropdown" onMouseLeave={this.handleHoverOff.bind(this)}>
      <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Dropdown Example
      <span class="caret"></span></button>
      <ul class="dropdown-menu" onMouseOut={this.handleHoverOff.bind(this)}>
        <li><a href="#">bla bla 1</a></li>
        <li><a href="#">bla bla 2</a></li>
        <li><a href="#">bla bla 3</a></li>
      </ul>
    </div>
  )
}

Ответ 12

Я лично использую Style It для встроенного стиля в React или сохраняю свой стиль отдельно в файле CSS или SASS...

Но если вам действительно интересно сделать это inline, посмотрите на библиотеку, я разделяю некоторые из следующих ниже способов:

В компоненте:

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    return (
      <Style>
        {`
          .intro {
            font-size: 40px;
          }
        `}

        <p className="intro">CSS-in-JS made simple -- just Style It.</p>
      </Style>
    );
  }
}

export default Intro;

Выход:

    <p class="intro _scoped-1">
      <style type="text/css">
        ._scoped-1.intro {
          font-size: 40px;
        }
      </style>

      CSS-in-JS made simple -- just Style It.
    </p>


   Также вы можете использовать переменные JavaScript с зависанием в вашем CSS, как показано ниже:

import React from 'react';
import Style from 'style-it';

class Intro extends React.Component {
  render() {
    const fontSize = 13;

    return Style.it(`
      .intro {
        font-size: ${ fontSize }px;  // ES2015 & ES6 Template Literal string interpolation
      }
      .package {
        color: blue;
      }
      .package:hover {
        color: aqua;
      }
    `,
      <p className="intro">CSS-in-JS made simple -- just Style It.</p>
    );
  }
}

export default Intro;

И результат, как показано ниже:

<p class="intro _scoped-1">
  <style type="text/css">
    ._scoped-1.intro {
      font-size: 13px;
    }
    ._scoped-1 .package {
      color: blue;
    }
    ._scoped-1 .package:hover {
      color: aqua;
    }
  </style>

  CSS-in-JS made simple -- just Style It.
</p>

Ответ 13

Я мог бы предложить вам пример, который мне было легко понять, я использую эмоции в React JS для придания стилей. Здесь вы можете найти более подробную информацию об этом https://emotion.sh/docs/introduction, надеюсь, это поможет вам.

const secondStyle = css'
  background: blue;
  height: 20px;
  width: 20px;
  :hover {
    cursor: pointer;
    background: red;
'

function myComponent() {
  return (
     <div className={firstStyle}>
       <button className={secondStyle}>Submit<button>
  )
}