React中的内联CSS样式:如何实现:hover?
我非常喜欢React中的内联CSS模式,并决定使用它。
但是,您不能使用:hover
和类似的select器。 那么,在使用内联CSS样式时,实现高亮hover的最佳方式是什么?
#reactjs的一个build议是有一个可Clickable
组件,并像这样使用它:
<Clickable> <Link /> </Clickable>
Clickable
有一个hovered
状态,并把它作为道具传递给Link。 然而, Clickable
(我实现它的方式)将Link
包装在一个div
以便它可以设置onMouseEnter
和onMouseLeave
。 这使得事情有点复杂,但是(例如span
包裹在一个div
行为与span
不同)。
有一个更简单的方法吗?
我处于同样的情况 真的很喜欢保持组件风格的模式,但hover状态似乎是最后一个障碍。
我所做的是写一个混合,你可以添加到你需要hover状态的组件。 这个mixin将会为你的组件添加一个新的hovered
属性。 如果用户将鼠标hover在组件的主要DOM节点上,则将其设置为true
如果用户离开该元素,则将其设置为false
。
现在在你的组件渲染function,你可以做这样的事情:
<button style={m( this.styles.container, this.state.hovered && this.styles.hover, )}>{this.props.children}</button>
现在,每当hovered
状态的状态发生变化时,组件将重新渲染。
我也为此创build了一个沙盒回购,我自己用来testing这些模式。 如果你想看到我的实现的例子,请检查它。
https://github.com/Sitebase/cssinjs/tree/feature-interaction-mixin
我认为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> ) }
然后,您可以使用hover状态(true / false)来更改链接的样式。
您可以使用Radium – 它是一个使用ReactJS的内联样式的开源工具。 它增加了你需要的select器。 非常受欢迎,请查看 – npm上的Radium
完整的CSS支持正是这个CSSinJS库的巨大数量的原因,要做到这一点,你需要生成实际的CSS,而不是内联样式。 内联样式在更大的系统中反应也要慢得多。 免责声明 – 我维护JSS 。
由于这个原因(其他人不同意实现其他库/语法和内联样式不支持前缀属性值)。 相信我们应该能够简单地使用JavaScript编写CSS,并且拥有完全独立的组件HTML-CSS-JS。 使用ES5 / ES6模板string,我们现在可以,也可以是相当的! 🙂
npm install style-it --save
function语法 ( 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;
您可以使用css模块作为替代,另外还可以使用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模块的例子
Checkout Typestyle如果您正在使用React with Typescript。
下面是一个示例代码:hover
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>
我在最近的一个应用程序中为我的目的使用了一个很好的hack-ish解决scheme,我发现它比在vanilla js中编写自定义的hover设置函数要快(尽pipe我认识到,在大多数环境中可能不是最佳实践..)所以,如果你仍然感兴趣,在这里。
我创build一个父元素只是为了保持内联的JavaScript样式,然后是一个具有className或id的子元素,我的css样式表将锁住并将hover样式写入我的专用css文件中。 这是因为更细粒度的子元素通过inheritance接收内联js样式,但hover样式被css文件覆盖。
所以基本上,我的实际CSS文件存在的唯一目的是保持hover效果,没有别的。 这使得它非常简洁和易于pipe理,并且使我能够在我的内联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="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>
最简单的方法就是在你的链接中添加段落标签,并将样式parsing为p。 <Link to='/'><p style={{ color: '#000000' }}>Some text</p></Link>
再加上乔纳森的回答 ,下面是覆盖焦点和活动状态的事件,以及使用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> ) }
关于风格元件和反应路由器v4,你可以这样做:
import {NavLink} from 'react-router-dom' const Link = styled(NavLink)` background: blue; &:hover { color: white; } ` ... <Clickable><Link to="/somewhere">somewhere</Link></Clickable>