Recently, a project fell into the pit of mobile terminal, including fixed layout in ios, keyboard evoked by H5 and other problems. As a B-terminal programmer, the weakness is browser compatibility and mobile terminal adaptation (after all, we can use Chrome). Fortunately, I learned some relevant knowledge this time. Let’s take a look at how I fought my way out of this hole.

The background,

Take a look at what to do, which is a post comment section with input boxes, likes, favorites, etc. It looks something like this:

The requirements are pretty routine, suck the bottom, enter comments and submit. So let’s go ahead and type in the code.

Ii. Fixed layout under ios

About this bottom suction operation, on the direct selection of fixed, this kind of scene instead of him who. This is the preliminary layout. (Because I use react, JSX writing method is very hard to paste, so write a code to represent, don’t be offended)

1 <body>
2     <div class='top'></div>
3     <div class='main'></div>
4     <div class="fix-bottom"></div>
5 </body>Copy the code

And then you don’t write much CSS, and the browser looks like that. Then something happened on ios. This is what it looks like (hopefully no factory workers)

Jacked up like that… If there is a problem, even if there is no time to solve it quickly, then we should also figure out the cause and effect. After all, we do not solve the problem for the sake of solving the problem. Let’s see why

2.1 Causes of Fixed Failure in ios

When the soft keyboard is aroused, the fixed element on the page will become invalid (ios thinks that the user wants the element to move with the scroll, that is, become absolute position). Since it is absolute, the invalid fixed element will follow the scroll when the page is more than one screen.

The same problem applies to any soft keyboard (such as date and time selection, select selection, etc.) that is invoked, not just for type=text fields.

2.2 How to Solve the problem

Since ios is what it is, we’ll just have to accept it and find a way around it. Roughly speaking, there are two directions:

1, Since it will become absolute, just use absolute.

Bottom directly uses body as the parent element for absolute positioning, but this kind of positioning is not recommended on the Internet. It seems that there are more problems waiting to be corrected, and the previous experience should be used for reference, so I did not try, but interested students can have a try.

2. Don’t let the page scroll, but let the body scroll by itself

If Fixed fails but the page is not longer than one screen, then absolut or Fixed makes no difference. With that in mind, let’s go back to the above structure and let main just roll around. The element and the theme of the bottom as two containers, the main part, set absolute positioning, fixed in the middle of the screen, beyond the part will roll on their own, the bottom element can play by themselves

It looks something like this:

1 <body>
2     <div class='warper'>
3         <div class='top'></div>
4         <div class='main'></div>
5     <div>
6     <div class="fix-bottom"></div>
7 </body>Copy the code

The corresponding style is as follows:

1 .cont-warper{ 2 position: absolute; 3 width: 100%; 4 left: 0; 5 right: 0; 6 top: 0; 7 bottom: 0; 8 overflow-y: scroll; 9 -webkit-overflow-scrolling: touch; Fix -bottom{12 position:fixed; 13 bottom:0; 14 width: 100%; 15}Copy the code

That would avoid the above problem. But the ios, the lower part for suction bottom element on the screen to evoke the keyboard, will be covering parts, some information is referred to a third party input method of the toolbar, I see the bottom of the suction phenomenon is elements are covered, in this case, we have to add a listener, when evoking the keyboard Settings scrollTop value, So if you don’t come up, I force you to come up:

/** * call up the keyboard, scroll */scrollContent() {
        this.interval = setInterval(() => { this.scrollToEnd(); }}, 500)scrollToEnd() {
        document.body.scrollTop = document.body.scrollHeight;
    }
    clearSrcoll() {
        clearInterval(this.interval);
    }Copy the code

Set delay toggle, input clear when losing focus.

H5 calls the virtual keyboard

Now that the layout problem is solved, let’s start writing happy. Before we start, let’s go back to the visual image above to see if there is something missing. What about our submission button? Generally speaking:

This let me how to start, but also good to consult the next boss, as an old driver he gently told me three words: online search…

But anyway, for this type of submission, it’s obviously a return on a soft keyboard. The search button you’ll most likely see is the use of type= ‘search’. If you want to submit information via the keyboard, you need to pull out the form form.

3.1 Keyboard Submission Event

This is typically done by including input in the form form so that you can listen for the Submit event. If someone asks me if AJAX is a walk and not a form, remember that there is an onSubmit event that does something you want to do. The code is as follows:

1 <form onClick={::this.changeInput} onSubmit={this.comment.bind(this, postID)}>
2 <Input type="text" placeholder="Please enter" id='commentInput'  value={::this.getVal()} onFocus={::this.scrollContent} onBlur={::this.clearSrcoll}/>
3 </form>Copy the code

React JSX might look like a pain in the ass. All of these things are really necessary. Here’s the idea:

1. Submit event can monitor the enter key of the user’s soft keyboard. For Ajax submission, we need to prevent the default event of the form to avoid the page refresh behavior of form submission

1 comment(postID, e) {2 e.preventdefault () 3Copy the code

This completes listening for the soft keyboard commit event, but other problems arise

3.2 Other areas evoke soft keyboards

Looking at the visuals again, it’s not just clicking on input to submit a comment, but there’s also a need to respond to someone else’s comment, and clicking on the label of the reply also calls up the keyboard to do it.

  

On mobile, h5 input, Focus, and blur can call up and close the keyboard, which makes sense for us to do. Bind an event to each reply and make input focus when clicked, as shown below

  

 1 <div className="comment-resquetion"OnClick ={this.changeparent. bind(this, comment.comment)}> 2 ChangeparentComment (val) {6let commentInput = document.querySelector('#commentInput')
 7         commentInput.focus()
 8         this.setState({
 9             parentComment: val
10         })
11     }Copy the code

This works on Android, but on ios there is a problem. Events that are not triggered by input cannot invoke the keyboard, which is similar to window.open’s restriction. Only active actions by the user can invoke the keyboard, so this is not possible.

In this case, we can be opportunistic, since it has to be an input triggered operation, so I’ll just use a transparent input at the top of the reply.

  

1 <div className="comment-resquetion"OnClick ={this.changeparent.bind (this, comment.comment)}> Reply <inputtype='text' className='hide-input'/></div>Copy the code

The CSS style is as follows:

.comment-resquetion{ position: relative; The font - size: 0.28 rem; color:#3E93C2;letter-spacing: -1px; The line - height: 0.45 rem; Padding: 0.05rem 0 0.15rem 0.32rem; } .hide-input{ position: absolute; width: 100%; Height: 0.28 rem; opacity: 0; z-index: 1000; Left: 0.32 rem; top: 0; }Copy the code

When you click reply, you actually click Input, so you can avoid the restriction of invoking the soft keyboard.

3.3 Closing the Keyboard

At this point, I thought that was the end of it, but it turned out that there was also a problem. The keyboard couldn’t be hidden when clicking on the soft keyboard to submit, which was a bit embarrassing, because after clicking on the submit button, there was no active folding of the keyboard. Because the IO user is still typing on the soft keyboard, the keyboard will not be folded up. If you click the button next to the keyboard to submit, it will be folded up automatically. Since it cannot be retracted actively, we have to manually force it. After the submission event returns, we can manually remove the focus. It is better to make a delay here, otherwise the experience will be too fast.

1 this.commentInput = document.querySelector('#commentInput'2)setTimeout(() => {3 this.props. ChangeParent (null) 6}, 500)Copy the code

At this point, this seemingly small function has finally come to an end. It is necessary to make a summary for myself and other students who need to do a reference.

Reference article:

Efe.baidu.com/blog/mobile…