React的onPaste必须点击一次元素才能起作用问题
最近在封装一个图片组件的过程中,有一个需求是需要能够复制粘贴上传图片, 因为React中有自带的合成事件onPaste
绑定事件,但是出现一个问题是, 鼠标直接放在上面,并不能触发onPaste
事件 .使用了各种方法都不行
handlePaste = (e)=> {
console.log(e)
}
...
<div className="cropper" onPaste={this.handlePaste}>
</div>
各种方法都尝试过了,下面尝试过的方法:
- 手动
focus()
组件 - 手动
click()
组件 - 手动绑定事件
ReactDOM.findDOMNode(this.refs.cropper).addEventListener('paste',(event)=> {this.handlePaste(event)})
这些方法都不行,必须要用户主动点击一下才行,这个我认为可能是浏览器的设定,非表单元素不能直接进行粘贴,也不能手动focus
,必须用户选中元素,不能用代码来模拟点击和聚焦,但是在vue用是可以直接使用的,我猜测是vue中的指令是通过由body监听到事件再分发给绑定了指令的元素,只是猜测
//vue中自定义指令
Vue.directive('paste',{
bind(el,binding,vnode) {
el.addEventListener('paste',function(event){
binding.value(event)
})
}
})
然后再react的github的issue里找到了一个相同的提问,有一种比较hack的方法,但是确实没有人给出有其他方法,大家都认为是浏览器行为.
里面的解决方法是,给div
添加tabindex
和contentEditable
,将元素变成一个可以focus
的元素,然后手动聚焦
var Hello = React.createClass({
handlePaste: function(evt) {
evt.preventDefault();
console.log("handling paste");
},
render: function() {
return <div
style={{color: "transparent"}}
tabIndex={0}
contentEditable={true}
ref={function(main) {
if (main != null) {
main.focus();
}
}
}
onPaste={this.handlePaste}>
<svg width={200} height={200}>
<rect width={50} height={50}/>
</svg>
text
</div>;
}
});
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
这种方法是比较hack的写法,目前还不知道有什么其他方法.