попытался создать таскающиеся окна информация о которых находится в сторе.
Получилось что-то ядерное. Хотел бы попросить помочь в доработке. Оно как-то все работает, но выглядит страшно. Пришлось руками лезть в 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);