[英]Registering click on different components in React
我有一个正在进行的项目,有一个有趣的困境。 我创建了一个组件(来自推荐的 React component/div draggable 方法)并对其进行了修改,以便 onMouseDown 仅在元素上而不在文档上。 在同一页面中,我有一个没有注册点击事件,尽管它获得了右键单击的焦点。 如果有人能发现为什么我不能单击以专注于文本输入,我将在此处附上元素和输入布局的整个代码。
Draggable.js
import React from 'react';
import PropTypes from 'prop-types';
class Draggable extends React.Component {
constructor(props) {
super(props);
this.state = {
relX: 0,
relY: 0,
x: parseInt(props.left),
y: parseInt(props.top),
dragged: false
};
this.gridX = props.gridX || 2;
this.gridY = props.gridY || 2;
this.onMouseDown = this.onMouseDown.bind(this);
this.onMouseMove = this.onMouseMove.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
this.onContext = this.onContext.bind(this);
this.clickRef = React.createRef();
}
static propTypes = {
onMove: PropTypes.func,
onStop: PropTypes.func,
onContext: PropTypes.func,
left: PropTypes.number.isRequired,
top: PropTypes.number.isRequired,
gridX: PropTypes.number,
gridY: PropTypes.number
};
onStart(e) {
if (this.props.enabled) {
this.setState({
relX: e.pageX - this.props.left,
relY: e.pageY - this.props.top
})
}
}
onMove(e, current) {
if (this.props.enabled) {
const x = Math.trunc((e.pageX - this.state.relX) / this.gridX) * this.gridX;
const y = Math.trunc((e.pageY - this.state.relY) / this.gridY) * this.gridY;
if (x !== this.state.x || y !== this.state.y) {
this.setState({
x,
y,
dragged: true
});
this.props.onMove && this.props.onMove({ left: this.state.x, top: this.state.y });
}
}
}
onMouseDown(e) {
if (e.button !== 0) return;
this.onStart(e);
this.clickRef.current.addEventListener('mousemove', this.onMouseMove);
this.clickRef.current.addEventListener('mouseup', this.onMouseUp);
e.preventDefault();
}
onMouseUp(e) {
this.clickRef.current.removeEventListener('mousemove', this.onMouseMove);
this.clickRef.current.removeEventListener('mouseup', this.onMouseUp);
this.props.onStop && this.props.onStop(e, this.props.index ? this.props.index : null, { left: this.state.x, top: this.state.y, dragged: this.state.dragged });
this.setState({ dragged: false });
if (this.props.onStop) e.preventDefault();
}
onMouseMove(e) {
this.onMove(e, this.props.index ? this.props.index : null, { left: this.state.x, top: this.state.y });
e.preventDefault();
}
onContext(e) {
if (this.props.onRightClick) {
e.preventDefault();
this.props.onRightClick(e, this.props.index ? this.props.index : null);
}
}
render() {
let style = {}
if (this.props.style) {
style = { ...this.props.style }
}
if (!(style.position && style.position === 'fixed')) {
style.position = 'absolute';
}
style.left = this.state.x + 'px';
style.top = this.state.y + 'px'
return <div
onMouseDown={this.onMouseDown}
onContextMenu={this.onContext}
onMouseMove={this.onMouseMove}
onMouseUp={this.onMouseUp}
style={style}
ref={this.clickRef}
>
{this.props.children}
</div>;
}
}
export default Draggable;
function 创建可拖动组件:
buildDesks = () => {
const newScale = this.getScale();
const layout = this.props.layout;
let container = document.querySelector("#Layout_Map_Container");
const desks = layout.desks;//.filter(desk => parseInt(desk.SiteId) === parseInt(map.id));
let ret = desks.map((desk, index) => {
let deskImg = null;
try {
let dImg = layout.deskTypes.find(d => parseInt(d.deskType) === parseInt(desk.deskType));
deskImg = dImg.deskImage;
}
catch (ex) {
console.log(ex);
}
const userName = desk.UserLogon !== (null || '') ? desk.UserLogon : "Unassigned";
const top = Math.trunc(parseInt(parseInt(desk.y) * newScale));
const left = Math.trunc(parseInt(parseInt(desk.x) * newScale));
const imgStyle = {
width: `${parseInt(parseInt(desk.width) * newScale)}px`,
height: `${parseInt((parseInt(desk.height) * newScale))}px`,
transform: `rotate(${parseInt(desk.rotation)}deg)`
}
const url = `data:image/jpeg;base64,${deskImg}`;
try {
return (
<Draggable key={desk.DeskID}
index={desk.DeskID}
enabled={this.state.edit}
left={left}
top={top}
onMove={this.updateProperties}
onStop={this.endMove}
onRightClick={this.rightClick}
>
<img style={imgStyle} alt={userName} src={url} />
</Draggable>
);
}
catch (ex) {
console.log(ex);
return null;
}
});//desks.map
return ret;
}//buildDesks
接下来创建文本框:
showStatus = () => {
//screen width - object width - right coordinate
let left = parseInt(window.innerWidth - 225);
let top = 106;
// return (<div></div>);
return (
<Draggable enabled={true}
top={top}
left={left}
>
<div style={{ width: '200px' }} className='editData'
style={{ position: 'fixed', top: top + 'px', left: left + 'px' }}>
<Row className='statusRow'>
<Col sm={12}>
<div id="Layout_UserImg" title="Click to upload new user image">
<div id="Layout_UserImgLabel">
Click to
upload new
user image</div>
</div>
</Col>
</Row>
<Row className='statusRow'>
<Col sm={5} className='statusDivHeading'>Manager</Col>
<Col sm={7} className='statusDivData'><input type='text' id="Layout_Manager" /></Col>
</Row>
<Row className='statusRow'>
<Col sm={5} className='statusDivHeading'>User</Col>
<Col sm={7} className='statusDivData'><input type='text' id="Layout_User" /></Col>
</Row>
<Row className='statusRow'>
<Col sm={5} className='statusDivHeading'>Emp. Id</Col>
<Col sm={7} className='statusDivData'><input type='text' id="Layout_EmpId" /></Col>
</Row>
<Row className='statusRow'>
<Col sm={5} className='statusDivHeading'>Extension</Col>
<Col sm={7} className='statusDivData'><input type='text' id="Layout_Extension" /></Col>
</Row>
<Row className='statusRow'>
<Col sm={5} className='statusDivHeading'>Department</Col>
<Col sm={7} className='statusDivData'><input type='text' id="Layout_Department" /></Col>
</Row>
<Row className='statusRow'>
<Col sm={5} className='statusDivHeading'>DB Id</Col>
<Col sm={7} className='statusDivData'><input type='text' id="Layout_DBRowId" /></Col>
</Row>
<Row className='statusRow'>
<Col sm={5} className='statusDivHeading'>Desk ID</Col>
<Col sm={7} className='statusDivData'><input type='text' id="Layout_DeskID" /></Col>
</Row>
<Row className='statusRow'>
<Col sm={5} className='statusDivHeading'>Assets</Col>
<Col sm={7} className='statusDivData'><input type='text' id="Layout_Assets" /></Col>
</Row>
<Row>
<Col>
<button onClick={this.updateStats}>Save Changes</button>
</Col>
<Col>
<button onClick={this.clearUserStats}>Clear all fields</button>
</Col>
</Row >
</div >
</Draggable >
)
}
最后是我的渲染:
render() {
if (this.props.layout.isLoading) {
return (<Loading title="Site Layout" />);
}
else if (this.props.layout.isLoadingMap) {
const map = this.props.layout.maps[this.props.layout.currentMap];
const siteName = map.SiteName;
return (
<Row>
<Col sm={1}></Col>
<Col sm={10} id="Layout_Map_Container">
<Loading title={"map '" + siteName + "'"} />
</Col>
</Row>
);
}
else if (this.props.layout.mapLoaded) {
return (
<div>
<Row>
<Col sm={1}>
{this.showAdmin()}
</Col>
<Col sm={10}>
{this.state.details}
</Col>
</Row>
<Row>
<Col sm={1}>
<select onChange={(e) => this.changeMap(e.target)}>
{this.buildMapOptions()}
</select>
</Col>
<Col sm={10} id="Layout_Map_Container">
{this.buildMap()}
{this.buildDesks()}
</Col>
</Row >
{this.showStatus()}
</div>
);
}
else {
return (
<Row>
<Col sm={1}>
<select onChange={(e) => this.changeMap(e.target)}>
{this.buildMapOptions()}
</select>
</Col>
<Col sm={10} id="Layout_Map_Container">
</Col>
</Row>
);
}
}
很多此代码仍未完善,因此如果您看到任何应该进行的更改,请同时指出。 同时,为什么 showStatus() 中的文本框不起作用?
谢谢你。
事实证明,当表单位于 ' 组件中时会出现问题,该组件将 onMouseDown 应用于表单的容器。 一旦被删除点击事件被正确注册。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.