При попытки выделить сообщение в textarea, происходит перетаскивание блока. React
При попытки выделить сообщение в textarea, происходит перетаскивание блока. React.
Если я передаю в любой обработчик событий (ondown, onmousemove и п.т вместе или раздельно вешаю именно на обработчики которые схожи в контейнере onDrag) textarea и сразу же "гашу" обработчик при помощи preventDefault() и stoppropagation- это не работает.
sender.tsx:
в этом компоненте происходит основная логика для отправки сообщения. (здесь и происходит баг)
return <OnDrag>
<div className="container-sending">
<div>
{store?.from?.length > 0 && store.from.map((id) => <div
key={id.msg}
className="message_from btn"
onClick={() => dispatch(deleteUserHandlerSender({msg: id.msg, thread: id.thread}))}
> » {id.msg === 0 ? '№' + id.thread : id.msg}</div>)}
</div>
<div className="container-message">
{store.from.length > 0 ?
<textarea className="container-textarea" onChange={textareaHamdler} ref={ref} value={store.message}/>
:
<div className="container-error">Требуется отправитель</div>}
</div>
<div className="container-button">
{store.from.length > 0 &&
<button className="btn btn-sender"
onClick={dataSend}
>Отправить</button>}
</div>
</div>
</OnDrag>
ondrag.tsx:
это компонент обертка в который я прокидываю нужные элементы для возможности перетаскивания их по экрану.
const dispatch = useDispatch();
const ref = useRef<HTMLDivElement>(null);
const [cursor, setCursor] = useState({x: 0, y: 0});
const [translate, setTranslate] = useState({ x: 0, y: window.pageYOffset});
const storeSender = useSelector((store: ReduxStore) => store.SENDER);
const handleDrag = (event: MouseEvent) => {
if(ref && ref.current){
const dialogWidth = ref.current.clientWidth;
const x = Math.min(
Math.max(0, event.pageX - cursor.x),
window.innerWidth - dialogWidth - 20
);
const y = Math.min(
Math.max(0, event.pageY - cursor.y),
window.pageYOffset + window.innerWidth
);
setTranslate({
x: x,
y: y
});
}
};
const enableDragging = (event: MouseEvent) => {
setCursor({
x: event.pageX - translate.x,
y: event.pageY - translate.y
});
}
const drag = useDrag(ref, translate, {onDrag: handleDrag, onMouseDown: enableDragging });
useEffect(() => {},[drag, storeSender]);
return <div
ref={ref}
style={{ top: translate.y + "px", left: translate.x + "px" }}
className="container-drag_element"
>
<div className="container-drag_carry">
<span className="container-drag_close"
onClick={() => dispatch(openHandlerSender(false))}
>✕</span>
</div>
{props.children}
</div>
useDrag.tsx:
это хук отвечающий за логику перетаскивания блока (в данном случае, компоненте обертки ondrag)
export const useDrag = (ref: React.MutableRefObject<HTMLDivElement | null>, deps:Position, options: IDrag) => {
const {
onMouseDown = () => {},
onMouseUp = () => {},
onMouseMove = () => {},
onDrag = () => {}
} = options;
const [isDragging, setIsDragging] = useState(false);
const handlePointerDown = (e:MouseEvent) => {
setIsDragging(true);
onMouseDown(e);
}
const handlePointerUp = (e:MouseEvent) => {
setIsDragging(false);
onMouseUp(e);
}
const handlePointerMove = (e:MouseEvent) => {
onMouseMove(e);
if (isDragging) return onDrag(e);
}
useEffect(() => {
addEvent();
return () => removeEvent();
}, [deps, isDragging]);
const addEvent = () => {
const element = ref.current;
if(element){
element.addEventListener("mouseup", handlePointerUp);
element.addEventListener("mouseleave", handlePointerUp);
element.addEventListener("mousemove", handlePointerMove);
element.addEventListener("mousedown", handlePointerDown);
}
}
const removeEvent = () => {
const element = ref.current;
if(element){
element.removeEventListener("mouseup", handlePointerUp);
element.removeEventListener("mouseleave", handlePointerUp);
element.removeEventListener("mousemove", handlePointerMove);
element.removeEventListener("mousedown", handlePointerDown);
}
}
return { isDragging }
}