背景
讨论区项目的回复框,使用的是Popup和TextArea做,布局如下图,希望键盘弹出时候,回复框可以紧贴键盘,这点实现起来比较简单,监听resize事件,动态修改popup的这题内容的top值即可,top的计算是document.body.clientHeight - popup中主体内容的高度即可
问题:
ios的键盘弹起时候,“发送”按钮的点击不起作用,“关闭”按钮不起作用,点击蒙层不起作用,就是不会触发click事件
暂时不知道原因,有大佬知道可以告知一下
解决方案:
键盘弹出时候,给按钮和蒙层添加touchstart事件代替click事件即可,重点逻辑:
1. 问题出在ios环境,所以需要是在ios环境才触发touchstart回调,否则直接return
2. 问题出在键盘弹起时候,需要也就是textarea聚焦时候才处理,否则直接return
主要代码图下:
- 函数isIos判断是ios环境
- window.visualViewport.addEventListener(‘resize’, handler)监听键盘弹出收起时候,动态设置popup定位
- processMaskListener是为蒙层添加touchstart事件
- 为TextArea添加onBlur和onFocus事件,用于判断是否聚焦
- 为关闭按钮和发送按钮添加onTouchStart事件
useEffect(() => {
/** 初始化监听 */
window.visualViewport.addEventListener('resize', handler)
processMaskListener()
}, [])
/** 判断是ios环境 */
const isIos = () => {
return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
}
/** 蒙层添加touchstart事件 */
const processMaskListener = () => {
status = ""
const mask = document.getElementsByClassName('adm-mask')[0]
if (!mask) { return }
mask.addEventListener('touchstart', () => {
if (isIos() && status === "focus") {
maskClickWillDo()
}
}, false)
}
const handler = () => {
const popTop = document.body.clientHeight - document.getElementsByClassName('pop-input')[0].parentNode.clientHeight
setPopStyle(popTop)
}
return (
<React.Fragment>
<Popup
className='reply-pop'
destroyOnClose={true}
visible={visible}
onMaskClick={() => maskClickWillDo()}
>
<div className="pop-input">
<div className="input-title">
<img
className="input-close"
alt=""
src={closeImg}
onTouchStart={() => {
if (isIos() && status === "focus") {
maskClickWillDo()
}
}}
onClick={() => maskClickWillDo()}
/>
<div
className={inputValue ? 'commit' : 'commit no-commit'}
onTouchStart={() => {
if (isIos() && status === "focus") {
onsole.log('%c [ onTouchStart执行了 ]-96', 'font-size:13px; background:pink; color:#bf2c9f;', )
prop.onSendFunc(inputValue)
}
}}
onClick={() => {
console.log('%c [ onClick执行了 ]-101', 'font-size:13px; background:pink; color:#bf2c9f;', )
prop.onSendFunc(inputValue)
}}
>
{prop.btnText ? prop.btnText : "发送"}
</div>
</div>
<div className='btn-style'>
<TextArea
id='textId'
ref={inputRef}
value={inputValue}
rows={5}
placeholder={prop.answerText ? prop.answerText : "我也来说两句.."}
onChange={(e) => {
setInputValue(e)
}}
onBlur={() => status = "blur"}
onFocus={() => status = "focus"}
/>
</div>
</div>
</Popup>
</React.Fragment>
)
键盘弹起时候,点击发送按钮