如何从这样的移动时,虚拟键盘在移动Safari浏览器中打开停止我的固定导航?(How do I st

2019-07-21 04:12发布

据我所知,移动Safari浏览器有很多周围的固定元素的bug,但在大多数情况下,我设法让我的布局正常工作,直到我说了急需的文本输入到在底部的固定导航。 现在,当用户集中在文本输入元素上,并显示虚拟键盘,我的导航,这是否则,始终固定在页面的底部,跳起来在页面的中间,真是奇怪的地方。

我想补充一些我的代码,这个职位,但我也不会知道从哪里开始。 即导航被固定在底部和位于左侧和底部0和100%的宽度。 从那里,我不知道发生了什么,我只能假设这是一个移动Safari浏览器的bug。

这似乎也失去了它的位置固定,并成为相对的,仅在文本输入元素是专注于和虚拟键盘是开放的。

Answer 1:

http://dansajin.com/2012/12/07/fix-position-fixed/这是所提出的解决方案之一。 似乎是值得一试。

简而言之:设置fixed元件position:absolute时任何输入是focus ED和重置它们时元件被blur红色

.header { 
    position: fixed; 
} 
.footer { 
    position: fixed; 
} 
.fixfixed .header, 
.fixfixed .footer { 
    position: absolute; 
} 

if ('ontouchstart' in window) {
    /* cache dom references */ 
    var $body = $('body'); 

    /* bind events */
    $(document)
    .on('focus', 'input', function() {
        $body.addClass('fixfixed');
    })
    .on('blur', 'input', function() {
        $body.removeClass('fixfixed');
    });
}


Answer 2:

顶部的解决方案有一些方法去解决这个问题,但我想添加额外的CSS类或使用我们事情复杂现代化建设的。

如果你想有一个更简单的解决方案,这里是一个非Modernizr的 非超CSS但纯jQuery的解决方案和工作的每个设备和浏览器我用这个修复我的所有项目上

if ('ontouchstart' in window) {
    $(document).on('focus', 'textarea,input,select', function() {
        $('.navbar.navbar-fixed-top').css('position', 'absolute');
    }).on('blur', 'textarea,input,select', function() {
        $('.navbar.navbar-fixed-top').css('position', '');
    });
}


Answer 3:

我有一个类似的问题,但我发现了一个解决方法中加入以下CSS类body元素的输入焦点,然后再以无焦点将其取出:

.u-oh {
    overflow: hidden;
    height: 100%;
    width: 100%;
    position: fixed;
}


Answer 4:

从什么sylowgreen没有考虑,关键是修复body在进入input 。 从而:

$("#myInput").on("focus", function () {
    $("body").css("position", "fixed");
});

$("#myInput").on("blur", function () {
    $("body").css("position", "static");
});


Answer 5:

添加JavaScript这样的:

$(function() {
  var $body;
  if ('ontouchstart' in window) {
    $body = $("body");
    document.addEventListener('focusin', function() {
      return $body.addClass("fixfixed");
    });
    return document.addEventListener('focusout', function() {
      $body.removeClass("fixfixed");
      return setTimeout(function() {
        return $(window).scrollLeft(0);
      }, 20);
    });
  }
});

并添加类是这样的:

.fixfixed header{ 
    position: absolute; 
} 

你可以参考这篇文章: http://dansajin.com/2012/12/07/fix-position-fixed/



Answer 6:

我真的很喜欢上面的解决方案。 我打包起来成为一个小的jQuery插件,所以我可以:

  • 一套父获取类
  • 设置这适用于(不要忘了“文本区域”和“选择”)的元素。
  • 设置父类的名字是什么
  • 允许它被链接
  • 允许它被多次使用

代码示例:

$.fn.mobileFix = function (options) {
    var $parent = $(this),
    $fixedElements = $(options.fixedElements);

    $(document)
    .on('focus', options.inputElements, function(e) {
        $parent.addClass(options.addClass);
    })
    .on('blur', options.inputElements, function(e) {
        $parent.removeClass(options.addClass);

        // Fix for some scenarios where you need to start scrolling
        setTimeout(function() {
            $(document).scrollTop($(document).scrollTop())
        }, 1);
    });

    return this; // Allowing chaining
};

// Only on touch devices
if (Modernizr.touch) {
    $("body").mobileFix({ // Pass parent to apply to
        inputElements: "input,textarea,select", // Pass activation child elements
        addClass: "fixfixed" // Pass class name
    });
}


Answer 7:

我用这个jQuery脚本:

var focus = 0;
var yourInput = $(".yourInputClass");
yourInput.focusin(function(){
    if(!focus) {
        yourInput.blur();
        $("html, body").scrollTop($(document).height());
        focus = 1;
    }
    if(focus) {
        yourInput.focus();
        focus = 0;
    }
});

完全为我工作。



Answer 8:

focusinfocusout的事件似乎更适合这个问题不是focusblur事件,因为前者泡沫达根元素。 见这个答案的SO。

我个人使用AngularJS,所以我实现它是这样的:

$window.document.body.addEventListener('focusin', function(event) {
    var element = event.target;
    var tagName = element.tagName.toLowerCase();
    if(!$rootScope.inputOverlay && (tagName === 'input' || tagName === 'textarea' || tagName === 'select')) {
        $rootScope.$apply(function() {
            $rootScope.inputOverlay = true;
        });
    }
});
$window.document.body.addEventListener('focusout', function() {
    if($rootScope.inputOverlay) {
        $rootScope.$apply(function() {
            $rootScope.inputOverlay = false;
        });
    }
});

注:我有条件地运行此脚本,如果这是移动Safari浏览器。

我把一个ng-class属性上我的导航栏:

<div class="navbar navbar-default navbar-fixed-top" ng-class="{'navbar-absolute': inputOverlay}">

使用下面的CSS:

.navbar-absolute {
    position: absolute !important;
}

你可以阅读更多有关focusin 这里和focusout 在这里 。



Answer 9:

测试这一项。 有用。 我只是测试它。

$(document).on('focus','input', function() {
    setTimeout(function() {
        $('#footer1').css('position', 'absolute');
        $('#header1').css('position', 'absolute');
    }, 0);
});
$(document).on('blur','input', function() {
    setTimeout(function() {
        $('#footer1').css('position', 'fixed');
        $('#header1').css('position', 'fixed');
    }, 800);
});


Answer 10:

这些解决方案都没有工作对我来说,因为我的DOM是复杂的,我有动力无限滚动页面,所以我不得不创建我自己的。

背景:我使用固定报头和那支下方一旦用户滚动远远向下的元件进一步向下。 这个元素有一个搜索输入字段。 此外,我不得不在前进添加动态页面和向后滚动。

问题:在iOS系统中,任何时候用户点击的固定元素的输入,浏览器将滚动一路到页面的顶部。 这不仅造成了意外的行为,这也触发了我的动态页面添加在页面的顶部。

预期解决方案:在IOS没有涡旋(根本没有),当用户点击在粘元件的输入端。

解:

     /*Returns a function, that, as long as it continues to be invoked, will not
    be triggered. The function will be called after it stops being called for
    N milliseconds. If `immediate` is passed, trigger the function on the
    leading edge, instead of the trailing.*/
    function debounce(func, wait, immediate) {
        var timeout;
        return function () {
            var context = this, args = arguments;
            var later = function () {
                timeout = null;
                if (!immediate) func.apply(context, args);
            };
            var callNow = immediate && !timeout;
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
            if (callNow) func.apply(context, args);
        };
    };

     function is_iOS() {
        var iDevices = [
          'iPad Simulator',
          'iPhone Simulator',
          'iPod Simulator',
          'iPad',
          'iPhone',
          'iPod'
        ];
        while (iDevices.length) {
            if (navigator.platform === iDevices.pop()) { return true; }
        }
        return false;
    }

    $(document).on("scrollstop", debounce(function () {
        //console.log("Stopped scrolling!");
        if (is_iOS()) {
            var yScrollPos = $(document).scrollTop();
            if (yScrollPos > 200) { //200 here to offset my fixed header (50px) and top banner (150px)
                $('#searchBarDiv').css('position', 'absolute');
                $('#searchBarDiv').css('top', yScrollPos + 50 + 'px'); //50 for fixed header
            }
            else {
                $('#searchBarDiv').css('position', 'inherit');
            }
        }
    },250,true));

    $(document).on("scrollstart", debounce(function () {
        //console.log("Started scrolling!");
        if (is_iOS()) {
            var yScrollPos = $(document).scrollTop();
            if (yScrollPos > 200) { //200 here to offset my fixed header (50px) and top banner (150px)
                $('#searchBarDiv').css('position', 'fixed');
                $('#searchBarDiv').css('width', '100%');
                $('#searchBarDiv').css('top', '50px'); //50 for fixed header
            }
        }
    },250,true));

要求:必须为startsroll和stopscroll职能工作jQuery Mobile的。

去抖动被包括以平滑掉由粘元件创建的任何滞后。

经测试,在iOS10。



Answer 11:

我没有与丹洒进提出的解决方案的任何运气。 也许是因为他写的博客文章错误有所改变,但在iOS 7.1中,当位置改变回输入模糊后修复了这一错误总是会浮出水面,即使你延迟,直到该软件键盘完全隐藏。 该解决方案我来包括等待touchstart事件,而不是blur的事件,因为当页面滚动的固定元素总是推到合适的位置。

if (Modernizr.touch) {
  var $el, focused;
  $el = $('body');
  focused = false;
  $(document).on('focus', 'input, textarea, select', function() {
    focused = true;
    $el.addClass('u-fixedFix');
  }).on('touchstart', 'input, textarea, select', function() {
    // always execute this function after the `focus` handler:
    setTimeout(function() {
      if (focused) {
        return $el.removeClass('u-fixedFix');
      }
    }, 1);
  });
}

HTH



文章来源: How do I stop my fixed navigation from moving like this when the virtual keyboard opens in Mobile Safari?