I. Problem description
Premise: a mobile page filled with input fields
Operation: When the cursor is positioned on a text box, the soft keyboard automatically pops up. If no action is taken, the soft keyboard may block the text box near the bottom.
Second, try to solve
Let’s start with two apis:
If you want to see the results, you can ignore this part!
scrollIntoView()
:
Note: MDN says this is an experimental feature, so be careful when using it.
Action: () scrolls the current element into the viewable area of the browser window.
There are two types of parameter types, the first type is Boolean, the second type is Object type, this type of parameter is experimental stage, not to mention, interested in MDN to see
When true, the top of the element is aligned with the top of the visible area of the scroll area in which it is located. When false, the bottom of the element is aligned with the bottom of the visible area of the scroll area in which it is located
Pay special attention to the sentence at the bottom of the document:
Depending on the layout of other elements, this element may not scroll all the way to the top or bottom.
(I was fooled by this one…)
scrollIntoViewIfNeeded()
MDN says that this is not a non-standard method and is not recommended for production
This feature is non-standard, so try not to use it in production!
Function:
The scroll () method is used to scroll elements that are not in the visible area of the browser window to the visible area of the browser window. If the element is already in the visible area of the browser window, no scrolling occurs. This method is a proprietary variant of the standard element.scrollintoView () method.
Here is an attempt to solve the problem using the above two apis, the code is as follows:
const u = navigator.userAgent; If (u.i ndexOf (' Android ') > 1 | | u.i ndexOf (' Linux ') > 1) {/ / Android mobile phone window. AddEventListener (' resize, Function () {// The activeElement property of the Document object returns the element currently in focus in the Document. If (document. ActiveElement. TagName = = = 'INPUT' | | document. ActiveElement. TagName = = = 'TEXTAREA') {the console. The log (' android trigger, document.activeElement.tagName) window.setTimeout(function() { // document.activeElement.scrollIntoView(true); // document.activeElement.scrollIntoView(false); //document.activeElement.scrollIntoViewIfNeeded(); }, 300); }})}Copy the code
After reading the explanation on the official website, I tried one by one with a little doubt, but the results were not as good as I expected. Sometimes they exceeded, and sometimes they were blocked, as shown in the picture below
Try way 1:
scrollIntoView(true); It didn’t scroll into the viewable area, but it did scroll up, just didn’t take into account the head element at the top of the fixed, so it was abandoned.
Figure 1:
Try method 2:
scrollIntoView(false); It did not scroll to the visible area, but it did scroll to the bottom from the effect, but it did not take into account the element of the button at the bottom of the fixed, so it was abandoned.
Figure 2:
Three ways to try:
The scrollIntoViewIfNeeded API is good and bad at times. The first time it is good, the cursor is blocked by the soft keyboard when it returns to the first text box after an operation on the current page. And then abandoned it.
Third, find another way out
Since the existing API provided is not enough, you can find your own way… Here is the layout of the current page :(don’t ask why, I don’t know why because of the ancestral code…)
The top and bottom buttons are fixed and the middle part is position and the height is 100%
.header { position: fixed; top: 0px; left: 0px; } .content { position: abslute; top: 45px; // Header height left: 0px; } .footer { position: fixed; bottom: 0px; left: 0px; }Copy the code
- Requirement analysis: What we need to do is very simple, in fact, when the cursor is located in the current text box, let it scroll to the top, and subtract the height of the header element position. When you lose the cursor, roll it back to its original position.
- solutionNow that we have an idea, we can add one for each textbox
focus
andblur
Events whenfocus
When, the scrolling height = the height of the text box from the top – the height of the head, whenblur
When you lose focus, set the scrolling height to 0.
Of course, input pulls out a component, just add one to add these two events to the component.
The code is as follows:
Function addInputTop(Event, Content) {var input = event.srcElement // The height of the current text box from the top minus 45 is the height of the header, of course, Here can also minus the height of the dynamic calculation var. Top = input getBoundingClientRect (). The top - 45 var current = document. QuerySelector ('. '+ content) / / Current. ScrollTo (0, top)} function removeInputTop(event, content) { var current = document.querySelector('.' + content) current.scrollTo(0, 0) }Copy the code
Note: The getBoundingClientRect() method returns an object containing the current dom element’s distance up, down, left, and right. GetBoundingClientRect is also an experimental feature, but compatibility is good
So far, done, and good compatibility! The first time to discover gold, if there is a mistake still hope you correct.