Issue an overview

Today, I had a problem. On my Android phone, when I wanted to input “store name”, the soft keyboard popped up and just blocked the input field. Block even, the key is that the page can not slide up, the entire phone window was pressed to the original half or so;

    

then

Then I found some solutions, but they were not applicable, or they were troublesome; So we need to integrate, first of all, let me think about what I want to achieve

What you want to achieve

    

The first step, make the screen small, page content can scroll view

As shown below, the black box represents the screen and the blue box represents the page size. When the screen is pressed down, the page content must remain the original height:

As soon as the page comes in, I get the height of the window, and set a minimum height for the outermost div, so that even if the window pressure is small, the page can still maintain the original height.

      let initWindowHeight=window.innerHeight
      let wrapDiv=document.getElementsByClassName('animated-router-forward-enter-done')[0]
      wrapDiv.style.minHeight =initWindowHeight+'px'
Copy the code

Step two, roll to the red line

(2018/9/3 Supplement: About the second step, the comments section has more simple realization method) because we cannot know when soft keyboard directly to come out, but he got out of the soft keyboard window height will narrow, so we can use to monitor events to determine whether the soft keyboard pop-up window size change, such as the height of the browser window suddenly shrink by more than 25%, Then we get the focus input distance from the top of the page and calculate how far it is from the red line. Let’s say the distance is 60, then we scroll the page up 60, and the input is just right at the red line.

  window.onresize=function() {if(initWindowHeight-window.innerHeight>initWindowHeight/4&&document.querySelectorAll(':focus').length>0){//offset is an encapsulated method of getting the scrolling distance of an element from the top of the pageif(offset(document.querySelectorAll(':focus')[0]).top>initWindowHeight/4){
             document.body.scrollTop=offset(document.querySelectorAll(':focus')[0]).top-initWindowHeight/4
           }
        }else if(window.innerHeight-initWindowHeight<20){
            document.body.scrollTop=0
        }
        
    };
Copy the code

The complete code

Since there can be multiple pages to call, I put the code in a separate JS file:

function pageInputScroll() {
    
    let initWindowHeight=window.innerHeight
    setTimeout(() => {
      let wrapDiv=document.getElementsByClassName('animated-router-forward-enter-done')[0]
      //console.log(wrapDiv.style)
      wrapDiv.style.minHeight =initWindowHeight+'px'}, 500); Onresize =? Onresize =? Onresize =function(){// If the height of the browser window is reduced by more than 25%, the soft keyboard is outif(initWindowHeight-window.innerHeight>initWindowHeight/4&&document.querySelectorAll(':focus').length>0){
           if(offset(document.querySelectorAll(':focus')[0]).top>initWindowHeight/4){
             document.body.scrollTop=offset(document.querySelectorAll(':focus')[0]).top-initWindowHeight/4
           }
        }else if(window.innerHeight-initWindowHeight<20){
            document.body.scrollTop=0
        }
        
    };
}
function offset(element) {
    var offest = {
        top: 0,
        left: 0
    };
 
    var _position;
 
    getOffset(element, true);
 
    returnoffest; // Use getBoundingClientRect to recursively obtain offsetfunctionGetOffset (node, init) {// Non-element terminates recursionif(node.nodeType ! = = 1) {return;
        }
        _position = window.getComputedStyle(node)['position']; // position=static: continue recursive parent nodeif (typeof(init) === 'undefined' && _position === 'static') {
            getOffset(node.parentNode);
            return; } offest.top = node.offsetTop + offest.top - node.scrollTop; offest.left = node.offsetLeft + offest.left - node.scrollLeft; // position = fixed: exit recursion after obtaining the valueif (_position === 'fixed') {
            return; } getOffset(node.parentNode); }}export {pageInputScroll};
Copy the code

Add js to the React page and call:

  import {pageInputScroll} from '.. /.. /util/pageInputScroll'.componentDidMount(){
       pageInputScroll()
   }
Copy the code

If you only want to use it on Android, you can add a judgment:

  if(/Android/i.test(navigator.userAgent)){
      pageInputScroll()
  }
Copy the code

Effect diagram

I’ll simulate the implementation in Google Chrome on PC:

note

The offset() method is a method that uses JS to implement offset() similar to jquery, see: native JS to implement offset method

  

  

Recommend: a can scan the barcode of commodities for commodity review small procedures

Welcome to scan code experience: