前兩天在測試新遊戲 HTML5 FUN Make 10 時,發現在 iPad 4 的 iOS 10.3.4 居然不能玩!研究半天,找到讓程式卡住的地方是監聽畫面動態的「ResizeObserver」,iOS 10.3.4 不支援,只好多加幾行,讓它改用傳統監聽「resize」事件的方法。以為從此就可以過著幸福快樂的日子了嗎?
來看看 Make 10 正常的畫面應該像 [圖1] 這樣:
![]() |
| [圖1] 正常排列的 Make 10 按鈕 |
結果在 iOS 10.3.4 中是 [圖2] 這樣,全部疊成一排:
![]() |
| [圖2] iOS 10.3.4 中全部疊在一起 |
Make 10 中的數字方塊使用了 grid 來配置按鈕棋盤:
.board-grid {
display: grid;
grid-template-columns: repeat(8, 1fr);
grid-template-rows: repeat(6, 1fr);
gap: 1%;
width: 100%;
height: 100%;
}
設計的是 8 x 6 的棋盤,在 iOS 10.3.4 中,8欄有正常分配了,6 排卻疊成一排。本來以為 iOS 10.3.4 不支援 repeat function,但實際用 getComputedStyle 取得 grid-template-rows 的值,它有執行 repeat(6, 1fr) ,只是回傳的值是「0px 0px 0px 0px 0px 0px」,分成六份了,但每一份都是 0px。
原來關鍵在 iOS 10.3.4 的 repeat 在計算寬度時,有正確解讀「width: 100%」,而在計算高度時,「height: 100%」使用了百分比,並沒有被正確解讀。如果換成別的單位,例如「height: 100vh」,就不會疊成一排了。
找到原因了,在 resize 的監聽程序中,加入程式計算高度即可,取得棋盤容器的總高,扣掉不能使用的空間,再將「height: 100%」最後用 px 的單位來設定。
不過,怎麼知道哪一個人用了像 iOS 10.3.4 這樣, repeat 有缺陷的瀏覽器呢?
本來是用前面提到的「0px 0px 0px 0px 0px 0px」,以按鈕的高度為 0 來判斷,但是這樣的方法只能在一進入遊戲時用,如果使用者旋轉了裝置或是讓視窗尺寸有所改變時,就無法再重新自動設定格子大小了。後來發現「gap: 1%;」這個也是個線索,因為 iOS 10.3.4 並不支援「gap」,所以用 getComputedStyle 取得的 gap 會是 undefined ,這個特性剛好可以用判斷是否為 iOS 10.3.4。
來看一下修改過後的畫面:
![]() |
| [圖3] 不使用 % 設定高度後的棋盤 |
套上修正方法後的 [圖3] ,和原始設計的 [圖1] 比較,可以看到 [圖3] 格子與格子沒有間隔,所以格線看不出來;不過修正過後,至少在 iOS 10.3.4 中可以玩 Make 10 了!
▋ 完美修正
還是不能接受「gap: 1%;」沒被 iOS 10.3.4 處理到,那怎麼辦?
把 1% 到底是多少算出來,然後將所有格子找出來設定它們的 width 和 height 為 calc(100% - gap) 就可以有 1% 的間隔了,底下是實作的程序:
function gridRepeatFix() {
const boardGrid = document.querySelector('.board-grid');
if (boardGrid) {
if (typeof getComputedStyle(boardGrid)['gap'] == 'undefined') {
const style = getComputedStyle(boardGrid.parentElement);
let height = parseFloat(style.height);
height -= parseFloat(style.paddingTop);
height -= parseFloat(style.paddingBottom);
const gap = Math.floor(height * 0.01);
boardGrid.style.height = Math.floor(height) + 'px';
Array.from(boardGrid.children).forEach(cell => {
cell.style.width = `calc(100% - ${gap}px)`;
cell.style.height = `calc(100% - ${gap}px)`;
});
}
}
}
▋ 相關連結



沒有留言:
張貼留言