onblur和onlick
来源:互联网 发布:淘宝店铺复古港风推荐 编辑:程序博客网 时间:2024/05/22 13:19
有这样的一个需求:
- 点击“更改”,出现右侧菜单,点击选项后对“更改”左侧的结果进行更改,更改成功后菜单消失
- 菜单出现的情况,点击空白菜单消失
应该是一个很普遍的需求,但是在react里实现还是花费了我一些力气,实际上和react的关系不太,还是各个事件的发生的顺序
首先为了实现点击按钮出现,点击空白消失,对更改按钮的span增加了tabindex,这样就可以通过onfocus和onblur实现,html布局要点就是右侧菜单div用absolute定位,是“更改”的span的子元素,这样点击菜单进行更改时就不会触发span的blur时间,点击完成后再绑定隐藏菜单的事件,perfect!来试一下:
部分代码:
// 点击显示更改学生自判答案的菜单 @action showSelect(index) { for (let i = 0; i < this.selectShow.length; i++) { this.selectShow[i] = false } this.selectShow[index] = true; } // 点击隐藏更改学生自判答案的菜单 @action hideSelect(index) { this.selectShow[index] = false; } // 点击更改学生自判答案 @action onClickChangeScore(index, e) { const {markStore} = this.props; const {questions} = markStore; let currentQuestion = questions[index]; currentQuestion.score = Number(e.target.value); // 强制MarkScoreTable组件刷新 this.updateCounter += 1; // 更改答对率 markStore.changeAccuracy(questions); // 隐藏当前选择菜单 this.selectShow[index] = false; }<div className={styles.markSelectWrap}> <span>学生自判:</span> <i className={styles.myAnswerResultIcon} name={question.score}/> <span className={styles.changeScore} tabIndex="1" onFocus={this.showSelect.bind(this, question.number)} onBlur={this.hideSelect.bind(this, question.number)}>更改 <div className={styles.markSelect} style={{'display': this.selectShow[question.number] ? 'flex' : 'none'}}> <div className={styles.markSelectLeft}> <div className={styles.selectLeftContent}/></div> <div className={styles.markSelectRight}> <div className={styles.selectRight}><input name="select" type="radio" value="2" onClick={this.onClickChangeScore.bind(this, question.number)}/></div> <div className={styles.selectHalf}><input name="select" type="radio" value="1" onClick={this.onClickChangeScore.bind(this, question.number)}/></div> <div className={styles.selectWrong}><input name="select" type="radio" value="0" onClick={this.onClickChangeScore.bind(this, question.number)}/></div> </div> </div> </span></div>
很完美,在我们的客户端和chrome浏览器都实现了,(我们的客户端是用cef框架的chrome46内核的应用程序),但是事情没有到此结束……
程序发布后,把自己的chrome由原来的46升级到了最新的52,发现点击后无法更改答案了!!!降级到49也是不行,只有在46是可以的,为什么?
不知道chrome在46升级后发生什么改变,是修复了bug还是又产生了bug(我估计是前者,之前的实现应该是利用了低版本chrome的bug),虽然对客户端没有影响,但是还是应该解决它。
分析原因,就是在新版本的浏览器中,浏览器并不认为点击出现的菜单属于“更改”的span,点击时先发生了blur事件,所以click事件根本没有发生,上网查找了资料,遇到这种情况,一种解决方法就是用mousedown事件来代替click事件,原因知乎上的邹鹏分析的很好,总结一下:
click事件的触发条件:鼠标点下去,然后松开。点击菜单时本想先触发click,结果先触发了blur,等到松开鼠标真正触发click的时候,鼠标已经不在被绑定click的元素上,所以无法触发。
显然,事件的顺序是:
mousedown -> blur -> mouseup(click)
所以对上面的代码进行更改,1是将input的click事件更改为mousedown事件,而是将事件里的隐藏菜单的代码去掉,由blur事件完成菜单的隐藏
更改后的部分代码如下:
// 点击显示更改学生自判答案的菜单 @action showSelect(index) { for (let i = 0; i < this.selectShow.length; i++) { this.selectShow[i] = false } this.selectShow[index] = true; } // 点击隐藏更改学生自判答案的菜单 @action hideSelect(index) { this.selectShow[index] = false; } // 点击更改学生自判答案 @action onClickChangeScore(index, e) { const {markStore} = this.props; const {questions} = markStore; let currentQuestion = questions[index]; currentQuestion.score = Number(e.target.value); // 强制MarkScoreTable组件刷新 this.updateCounter += 1; // 更改答对率 markStore.changeAccuracy(questions); // 隐藏当前选择菜单 // this.selectShow[index] = false; }<div className={styles.markSelectWrap}> <span>学生自判:</span> <i className={styles.myAnswerResultIcon} name={question.score}/> <span className={styles.changeScore} tabIndex="1" onFocus={this.showSelect.bind(this, question.number)} onBlur={this.hideSelect.bind(this, question.number)}>更改 <div className={styles.markSelect} style={{'display': this.selectShow[question.number] ? 'flex' : 'none'}}> <div className={styles.markSelectLeft}> <div className={styles.selectLeftContent}/></div> <div className={styles.markSelectRight}> <div className={styles.selectRight}><input name="select" type="radio" value="2" D={this.onClickChangeScore.bind(this, question.number)}/></div> <div className={styles.selectHalf}><input name="select" type="radio" value="1" onMouseDown={this.onClickChangeScore.bind(this, question.number)}/></div> <div className={styles.selectWrong}><input name="select" type="radio" value="0" onMouseDown={this.onClickChangeScore.bind(this, question.number)}/></div> </div> </div> </span></div>
但是这样的话好像在低版本的上也会有问题,点击后不消失,我也是醉了。
以后如果做这种不是针对特性版本浏览器客户端的,不行就用透明度去实现,或者在document上绑定事件,然后判断target去实现
- onblur和onlick
- onfoucs和onblur事件
- onfocus和onblur
- onblur()和onfocus()
- HTML onfocus和onblur
- 每周学点js_<a>的href和onlick
- onblur的死锁和解决方案
- 【20100209】onblur 和onfocus问题
- onchange、onpropertychange、oninput和onblur
- js的onblur和onfocus
- onblur和onfocus的区别
- JS: onfocus和onblur事件应用举例
- onblur, onchange和onpropertychange之间的区别
- JS:onfocus和onblur事件应用举例
- JavaScript onfocus和onblur事件应用举例
- JS: onfocus和onblur事件应用举例
- Js中的onblur和onfocus事件
- JS 之 onfocus事件和onblur事件
- Servlet基础
- 导出excel
- 形参与实参&值传递和地址传递
- 关于jwt的思考
- vue
- onblur和onlick
- Spring MVC源码深入剖析执行流程
- libsvm支持向量机参数的意义
- PHP —— Eclipse for php 环境搭建
- extjs textfield 不可编辑,点击不出现光标
- MySql SqlServer Oracle三款 主流数据库的比较
- 【OpenCV入门教程之十一】 形态学图像处理(二):开运算、闭运算、形态学梯度、顶帽、黑帽合辑
- 小白学习laravel/lumen(一)前言
- H.264/AVC率失真优化( RDO) 策略研究