NauGaika
@NauGaika
At heart I'm a programmer .

Как доработать плавающие окна React, Redux?

попытался создать таскающиеся окна информация о которых находится в сторе.
Получилось что-то ядерное. Хотел бы попросить помочь в доработке. Оно как-то все работает, но выглядит страшно. Пришлось руками лезть в DOM, чтобы навешивать события через addEventListener, Ставить заглушки, которые препятствовали перетаскиванию в виде window.getSelection().removeAllRanges(). Может есть другой подход в навешивании вложенных событий?

.window
{
    position: absolute;
    box-shadow: 0 0 10px rgba(0,0,0,0.5);
    border-radius: 0.5em 0.5em 0.5em 0.5em;
    min-width: 150px;
    min-height: 100px;
}
.windows
{
    position: absolute;
    left: 0;
    bottom:0;
    right: 0;
    top:0;
    background: grey;
}
.windowTitle
{
    background-color: #456598;
    border-radius: 0.5em 0.5em 0 0;
    height: 2em;
    cursor: move;
    user-select: none;
    width:100%
    
}
.windowContent
{
    position: absolute;
    background: #e9ebee;
    top: 2em;
    bottom:0;
    right:0;
    left:0;
    border-radius: 0 0 0.5em 0.5em;
}
.windowTitle span
{
    margin-left: 1em;
    line-height: 2em;
    color: white;
    vertical-align: middle;
}
.closeButton
{
    background: url('./img/close.png');
    width: 14px;
    height: 14px;
    border: 0;
    float:right;
    margin: 0.5em 0.5em 0 0;
    cursor: pointer;
}
.windowResize
{
    position: absolute;
    right: 2px;
    bottom:2px;
    width:12px;
    height:12px;
    cursor: se-resize;
    background: url('./img/resize.png');
}

import React, {Component} from 'react';

export class UserWindow extends Component {
  startX;
  startY;
  minWidth = 150;
  minHeight = 100;
  sendNewState = () => {
    let parentElement = this.refs.body.style;
    this.props.parent.props.changeWindowPosition(
      this.props.el, 
      parseInt(parentElement.width), 
      parseInt(parentElement.height), 
      parseInt(parentElement.top), 
      parseInt(parentElement.left),
      parseInt(parentElement.zIndex)
      );
  }
  closeWindow = (e) => {
    e.preventDefault();
    this.props.parent.props.closeWindow(this.props.el);
  } 

  resizeStop = () => {
    let elem = this.refs.body.parentNode;
    elem.removeEventListener('mousemove', this.changeWindowSize);
    setTimeout(()=>{window.getSelection().removeAllRanges();}, 30);
    this.refs.content.style.userSelect = 'auto';
    this.refs.body.parentNode.removeEventListener('mouseup', this.resizeStop);
    this.sendNewState();
  }
  changeWindowSize = (e) =>
  {
    let element = this.refs.body.style;
    let width = parseInt(element.width);
    let height = parseInt(element.height);
    width +=  e.clientX - this.startX;
    height +=  e.clientY - this.startY;
    if(width < this.minWidth)
      width = this.minWidth;
    if(height < this.minHeight)
      height = this.minHeight;
    this.startX = e.clientX;
    this.startY = e.clientY;
    element.width = width + 'px'; 
    element.height = height + 'px'; 
  }
  resizeDown = (e) => {
    window.getSelection().removeAllRanges();
    let where = this.refs.body.parentNode;
    this.startX = e.clientX;
    this.startY = e.clientY;
    where.addEventListener('mousemove', this.changeWindowSize);
    where.addEventListener('mouseup', this.resizeStop);
    this.refs.content.style.userSelect = 'none';
  } 
  changeWindowPosition = (e) => {
    let element = this.refs.body.style;
    let left = parseInt(element.left);
    let top = parseInt(element.top);
    left +=  e.clientX - this.startX;
    top +=  e.clientY - this.startY;
    if(left < 0)
      left = 0;
    if(top < 0)
      top= top;
    this.startX = e.clientX;
    this.startY = e.clientY;
    element.left = left + 'px'; 
    element.top = top + 'px'; 
  }
  movingStop = (e) =>
  {
    let elem = this.refs.body.parentNode;
    elem.removeEventListener('mousemove', this.changeWindowPosition);
    setTimeout(()=>{window.getSelection().removeAllRanges();}, 30);
    this.refs.content.style.userSelect = 'auto';
    elem.removeEventListener('mouseup', this.movingStop);
  }
  moveWindow = (e) => {
      window.getSelection().removeAllRanges();
      let where = this.refs.body.parentNode;
      this.startX = e.clientX;
      this.startY = e.clientY;
      where.addEventListener('mousemove', this.changeWindowPosition);
      where.addEventListener('mouseup', this.movingStop);
      where.addEventListener('mouseup', this.movingStop);
      this.refs.content.style.userSelect = 'none';
      this.sendNewState(); 
  }
  makeActive = (e) =>
  {
    this.sendNewState();
  }
  render() {
    let styleWindow = {
      width: this.props.width,
      height: this.props.height,
      top: this.props.top,
      left: this.props.left,
      zIndex: this.props.zIndex

    }
      return (
      <div ref="body" className="window"style={styleWindow}>
        <div onMouseDown={this.moveWindow} className="windowTitle">
            <span>{this.props.name}</span>
            <input onClick={this.closeWindow} type="submit" value="" className="closeButton"/>
        </div>
        <div onClick={this.makeActive} ref="content" className="windowContent">{this.props.content}</div>
        <div onMouseDown={this.resizeDown} className="windowResize"></div>
      </div>
      )
    }
}

import React, {Component} from 'react';
import { connect } from 'react-redux';
import { actions } from 'actions/actions.jsx';
import { UserWindow } from './UserWindow.jsx';
require('style!css!aplicationStyles/Windows/Windows.css');
class Windows extends Component {
  render() {
      
      if (this.props.store.windows)
      {
          let elements = this.props.store.windows.map((el) => {
          return <UserWindow 
          width={el.width} 
          height={el.height} 
          top={el.top} 
          left={el.left} 
          zIndex={el.zIndex} 
          name={el.name} 
          el={el.id}
          key={el.id} 
          content={el.content}
          parent={this} />
      });
        return (
            <div className="windows">
                {elements}
            </div>
        );
      }
      else
        return null;
  }
}

export default connect(
state => ({
    store: state
}),
dispatch => ({
    closeWindow: (id) => {
        dispatch(actions.windows.closeWindow(id))
    },
    changeWindowPosition: (id,width,height,top,left,zIndex) =>{
           // dispatch(action.windows.changeWindowPosition(id,width,height,top,left))
           dispatch(actions.windows.changeWindowPosition(id,width,height,top,left,zIndex));
        }
})
)(Windows);
  • Вопрос задан
  • 416 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы