React-draggable npm 包防止在输入字段内点击
React-draggable npm package prevents clicking inside input field
我正在使用 npm 包“react-draggable”来允许拖动包含表单的元素。
现在我可以在我的元素周围拖动了,我很高兴...但是输入字段不可单击,因为您无法单击和键入。我唯一能做的就是点击并按住然后输入。
片段:
render() {
return (
<Draggable>
<div className="pokedex">
<div className="screen">
{this.state.isSearching ? (<Loader/>) : null}
{this.state.hasFound ? this.renderResult() : null}
{this.state.hasError ? (<p className="text-center error">{this.state.hasError}</p>) : null}
</div>
<form onSubmit={(e) => this.onSubmit(e)}>
<input className="field" type="text" placeholder="Who is this pokemon?" onChange={(e) => this.setPokemon(e.target.value)}/>
{this.state.isSearching ? <input className="button text-center" disabled type="submit" value="Find!"/> : <input className="button text-center" type="submit" value="Find!"/>}
</form>
<div className="button-group">
<div className="blue-button"/>
<div className="green-button"/>
<div className="orange-button"/>
</div>
</div>
</Draggable>
)
}
有没有办法避免这种行为?
添加 event.stopPropagation()
onMouseDown 成功了!
Prevents further propagation of the current event in the capturing and bubbling phases.
片段:
render() {
return (
<Draggable>
<div className="pokedex">
<div className="screen">
{this.state.isSearching ? (<Loader/>) : null}
{this.state.hasFound ? this.renderResult() : null}
{this.state.hasError ? (<p className="text-center error">{this.state.hasError}</p>) : null}
</div>
<form onSubmit={(e) => this.onSubmit(e)}>
<input onMouseDown={(e) => {e.stopPropagation()}} className="field" type="text" placeholder="Who is this pokemon?" onChange={(e) => this.setPokemon(e.target.value)}/>
{this.state.isSearching ? <input className="button text-center" disabled type="submit" value="Find!"/> : <input className="button text-center" type="submit" value="Find!"/>}
</form>
<div className="button-group">
<div className="blue-button"/>
<div className="green-button"/>
<div className="orange-button"/>
</div>
</div>
</Draggable>
)
}
stopPropagation()
对我不起作用。但是 cancel
确实如此。
render() {
return (
<Draggable
cancel=".field"
>
<div className="pokedex">
<div className="screen">
{this.state.isSearching ? (<Loader/>) : null}
{this.state.hasFound ? this.renderResult() : null}
{this.state.hasError ? (<p className="text-center error">{this.state.hasError}</p>) : null}
</div>
<form onSubmit={(e) => this.onSubmit(e)}>
<input className="field" type="text" placeholder="Who is this pokemon?" onChange={(e) => this.setPokemon(e.target.value)}/>
{this.state.isSearching ? <input className="button text-center" disabled type="submit" value="Find!"/> : <input className="button text-center" type="submit" value="Find!"/>}
</form>
<div className="button-group">
<div className="blue-button"/>
<div className="green-button"/>
<div className="orange-button"/>
</div>
</div>
</Draggable>
)
}
在我这边,我不得不编写一些代码 'observer' 来检测用户是否真的在拖动或点击。原理是计算拖动起点和拖动停止点之间的距离:
function useClickObserver(callback)
{
const [dragStartPos, setDragStartPos] = React.useState(new Point())
const onStart = (_, data) =>
{
setDragStartPos(new Point(data.x, data.y))
}
const onStop = (_, data) =>
{
const dragStopPoint = new Point(data.x, data.y)
if(Point.dist(dragStartPos, dragStopPoint) < 5)
{
callback()
}
}
return {onStart, onStop}
}
并将其注入 Draggable:
<Draggable
onDrag={handleDrag}
{...useClickObserver(myOnClickCallback)}
>
在此处查看完整源代码:
https://gitlab.com/ggpack/banana/-/blob/master/src/components/Emitter.js#L22
现场示例(PWA):
https://ggpack.gitlab.io/banana
我正在使用 npm 包“react-draggable”来允许拖动包含表单的元素。
现在我可以在我的元素周围拖动了,我很高兴...但是输入字段不可单击,因为您无法单击和键入。我唯一能做的就是点击并按住然后输入。
片段:
render() {
return (
<Draggable>
<div className="pokedex">
<div className="screen">
{this.state.isSearching ? (<Loader/>) : null}
{this.state.hasFound ? this.renderResult() : null}
{this.state.hasError ? (<p className="text-center error">{this.state.hasError}</p>) : null}
</div>
<form onSubmit={(e) => this.onSubmit(e)}>
<input className="field" type="text" placeholder="Who is this pokemon?" onChange={(e) => this.setPokemon(e.target.value)}/>
{this.state.isSearching ? <input className="button text-center" disabled type="submit" value="Find!"/> : <input className="button text-center" type="submit" value="Find!"/>}
</form>
<div className="button-group">
<div className="blue-button"/>
<div className="green-button"/>
<div className="orange-button"/>
</div>
</div>
</Draggable>
)
}
有没有办法避免这种行为?
添加 event.stopPropagation()
onMouseDown 成功了!
Prevents further propagation of the current event in the capturing and bubbling phases.
片段:
render() {
return (
<Draggable>
<div className="pokedex">
<div className="screen">
{this.state.isSearching ? (<Loader/>) : null}
{this.state.hasFound ? this.renderResult() : null}
{this.state.hasError ? (<p className="text-center error">{this.state.hasError}</p>) : null}
</div>
<form onSubmit={(e) => this.onSubmit(e)}>
<input onMouseDown={(e) => {e.stopPropagation()}} className="field" type="text" placeholder="Who is this pokemon?" onChange={(e) => this.setPokemon(e.target.value)}/>
{this.state.isSearching ? <input className="button text-center" disabled type="submit" value="Find!"/> : <input className="button text-center" type="submit" value="Find!"/>}
</form>
<div className="button-group">
<div className="blue-button"/>
<div className="green-button"/>
<div className="orange-button"/>
</div>
</div>
</Draggable>
)
}
stopPropagation()
对我不起作用。但是 cancel
确实如此。
render() {
return (
<Draggable
cancel=".field"
>
<div className="pokedex">
<div className="screen">
{this.state.isSearching ? (<Loader/>) : null}
{this.state.hasFound ? this.renderResult() : null}
{this.state.hasError ? (<p className="text-center error">{this.state.hasError}</p>) : null}
</div>
<form onSubmit={(e) => this.onSubmit(e)}>
<input className="field" type="text" placeholder="Who is this pokemon?" onChange={(e) => this.setPokemon(e.target.value)}/>
{this.state.isSearching ? <input className="button text-center" disabled type="submit" value="Find!"/> : <input className="button text-center" type="submit" value="Find!"/>}
</form>
<div className="button-group">
<div className="blue-button"/>
<div className="green-button"/>
<div className="orange-button"/>
</div>
</div>
</Draggable>
)
}
在我这边,我不得不编写一些代码 'observer' 来检测用户是否真的在拖动或点击。原理是计算拖动起点和拖动停止点之间的距离:
function useClickObserver(callback)
{
const [dragStartPos, setDragStartPos] = React.useState(new Point())
const onStart = (_, data) =>
{
setDragStartPos(new Point(data.x, data.y))
}
const onStop = (_, data) =>
{
const dragStopPoint = new Point(data.x, data.y)
if(Point.dist(dragStartPos, dragStopPoint) < 5)
{
callback()
}
}
return {onStart, onStop}
}
并将其注入 Draggable:
<Draggable
onDrag={handleDrag}
{...useClickObserver(myOnClickCallback)}
>
在此处查看完整源代码: https://gitlab.com/ggpack/banana/-/blob/master/src/components/Emitter.js#L22
现场示例(PWA): https://ggpack.gitlab.io/banana