2015-02-06 146 views
84

我很喜欢inline CSS pattern in React,并决定使用它。React中的内联CSS样式:如何实现:悬停?

但是,您不能使用:hover和类似的选择器。那么,在使用内联CSS样式时,实现高亮悬停的最佳方式是什么?从#reactjs

一个建议是具有Clickable组件,并使用这样的:

<Clickable> 
    <Link /> 
</Clickable> 

Clickable具有hovered状态,并将其作为道具到链路。然而,Clickable(我实现它的方式)将Link包含在div中,以便它可以将onMouseEnteronMouseLeave设置为它。尽管(例如span包装在div中的行为不同于span),但这会使事情变得有点复杂。

有没有更简单的方法?

+0

你是绝对正确的 - 模拟的唯一途径:悬停等选择与内联样式是使用'onMouseEnter'和'onMouseL eave'。关于具体实施 - 完全取决于你。看看你的具体例子,为什么不把''包装器做成'span'? – 2015-02-06 14:20:18

+2

我会建议使用外部样式表与ExtractText的WebPack插件一起,这将帮助你在更长的运行如果你想ServerRender否则,你可以尝试镭https://github.com/FormidableLabs/radium – abhirathore2006 2016-08-17 14:05:48

+0

目前[样式的组件( https://github.com/styled-components/styled-components)是模拟css/scss在反应中的所有可能性的最佳解决方案。 – 2017-09-25 09:51:11

回答

23

我处于相同的情况。真的很喜欢保持组件样式的模式,但悬停状态似乎是最后一道关卡。

我所做的是编写一个mixin,您可以添加到需要悬停状态的组件。 该mixin将为您的组件添加一个新的hovered属性。如果用户将鼠标悬停在组件的主要DOM节点上,并将其设置回false(如果用户离开该元素),它将被设置为true

现在在组件渲染功能,你可以这样做:

<button style={m(
     this.styles.container, 
     this.state.hovered && this.styles.hover, 
    )}>{this.props.children}</button> 

现在每次hovered状态的状态改变组件将重新呈现。

我也为此创建了一个沙盒回购,我用它来自己测试这些模式中的一些。如果您想查看我的实施示例,请查看它。

https://github.com/Sitebase/cssinjs/tree/feature-interaction-mixin

+2

不是长远来看一个很好的解决方案,镭将是更好的选择,或者使用外部样式表 – abhirathore2006 2016-08-17 14:07:30

+6

@ abhirathore2006镭的工作方式相同,问题是具体怎么做,而无需使用外部的样式表 – 2016-08-27 21:48:37

20

您可以使用镭 - 它是内嵌样式ReactJS的开源工具。它增加了您需要的选择器。很受欢迎,看看 - Radium on npm

+0

我只是碰到这个帖子,怎么来的你会在以下情况下实施Radium吗? 'module.exports = React.createClass({显示名: '应用',})' – Mintberry 2015-11-09 23:12:26

+1

@Rkhayat您可以把它包装为'module.exports =镭(React.createClass({显示名: '应用',})) '或类分配给一个值,并添加它上面的'@ Radium'装饰作为文档提到https://github.com/FormidableLabs/radium#usage – pbojinov 2016-02-23 05:46:06

+0

这里还有这个所谓的CSS伟大的事情;) – Pixelomo 2018-02-07 02:22:22

55

我认为onMouseEnter和onMouseLeave是要走的路,但我看不到需要额外的包装组件。下面是我如何实现它:

var Link = React.createClass({ 
    getInitialState: function(){ 
    return {hover: false} 
    }, 
    toggleHover: function(){ 
    this.setState({hover: !this.state.hover}) 
    }, 
    render: function() { 
    var linkStyle; 
    if (this.state.hover) { 
     linkStyle = {backgroundColor: 'red'} 
    } else { 
     linkStyle = {backgroundColor: 'blue'} 
    } 
    return(
     <div> 
     <a style={linkStyle} onMouseEnter={this.toggleHover} onMouseLeave={this.toggleHover}>Link</a> 
     </div> 
    ) 
    } 

然后,您可以使用悬停状态(true/false)来更改链接的样式。

+1

这似乎覆盖':悬停'但不是':焦点' – 2016-04-12 12:33:52

+3

@AdamTuttle反应有一个'onFocus'事件;所以你可以做'同样的事情:focus'为':hover',除了没有需要'onMouseEnter'和'onMouseLeave'你只需要'onFocus' – Jonathan 2016-04-12 17:35:56

+1

要知道,这种方法迫使主线程,而典型的执行CSS事件被更有效地处理。 – 2017-12-20 15:27:42

3

您可以使用css modules作为替代,另外使用react-css-modules来进行类名映射。

这样,你可以导入你的样式如下,使用普通的CSS局部范围将组件:

import React from 'react'; 
import CSSModules from 'react-css-modules'; 
import styles from './table.css'; 

class Table extends React.Component { 
    render() { 
     return <div styleName='table'> 
      <div styleName='row'> 
       <div styleName='cell'>A0</div> 
       <div styleName='cell'>B0</div> 
      </div> 
     </div>; 
    } 
} 

export default CSSModules(Table, styles); 

这里是一个webpack css modules example

+0

供参考:如果你使用流星检查这个包:https://github.com/nathantreid/meteor-css-modules。迄今为止,我自己使用它取得了巨大的成功。 – Spiralis 2016-06-21 09:40:20

+0

这是反应元件风格的好方法,但并不能完全控制内联样式。例如,你不能在运行时像使用Radium或其他基于onMouseOver的解决方案那样更改':hover'样式 – 2016-08-27 22:02:37

4

制造Style It - 部分 - 因为这个原因(其他人对实现其他库/语法和内联样式不支持前缀属性值的意见不一致)。相信我们应该能够简单地用JavaScript编写CSS,并且拥有完全独立的组件HTML-CSS-JS。使用ES5/ES6模板字符串,我们现在可以并且它可以非常棒! :)

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; 
2

结帐Typestyle如果您使用的是带有打字稿反应。

下面是一个示例代码:悬停

import {style} from "typestyle"; 

/** convert a style object to a CSS class name */ 
const niceColors = style({ 
    transition: 'color .2s', 
    color: 'blue', 
    $nest: { 
    '&:hover': { 
     color: 'red' 
    } 
    } 
}); 

<h1 className={niceColors}>Hello world</h1> 
0

我用这个漂亮的劈十岁上下的解决方案,我最近是我的目的,适用的应用程序之一,我觉得比编写自定义悬停更快设置功能在香草js(虽然,我承认,也许不是在大多数环境中的最佳做法..)所以,如果你仍然感兴趣,这里。

我创建了一个父元素只是为了保持内联JavaScript样式,然后是一个带有className或id的子元素,我的css样式表会锁定并将悬停样式写入我的专用css文件中。这是可行的,因为更细粒度的子元素通过继承接收内联js样式,但悬停样式被css文件覆盖。

所以基本上,我的实际CSS文件存在的唯一目的是保持悬停效果,没有别的。这使得它非常简洁和易于管理,并且使我能够在我的内联React组件样式中完成繁重工作。

下面是一个例子:

const styles = { 
 
    container: { 
 
    height: '3em', 
 
    backgroundColor: 'white', 
 
    display: 'flex', 
 
    flexDirection: 'row', 
 
    alignItems: 'stretch', 
 
    justifyContent: 'flex-start', 
 
    borderBottom: '1px solid gainsboro', 
 
    }, 
 
    parent: { 
 
    display: 'flex', 
 
    flex: 1, 
 
    flexDirection: 'row', 
 
    alignItems: 'stretch', 
 
    justifyContent: 'flex-start', 
 
    color: 'darkgrey', 
 
    }, 
 
    child: { 
 
    width: '6em', 
 
    textAlign: 'center', 
 
    verticalAlign: 'middle', 
 
    lineHeight: '3em', 
 
    }, 
 
}; 
 

 
var NavBar = (props) => { 
 
    const menuOptions = ['home', 'blog', 'projects', 'about']; 
 

 
    return (
 
    <div style={styles.container}> 
 
     <div style={styles.parent}> 
 
     {menuOptions.map((page) => <div className={'navBarOption'} style={styles.child} key={page}>{page}</div>)} 
 
     </div> 
 
    </div> 
 
); 
 
}; 
 

 

 
ReactDOM.render(
 
    <NavBar/>, 
 
    document.getElementById('app') 
 
);
.navBarOption:hover { 
 
    color: black; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 

 
<div id="app"></div>

注意, “孩子” 内嵌样式没有一个 “色” 属性设置。如果是这样,这将不起作用,因为内联样式优先于我的样式表。

6

完全的CSS支持正是这个CSSinJS库的巨大数量的原因,为了有效地完成这项工作,您需要生成实际的CSS,而不是内联样式。在更大的系统中,内联样式的反应也要慢得多。免责声明 - 我保留JSS

0

最简单的方法就是在你的链接中添加段落标签并将样式解析为p。 <Link to='/'><p style={{ color: '#000000' }}>Some text</p></Link>

1

添加到Jonathan's answer,这里有覆盖的重点和活动状态的事件,并使用onMouseOver代替onMouseEnter因为后者不会泡沫,如果你有一个目标内的任何子元素正在应用的事件至。

var Link = React.createClass({ 

    getInitialState: function(){ 
    return {hover: false, active: false, focus: false} 
    }, 

    toggleHover: function(){ 
    this.setState({hover: !this.state.hover}) 
    }, 

    toggleActive: function(){ 
    this.setState({active: !this.state.active}) 
    }, 

    toggleFocus: function(){ 
    this.setState({focus: !this.state.focus}) 
    }, 

    render: function() { 
    var linkStyle; 
    if (this.state.hover) { 
     linkStyle = {backgroundColor: 'red'} 
    } else if (this.state.active) { 
     linkStyle = {backgroundColor: 'blue'} 
    } else if (this.state.focus) { 
     linkStyle = {backgroundColor: 'purple'} 
    } 

    return(
     <div> 
     <a style={linkStyle} 
      onMouseOver={this.toggleHover} 
      onMouseOut={this.toggleHover} 
      onMouseUp={this.toggleActive} 
      onMouseDown={this.toggleActive} 
      onFocus={this.toggleFocus}> 
      Link 
     </a> 
     </div> 
    ) 
    } 
0

在问候styled-componentsreact-router v4你可以这样做:

import {NavLink} from 'react-router-dom' 

const Link = styled(NavLink)`  
    background: blue; 

    &:hover { 
    color: white; 
    } 
` 

... 
<Clickable><Link to="/somewhere">somewhere</Link></Clickable> 
0

这对于具有内嵌样式反应组件内一个漂亮的黑客(并且还使用:悬停CSS功能):

... <style> {`.galleryThumbnail.selected:hover{outline:2px solid #00c6af}`} </style> ...