使用react写悬浮气泡和组件的hover事件
1、效果
气泡随着按钮来变化展示,根据继承react.component,使用OnMouseOver和OnMouseOut事件方法来实现hover的效果
2、气泡组件 overlap.js:
import React from "react"
import jdyStyles from "./container.module.css"
// OverLap 组件
class OverLap extends React.Component {
render() {
const {children,topDistance} = this.props
return (
<div className={jdyStyles.air_bubble} style={{top:topDistance+'px'}}>
{children}
</div>
)
}
}
export default OverLap;
// 当前组件需要设置一个 top来确定气泡相对于悬浮按钮的位置
3、悬浮按钮组件 float-icon-text-button.js:
//react中重新渲染组件布局,是可以根据 this.setState 方法触发render的
import React from "react"
import jdyStyles from "./container.module.css"
import OverlapComponent from "../components/overlap"
// TAB button 组件
class FloatButton extends React.Component {
constructor(props){
super(props);
this.onMouseOver = this.onMouseOver.bind(this);
this.onMouseOut = this.onMouseOut.bind(this);
// 设置默认的over状态
this.state = {
isMouseOn: false
};
}
// 监听hover on
onMouseOver =()=>{
this.setState({ isMouseOn: true });
}
// 监听hover out
onMouseOut =()=>{
this.setState({ isMouseOn: false });
}
render() {
const {isTop,icon,onClick,children,leftWindowContent,leftWindowTopDistance} = this.props;
let leftWindow = null;
// 获取mouse over状态
const { isMouseOn } = this.state;
if(leftWindowContent && isMouseOn){
leftWindow = <OverlapComponent topDistance={leftWindowTopDistance}>
{leftWindowContent}
</OverlapComponent> ;
}
return (
<div className={jdyStyles.side_float_btn} onClick={onClick} onKeyDown={onClick} role="button" tabIndex="0" onFocus={()=>0} onBlur={()=>0} onMouseOver={this.onMouseOver} onMouseOut={this.onMouseOut} >
<img style={{ margin: (isTop?'12px 0 6px':'8px 0 6px') }} src={icon} alt="suspend-top.png"></img>
{ children }
{leftWindow}
</div>
)
}
}
export default FloatButton;
4、悬浮模块组件 layout-sidebar.js:
import React from "react"
import { css } from "@emotion/core"
import FloatButton from "../components/float-icon-text-button"
// 回到顶部图标
var imageSuspendTop = require("../images/suspend-top.png");
// 客服图标
var imageSuspendPhone = require("../images/suspend-phone.png");
// 公众号图标
var imageSuspendWx = require("../images/suspend-wx.png");
// 申请使用
var imageSuspendUse = require("../images/suspend-use.png");
// 弹框 客服图标
var imageSuspendService = require("../images/suspend-service.png");
// 弹框 二维码图标
var imageSuspendCode = require("../images/suspend-code.png");
// 定义sidebar组件
class SideBar extends React.Component {
constructor(props){
super(props);
this.click2Top = this.click2Top.bind(this);
this.click2PhoneService = this.click2PhoneService.bind(this);
this.click2WechatAccount = this.click2WechatAccount.bind(this);
this.click2ApplyUsing = this.click2ApplyUsing.bind(this);
}
// 滚到页面顶部
click2Top =()=>{
document.body.scrollIntoView(true);//为ture返回顶部,false为底部
}
// 点击客服
click2PhoneService =()=>{
console.log('111111111111111111 点击客服');
}
// 微信公众号
click2WechatAccount =()=>{
console.log('111111111111111111 点击微信公众号');
}
// 申请使用
click2ApplyUsing =()=>{
console.log('111111111111111111 点击申请使用');
}
render() {
return (
<div css={css`position: fixed;top: 500px;z-index: 10000;right: 68px;`}>
{/* 顶部 */}
<FloatButton isTop={true} icon={imageSuspendTop} onClick={()=>this.click2Top()}>顶部</FloatButton>
{/* 客服 */}
<FloatButton icon={imageSuspendPhone} onClick={this.click2PhoneService} leftWindowContent={<div css={css`display: flex;align-items: center;flex-direction: column;`}>
<div css={css`display: flex;flex-direction: row;`}>
<img css={css`margin:0 auto;`} src={imageSuspendService} alt="客服电话"></img>
<div css={css`margin-left:6px;color: #333;font-size: 16px;`}>客服电话</div>
</div>
<div css={css`margin-left:6px;color: #0084ff;font-size: 22px;`}>400-777-585</div>
</div>} leftWindowTopDistance={84}>客服</FloatButton>
{/* 公众号 */}
<FloatButton icon={imageSuspendWx} onClick={this.click2WechatAccount} leftWindowContent={<div css={css`display: flex;align-items: center;flex-direction: column;`}>
<div css={css`display: flex;flex-direction: column;`}>
<img css={css`margin:0 auto;`} src={imageSuspendCode} alt="客服电话"></img>
<div css={css`margin-top:8px;color: #333;font-size: 14px;`}>金斗云智能管理平台订阅号</div>
</div>
<div css={css`display: flex;flex-direction: column;margin-top:24px;`}>
<img css={css`margin:0 auto;`} src={imageSuspendCode} alt="客服电话"></img>
<div css={css`margin-top:8px;color: #333;font-size: 14px;`}>金斗云智能管理平台服务号</div>
</div>
</div>} leftWindowTopDistance={0}>公众号</FloatButton>
{/* 申请使用 */}
<FloatButton icon={imageSuspendUse} onClick={this.click2ApplyUsing} >申请使用</FloatButton>
</div>
)
}
}
export default SideBar;
5、css样式 container.module.css:
.air_bubble {
float:right;
width: 180px;
position: absolute;
right: 85px;
background-color: #fff;
border-bottom-color: #fff;
/*为了给after伪元素自动继承*/
color: #333333;
font-size: 16px;
padding: 5px;
box-sizing: border-box;
word-break: break-all;
box-shadow: 0px 2px 2px 2px #eee;
}
/*此处css为向上带阴影的三角,用于气泡箭头*/
.air_bubble::before {
content: '';
position: absolute;
width: 0;
height: 0;
top: 50%;
right: -4px;
border-style: solid;
border-width: 6px;
border-color: transparent transparent #fff #fff;
transform: rotate(225deg);
-webkit-box-shadow: -2px 2px 3px 0 #eee;
-moz-box-shadow: -2px 2px 3px 0 #eee;
box-shadow: -2px 2px 3px 0 #eee;
}
.side_float_btn {
height: 60px;
width: 60px;
border-radius: 10px;
background: rgba(0, 132, 255, .8);
margin-bottom: 24px;
display: flex;
outline: none;
flex-direction: column;
align-items: center;
font-size: 14px;
color: #fff;
}
// 这里的hover用css 只是为了悬浮按钮的hover效果
.side_float_btn:hover {
background: #0084ff;
}