Safari in ios8 is scrolling screen when fixed elements get focus

前端 未结 12 1095
失恋的感觉
失恋的感觉 2020-12-12 11:24

In IOS8 Safari there is a new bug with position fixed.

If you focus a textarea that is in a fixed panel, safari will scroll you to the bottom of the page.

T

12条回答
  •  轮回少年
    2020-12-12 11:45

    The best solution I could come up with is to switch to using position: absolute; on focus and calculating the position it was at when it was using position: fixed;. The trick is that the focus event fires too late, so touchstart must be used.

    The solution in this answer mimics the correct behavior we had in iOS 7 very closely.

    Requirements:

    The body element must have positioning in order to ensure proper positioning when the element switches to absolute positioning.

    body {
        position: relative;
    }
    

    The Code (Live Example):

    The following code is a basic example for the provided test-case, and can be adapted for your specific use-case.

    //Get the fixed element, and the input element it contains.
    var fixed_el = document.getElementById('b');
    var input_el = document.querySelector('textarea');
    //Listen for touchstart, focus will fire too late.
    input_el.addEventListener('touchstart', function() {
        //If using a non-px value, you will have to get clever, or just use 0 and live with the temporary jump.
        var bottom = parseFloat(window.getComputedStyle(fixed_el).bottom);
        //Switch to position absolute.
        fixed_el.style.position = 'absolute';
        fixed_el.style.bottom = (document.height - (window.scrollY + window.innerHeight) + bottom) + 'px';
        //Switch back when focus is lost.
        function blured() {
            fixed_el.style.position = '';
            fixed_el.style.bottom = '';
            input_el.removeEventListener('blur', blured);
        }
        input_el.addEventListener('blur', blured);
    });
    

    Here is the same code without the hack for comparison.

    Caveat:

    If the position: fixed; element has any other parent elements with positioning besides body, switching to position: absolute; may have unexpected behavior. Due to the nature of position: fixed; this is probably not a major issue, since nesting such elements is not common.

    Recommendations:

    While the use of the touchstart event will filter out most desktop environments, you will probably want to use user-agent sniffing so that this code will only run for the broken iOS 8, and not other devices such as Android and older iOS versions. Unfortunately, we don't yet know when Apple will fix this issue in iOS, but I would be surprised if it is not fixed in the next major version.

提交回复
热议问题