努力寫完文章按下儲存卻跳出404錯誤,文章不見了ㅠㅠ
在開發行動網頁時遇到的兩個惱人的跨瀏覽器問題,以及其他需要考慮的問題
瀏覽器本身的位址列和導覽列造成的視窗高度計算問題
Safari和Samsung Internet本身就具有底部的導覽列。除非特別設定show/hide,否則向下捲動時會出現,向上捲動時會消失。
問題是,由於這些導覽列的存在,視窗高度並非固定,而是會改變。
例如,如果將高度設定為100vh,在沒有導覽列時,佈局會準確顯示;但導覽列出現時,導覽列就會遮擋UI。
dvh是動態視窗高度單位,視窗高度改變時會自動反映變化。因此,可以應對位址列或底部導覽列的有無而造成的UI佈局改變。
svh是指不包含位址列或導覽列的純UI區域高度。在預期位址列或導覽列會出現的情況下,使用svh會更準確。
選擇input時,虛擬鍵盤造成UI偏移的問題
在行動版Safari中,選擇input時,虛擬鍵盤會造成既有的UI元素偏移。在其他瀏覽器中,虛擬鍵盤通常會以absolute方式顯示,但在Safari行動網頁中,它看起來像是應用display block一樣佔用了空間。
Safari在虛擬鍵盤彈出時會動態調整視窗高度,導致使用vh單位的元素重新調整,從而產生問題。要解決這個問題,
html, body {
height: 100%;
min-height: 100vh; /* 設定固定的最小高度 */
overflow: hidden;
}
html, body {
height: -webkit-fill-available; /* 支援Safari */
}
window.addEventListener('resize', () => {
if (window.innerHeight < 500) {
// 鍵盤彈出時執行的程式碼
document.body.classList.add('keyboard-visible');
} else {
// 鍵盤收起時執行的程式碼
document.body.classList.remove('keyboard-visible');
}
});
監聽resize事件以偵測視窗高度變化,並應用適當的樣式。
document.querySelectorAll('input, textarea').forEach(element => {
element.addEventListener('focusin', () => {
setTimeout(() => {
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
}, 100);
});
});
3-2. 虛擬鍵盤出現時控制位置。(以下範例中應用class)
let originalHeight = window.innerHeight;
window.addEventListener('resize', () => {
if (window.innerHeight < originalHeight) {
// 虛擬鍵盤彈出狀態
document.body.classList.add('keyboard-visible');
} else {
// 虛擬鍵盤收起狀態
document.body.classList.remove('keyboard-visible');
}
});
我使用3-1的方法解決了問題。如果3-1方法無法如預期般運作,請先使用以下程式碼確認是否符合預期。
window.addEventListener('focusin', () => {
setTimeout(()=> {
window.scrollTo(0,0)
}, 100);
})
其他
此外,還搜尋了一些在Safari開發行動網頁時需要考慮的事項。
* 供應商前綴是讓瀏覽器理解並渲染特定CSS屬性的前綴,讓不同瀏覽器以不同方式實現的CSS能按照預期生效。藉此,可以確保不同瀏覽器之間的一致性,並與舊版瀏覽器保持相容性。
-webkit-:Chrome、Safari等
-moz-:Mozilla Firefox
-ms-:Internet Explorer和Edge
-o-:Opera
.container {
display: -webkit-flex; /* Safari */
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
}
.item {
-webkit-flex-grow: 1; /* Safari */
flex-grow: 1;
-webkit-flex-shrink: 1; /* Safari */
flex-shrink: 1;
}
.grid-container {
display: -ms-grid; /* IE11和舊版瀏覽器 */
display: grid; /* 最新瀏覽器 */
}
.sticky-element {
position: -webkit-sticky; /* Safari */
position: sticky;
}
input[type="text"],
select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
此外,Safari將LocalStorage和SessionStorage的容量限制在約5MB,並且各個分頁之間不共享儲存空間,因此需要注意。
ps. 原本寫好的文章不見了,太難過了。雖然我發表的文章質量不高……ㅠ一定要養成儲存草稿的習慣。