React的onPaste必须点击一次元素才能起作用问题

在React中封装图片组件时遇到onPaste事件只能在元素被点击后才生效的问题。尝试了手动组件、手动绑定事件等方法无果,可能由于浏览器设定非表单元素无法直接粘贴。在Vue中则可以直接使用。在React GitHub issue中找到一种hack方法,即通过添加和属性使元素变为可编辑并手动聚焦,但这种方法并不理想。

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添加tabindexcontentEditable,将元素变成一个可以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的写法,目前还不知道有什么其他方法.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值