簡體   English   中英

iOS Safari/Chrome - 在模態內聚焦輸入時不需要滾動

[英]iOS Safari/Chrome - Unwanted scrolling when focusing an input inside the modal

在 Safari 和 Chrome 中測試 - 結果相同,所以我認為這是 iOS 問題。

僅當模態中有輸入並且我點擊該輸入時才會發生這種情況。 在輸入獲得焦點的同時,原生 iOS 鍵盤變得可見。

同一時刻模態下方的頁面會自動滾動到其高度的 50%。 這種行為是完全不需要的,我不知道如何阻止這個默認的 iOS“功能”。

演示:

在此處輸入圖片說明

只是在這里添加一個答案,以防人們偶然發現這個問題( 而不是你的另一個問題,它有一個很好的演示來說明這個問題

我們在工作中也面臨着類似的問題。 正如您所提到的,偏移量始終是頁面高度的 50%,無論您的初始偏移量在哪里,都會發生這種情況。

過去,當我在早期的 iO​​S 版本中觀察到類似的“跳躍”(盡管跳躍不那么劇烈)時,我通常通過將position: fixed (or relative ) 應用到body這允許overflow: hidden to正常工作)。

但是,如果用戶向下滾動,這會導致用戶跳回頁面頂部的無人值守后果。

所以,如果你願意用一些JavaScript解決這個問題,這里有一個修復/黑客我已經拋出:

// Tapping into swal events
onOpen: function () {
  var offset = document.body.scrollTop;
  document.body.style.top = (offset * -1) + 'px';
  document.body.classList.add('modal--opened');
},
onClose: function () {
  var offset = parseInt(document.body.style.top, 10);
  document.body.classList.remove('modal--opened');
  document.body.scrollTop = (offset * -1);
}

以及 CSS 的樣子:

.modal--opened {
  position: fixed;
  left: 0;
  right: 0;
}

這是您的演示頁面的一個分支(來自您的其他問題),以說明: https : //jpattishall.github.io/sweetalert2/ios-bug.html

對於那些正在尋找更通用修復的人,您可以在打開/關閉模態時執行以下操作:

function toggleModal() {
    var offset;
    if (document.body.classList.contains('modal--opened')) {
        offset = parseInt(document.body.style.top, 10);
        document.body.classList.remove('modal--opened');
        document.body.scrollTop = (offset * -1);
    } else {
        offset = document.body.scrollTop;
        document.body.style.top = (offset * -1) + 'px';
        document.body.classList.add('modal--opened');
    }
}

編輯:為了避免台式機上的“移動/取消移動”,我建議功能檢測/ ua 嗅探將其僅應用於移動 safari。

我也遇到過這個問題。 一個簡短的解釋是,iOS Safari 將嘗試自動滾動到任何聚焦的輸入,在這種特殊情況下,聚焦元素位於固定定位元素內。 當 Safari 想要將元素在屏幕上居中時,它似乎很難找到固定位置元素,從而導致背景滾動。

一種可能的解決方法是在輸入字段中添加一個touchstart事件偵聽器並計算疊加層的當前位置,將定位更改為絕對位置並更新頂部/左側位置以在固定定位時將疊加層放回屏幕上的位置,最后添加一個新的blur偵聽器,以在輸入上留下焦點/模糊時將覆蓋重置回固定位置。 這應該可以防止頁面滾動。 我建議使用touchstart因為它應該在focus事件之前觸發,在這種情況下頁面已經開始滾動。 當觸發focus事件時,Safari 應該能夠找到絕對定位的疊加層並將其居中。

所以我已經解決了這個問題並在我的 Iphone 5 上進行了測試,沒有 Ipad 來檢查。 我已禁用overflow:hidden在我的解決方案中,您可以添加,如果您想為所有模式禁用全部滾動。 解決方案是向 html 和 body 元素添加基本的 height 和 position 屬性。

html, body {
   position:relative;
   /*overflow:hidden;*/
   height: 100%;
}

所以,只有當你專注於輸入時,高度和位置才會被定義,我已經從你的倉庫中編寫了這個解決方案,我會向你發送拉取請求。 我還在你的 gulp 設置中添加了 browserSync。 因此,現在可以輕松地在任何設備上進行測試。

干杯!

編輯:另一種方式,如果上述解決方案由於某種原因不起作用。 然后,

 /*
  * @summary touch handler; will remove touch ability
  * @author yeomann
  */
  function Touchyhandler(e) {
    e.preventDefault();
  }

然后務實地添加和刪除這樣的觸摸監聽器

//to add
document.addEventListener('touchmove', Touchyhandler, false); 
//to remove   
document.removeEventListener('touchmove', Touchyhandler);

以上在 IOS 9.3.2 上測試的 js 解決方案對我來說就像魅力一樣]

為了阻止頁面在 x 軸和 y 軸上滾動,我們使用了overflow: hidden; css中的屬性。

所以如果我們把這個應用到身體上

body {
    overflow: hidden !important;
}

它應該正常工作嗎?

事實上,這實際上是行不通的,因為您只是一直禁用整個頁面的 x 和 y 滾動。

為了繞過這一點,我們可以在模態處於活動狀態時使用一點 javascript 向主體添加一個類。

首先,我們必須為我們的身體添加一個 id, <body id="body">這允許 javascript 識別身體。

其次,我們必須為我們的模態添加一個 id, <div id="modal"> ,也允許 javascript 識別模態。

<script type="text/javascript">
    function modalActive() {
        if (document.getElementById("modal").classList.contains("active")) {
            document.getElementById("body").classList.add("modal-active");
        } else {
            getElementById("modal").classList.remove("active"));
            getElementById("body").classList.remove("modal-active"));           
        }
    }
</script>

對於啟動和關閉模式的按鈕,我們必須添加一個 onclick 事件,

<button onclick="modalActive()">Click Me!</button>

最重要的是,我們必須將其添加到 css 文件中。

body {
    overflow: initial !important;
}

body.modal-active {
    overflow: hidden !important;
}

我們走了。

我不是 100% 確定,但我可以想象以下內容:

當鍵盤出現時,窗口高度降低,但是scrollTop值還是一樣,所以站點跳轉到那個值。 當模態打開時,您可以將overflow:hidden添加到body 這將阻止在模態“后面”滾動並可能解決您的問題。

我嘗試了多種方法,這些方法適用於 html 頁面上的彈跳模式輸入。 對我有用的最簡單的解決方案在頁面上打開模態時body 標記添加以下樣式。

position: fixed;
width: 100%;

添加此元 ( maximum-scale=1, minimum-scale=1 ) 以重置滾動,這是在聚焦輸入字段時發生的。

升級到 iPadOS 13 后我遇到了這個問題。我不得不刪除以下舊的 JavaScript 代碼,這是修復舊版本中不同的滾動問題所必需的:

function fixIpadKeyboardScrolling() {
   if ((Device.is("ipad") || Device.is("iphone"))) {
    console.log("Fixing iPad/iPhone floating bar bug");
    var inputs = document.getElementsByTagName("input");
    if (inputs.length) {
      for (var i = inputs.length - 1; i >= 0; i--) {
        addListener(inputs[i], "blur", function () {
          setTimeout(function () {
              window.scrollTo(document.body.scrollLeft, document.body.scrollTop);
          }, 0);
        });
      }
    }
    console.log(inputs.length + " input controls where edited to fix keyboard scrolling");
  }
}

如果您在升級后突然遇到此問題,您的應用程序可能應用了類似的代碼。

就我而言,我添加了對 safari mobile 13 版本的檢測,並且只運行低於該版本的腳本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM