H5移动端输入框随键盘上移

textarea置底展示问题

ios 中的输入体验永远伴随着一个问题,就是当唤起键盘后,整个页面会被键盘压缩,也就是说页面的高度变小,并且所有的fixed全部变为了absolute。
android效果:

使用 fixed 定位。

可见 android 中唤起键盘是覆盖在页面上,不会压缩页面。

在 ios 上的效果:

那么如果我们需要将输入框固定在屏幕下方,而当键盘被唤起同时输入框固定在键盘上方(如下图样式)该如何解决呢?

首先我们来看下 ios 的表现。

可以看出,键盘会将页面顶上去。那么如果希望可以将输入框和键盘完全贴合,我们可以使用div模拟一个假的输入框,使用定位将真正的输入框隐藏掉,当点击假的输入框的时候,将真正的输入框定位到键盘上方,并且手动获取输入框焦点。

在实现过程中需要注意下面几个问题:

1、真正的输入框的位置计算:

首先记录无键盘时的 window.innerHeight,当键盘弹出后再获取当前的 window.innerHeight ,两者的差值即为键盘的高度,那么定位真输入框自然就很容易了。

2、在 ios 下手动获取焦点不可以用 click 事件,需要使用 tap 事件才可以手动触发

$('#fake-input').on($.os.ios?'tap' : 'click', function() {
    initHeight = window.innerHeight;
    $('#input').focus();
});

3、当键盘收起的时候我们需要将真输入框再次隐藏掉,除了使用失去焦点(blur)方法,还有什么方法可以判断键盘是否收起呢?

这里可以使用 setInterval 监听,当当前 window.innerHeight 和整屏高度相等的时候判断为键盘收起。
注意:键盘弹起需要一点时间,所以计算当前屏幕高度也需要使用setInterval。

4、因为 textarea 中的文字不能置底显示,当输入超过一行textarea需要自动调整高度,因此将scrollHeight赋值给textarea的height。当删除文字的时候需要height也有变化,因此每次input都先将height置0,然后再赋值。

$('#textarea').css('height', 0);
$('#textarea').css('height', $('#textarea')[0].scrollHeight);
仿原生效果

解决webview中input被遮挡后webview整体在iOS壳子中向上滚动,而不是仅input随着键盘抬高问题

js中代码:

{ $("#commentInputItem").show(); $("#commentInputDiv").hide(); const handler = window["webkit"] && webkit && webkit.messageHandlers["bridgeMessage"] if (handler) { // 是在iOS壳子里 $(".comment-reply").css({ top: "auto", bottom: "1000px", position: "absolute", opacity: "1" }); } this.text.focus(); }}>回复...
(this.text = el)} placeholder="回复..." onFocus={this.commentFocus.bind(this)} onBlur={this.commentBlur.bind(this)} clear={true} value={replyContent} onChange={e => this.dispatch({ type: "changeState", data: { replyContent: e } })} />
        commentFocus() {
            // this.dispatch({ type: "input", data: { comment: true } });
            if (!browser.versions.ios) {
                // 非IOS系统
                $("#comment").css({ position: "relative", opacity: "1" });
                $("#autoFocus").focus();
            } else {
                const handler = window["webkit"] && webkit && webkit.messageHandlers["bridgeMessage"]
                if (handler) { // 是在iOS壳子里
                    window["setHeightComment"] = (height) => {
                        $(".comment-reply").css({ top: "auto", bottom: height + "px", position: "absolute", opacity: "1" });
                    };
                    return;
                }
            }
        }

        commentBlur() {
            $("#commentInputItem").hide();
            $("#commentInputDiv").show();
            window["setHeightComment"] = null;
            $(".comment-reply").attr("style", "");
        }

原生中代码:

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeFramePoint:) name:UIKeyboardDidChangeFrameNotification object:nil];

-(void)changeFramePoint:(NSNotification *)notification{
        NSDictionary *userInfo = [notification userInfo];
         CGSize value = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
        CGFloat keyBoardHight = value.height;  // 得到键盘弹出后的键盘视图所在y坐标
        if (KIsiPhoneX || KIsiPhoneXR || KIsiPhoneX_MAX) {
            [wkWebView evaluateJavaScript:[NSString stringWithFormat:@"setCommentHeight('%@')",[NSString stringWithFormat:@"%f",keyBoardHight-34]] completionHandler:nil];
        }else{
            [wkWebView evaluateJavaScript:[NSString stringWithFormat:@"setCommentHeight('%@')",[NSString stringWithFormat:@"%f",keyBoardHight]] completionHandler:nil];
        }
}

大概思路就是使用div模拟假输入框,点击div显示真输入框并抬高至真输入框不会被键盘遮挡(这样iOS中就不会向上滚动webview),抬高后再手动聚焦真输入框input,原生拿到键盘高度后再设置input位置到键盘上方.

你可能感兴趣的:(我的前端)