反应组件实现自定义滑动通知

时间:2019-11-15 08:55:05

标签: javascript html css reactjs

我正在编写一个SimpleNotification组件,该组件将在调用show()时滑入视图,并在调用dismiss()时滑出。

目前,我有两个问题。

enter image description here

首先,即使消息溢出,我也希望消息和十字按钮位于同一行。十字按钮应始终位于消息的右侧。十字按钮应该是圆形的,并且其内容应居中。

第二个问题是,当调用show()dismiss()时,我不知道如何添加滑动动画(是过渡动画吗?)。因此,现在我暂时使用布尔visible来控制其可见性,而不是使其滑入和滑出。

如何实现我想要的?预先感谢!

在我当前的尝试中,我是前端和下端的新手。

class SimpleNotification extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            visible: false
        }
        this.style = {
            card: {
                width: "fit-content",
                minWidth: "300px",
                padding: "10px",
                boxShadow: "0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)",
                float: "right",
            },
            cross: {
                display: "inline",
                margin: "10px",
                backgroundColor: "#D3D3D3",
                borderRadius: "50%",
                width: "22px",
                height: "22px",
                textAlign: "center"
            },
            message: {
                display: "inline",
                margin: "10px",
                width: "80%",
                wordWrap: "break-word",
            },
            transition: {
                transition: "all 0.5s linear"
            },
        }
        // Replace existing notification
        this.call_stack = []
    }

    show(message = "", duration = 2000){
        // transition: width 2s, height 4s;
        this.call_stack.push({message: message, duration: duration})
        let count = this.call_stack.length
        this.setState({visible: true, message})
        setTimeout(() => {
            if (this.call_stack.length == count)
                this.dismiss()
            this.call_stack.splice(count - 1, 1)
        }, 10000000)
    }

    dismiss(){
        this.setState({visible: false})
    }

    render() {
      const {visible, message} = this.state
      return visible ? <div id={this.props.id} style={this.style.card}>
          <p style={this.style.message}>{message}</p>
          <p style={this.style.cross} onClick={this.dismiss.bind(this)}>×</p>
      </div> : null
    }
  }

2 个答案:

答案 0 :(得分:0)

可以通过将x放在不同的div中来解决第一个问题

<div className="row">
  <div className="col-11">
     Text here
  </div>
  <div className="col-1">
    X
  </div>
</div>

第二个问题可以使用有条件的应用类来解决。

    .hiden{
transform: translateX(-300px) // width of you notification container
transition: all 0.5s;
}

.open{
transform: translateX(0);
}

有条件地像这样在CSS上方应用

<div className={`hiden ${state.open? 'open': ''}`}>

答案 1 :(得分:-1)

要使消息和关闭图标保持在同一行,可以使用flexbox。

.message-container {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}

.cross {
  display: flex;
  justify-content: center;
  margin: 10px;
  background-color: #d3d3d3;
  border-radius: 50%;
  width: 22px;
  height: 22px;
  text-align: center;
}

.message {
  display: flex;
  flex-grow: 1;
  margin: 10px;
  width: 80%;
  word-wrap: break-word;
}

我已经将邮件包装好并交叉放在一个容器中,以便为它们提供正确的布局。

卡片默认关闭,然后在有任何消息时动态应用card__open类

.card {
  width: fit-content;
  min-width: 300px;
  padding: 10px;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
  position: absolute;
  top: -50px;
  transition: top 0.5s;
}

.card__open {
  top: 20px;
}

Classnames库非常适合动态定义应应用的类

const classes = classNames({
    card: true,
    card__open: messages.length
  });


return (
    <div className={classes}>
    ...

我已经创建了一个有关如何应用动画的小例子。

CodeSandbox Example