h5 小遊戲總結及踩坑記錄(全是乾貨~)

這是近期的一個 h5 項目,由於某些原因,預覽地址不能放出來。不過這不是重點,沒有 demo 不就可以好好看文章了嗎 哈哈哈~

文中提到的 pixi 是 pixiJs,精靈是 pixiJs 中的概念。閱讀本文假設你已經知道了這些東西,不過這在本篇文章中並沒有太多關於這個庫的內容

覺得這篇文章有幫助到自己,就讓它去收藏夾吃灰;覺得沒用或覺得寫的不好的,可以留下你的足跡;覺得我的代碼或文字可以改善的,咱們可以進行多人運動一起交流~

下面就開始正經的東西了:

適配方案

這個項目裏用的是 rem 適配方案,通過計算 設備寬度/設計稿寬度 的比例,來設置 html 的 font-size 屬性,達到適配的目的,代碼如下:

function setSize() {
  // 設備寬度
  let deviceWidth = window.screen.width;
  // 設計稿寬度
  const baseValue = 750;
  // html的字體大小 = (設備寬度 / 設計稿寬度) * 100
  document.documentElement.style.fontSize = (deviceWidth / baseValue) * 100 + 'px';
}

// DOM樹加載完執行
window.addEventListener("DOMContentLoaded", function () {
  setSize();
})

// 屏幕變化就執行
window.addEventListener("resize", function () {
  setSize();
})

setSize();

資源的預加載

資源的預加載用的是 preloadjs

中文官網:http://www.createjs.cc/preloadjs

用法也是極其簡單:

  var queue = new window.createjs.LoadQueue(true);
  queue.on("complete", this.allLoadComplete);	// 所有文件加載完成時觸發
  queue.on("fileload", this.aloneLoadComplete);	// 單個文件加載完成時觸發
  queue.on("progress", this.fileProgress);	// 加載進度
  queue.loadManifest(allImg);	// 需要加載的資源數組
  queue.load();

如何解決需要引入很多圖片的問題

這裏用到了 webpack 的 api: require.context,當項目需要引入很多資源時,這項技術是必須要掌握的

可以閱讀 使用require.context自動導入ES模塊 - yeyan1996 這位大佬的文章,本文不做深入探討

如何實現換裝

如何讓人物換裝也是一個問題,經過嘗試後發現,直接切換精靈的 texture 可以達到這個目的

this.personContainers[key].children.map((item, index) => {
    if (item.type == type) {
      item.texture = loadSources[name].texture
    }
})

pixi 多個容器的排序問題

在 pixi 裏,要想動態的改變某個精靈或容器的層級,不能只改一個,,還需要把其他不相干的元素的層級設低

舉個栗子:

personContainers.map((item, i) => {
    item.zIndex = 0;	// 不相干的元素 層級設爲最低
    if (index == i) {
      item.zIndex = 99;	// 目標元素 層級設爲最高
    }
})

精靈的 touchend 事件移動時會失效

具體爲什麼會失效還不知道,我的解決方法是:在給精靈綁定一個 touchendoutside 事件

touchendoutside:觸摸開始、移出對象鬆開時觸發

html2canvas 截取頁面時圖片模糊

如果截取的區域裏有涉及到圖片,不要用 background 設置圖片,全部替換成 img 標籤

這樣可以大大提升圖片的清晰度

ios 鍵盤會把頁面頂上去 不會自動下來

問題描述:移動端 ios 鍵盤彈起後,會把頁面頂上去,輸入完成後頁面不會自動下來

解決辦法:

document.body.addEventListener('focusout', function () {
    window.scrollTo(0,0);
});

當監聽到 body 裏有元素失去焦點時,就把頁面滾上去

focusout: 當元素即將失去焦點時,focusout 事件被觸發。focusout 事件和 blur 事件之間的主要區別在於後者不會冒泡

—— MDN

如何監聽 textarea 的輸入

這個項目用了多行輸入框 textarea ,發現直接在標籤上加了監聽事件後啥也沒有…,後來找到了解決辦法:

this.$refs.textarea.addEventListener('input', e => {
	console.log(e.target.value);	// textarea 輸入的文字
}, false)

滑動加載以及獲取body實際高度的坑

滑動加載的關鍵就是如果頁面滑動到了底部,就進行數據的請求,要事先和後端溝通好數據怎麼返回

滑動到頁面底部的條件:滾動條離頂部的距離(document.body.scrollTop)+ 窗口的文檔顯示區的高度(window.innerHeight)>= 文檔實際高度(document.body.scrollHeight)

這裏有個坑,關於獲取文檔實際高度的:

document.body.scrollHeight 可以在手機上獲取到實際文檔高度,但在 chrome 裏獲取到的高度是 0

document.documentElement.scrollHeight 在 chrome 裏可以獲取到正常的,但在手機上獲取的高度是 0

這樣的話,還要判斷當前設備是手機還是 pc 然後再去獲取嗎,No No No,有個優雅的寫法:

// 獲取文檔實際高度/移動端
var bodyHeight = Math.max(
  document.documentElement.scrollHeight,
  document.body.scrollHeight
);

沒有把基礎的東西丟掉,此處應該有掌聲 [啪啪啪]

vscode 返回上一個編輯點

當代碼寫的像又臭又長的意大利式代碼時,需要去調試某個函數,發現另一個函數又有問題,看完之後還需要翻回來,這就很難頂了

後來發現了這個釋放雙手的快捷鍵 - 返回上/下一個編輯點:Alt + ←/→ (windows)

去除 iphone x 的小尾巴

大家管這玩意叫鬍子,我比較喜歡叫小尾巴~,就是 iphone x 下面那一根玩意

想要了解更多請點擊:https://imweb.io/topic/5baa38c279ddc80f36592efb

我在這裏就說說我是怎麼用的

meta 標籤里加上 viewport-fit=cover

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover" />

然後在底部的樣式里加上樣式:

bottom: env(safe-area-inset-bottom);
bottom: 0;	// 這一句也要加上 沒有小尾巴的機型需要用到這個樣式

這裏的 safe-area-inset-bottom 的意思是:在 Viewport底部的安全區域內設置量(CSS像素),更多方向看下圖

img

(ps: 圖片來源 https://imweb.io/topic/5baa38c279ddc80f36592efb 侵刪)

小程序跳轉頁面傳值的問題

小程序跳轉到其他組件時,如果需要帶網址這類的參數的話,記得要轉碼,不然是傳不過去滴

栗子:

let link = "https://www.baidu.com/"
wx.redirectTo({
  url: "/pages/index/index?url=" + encodeURIComponent(url),	// 解碼: decodeURIComponent
})

爲什麼要轉碼呢?

假設現在需要獲取用戶信息後傳個網址給 index 組件,這時候,這個鏈接裏是帶有中文或者其他符號的,如果不轉碼,小程序會覺得你這個不是個可以識別的地址,會直接把域名後面的值給你去掉

想要了解更多 轉/解碼 的知識請點擊:https://www.w3school.com.cn/js/jsref_encodeURIComponent.asp

ios 最新版系統 微信瀏覽器 html2canvas 生成圖片失敗

這個項目裏有個生成圖片的功能,需要保存用戶操作過的一些東西,其他設備都正常,唯獨 ios 最新版的系統有問題

debug 了一波後發現,這他瞄的根本沒有執行這個函數,找一半天也沒找到爲什麼,後來看 issues 發現有人說把版本換成 rc.4 的就可以了

issues:https://github.com/niklasvh/html2canvas/issues/2205

emoji 表情轉碼

項目測試的時候,發現 textarea 標籤裏可以輸入表情,緊接着,接口就報錯了,一查看,雖然支持輸入表情,但是不會自動對錶情轉碼,所以提交接口的時候報錯了,下面分享個 emoji 表情轉字符的方法:

// 表情轉字符
utf16toEntities(str) {
  var patt = /[\ud800-\udbff][\udc00-\udfff]/g // 檢測utf16字符正則
  str = str.replace(patt, function(char) {
    var H, L, code
    if (char.length === 2) {
      H = char.charCodeAt(0) // 取出高位
      L = char.charCodeAt(1) // 取出低位
      code = (H - 0xd800) * 0x400 + 0x10000 + L - 0xdc00 // 轉換算法
      return '&#' + code + ';'
    } else {
      return char
    }
  })
  return str
}

教訓

  • 全局事件卸載組件時一定要註銷事件
  • 自己寫的東西要多測幾遍
  • npm 包切換版本後要去文件裏看下是不是真的切換了

參考文章

  • 原生 js 監聽 textarea 的輸入 - https://www.jianshu.com/p/66c205c6ef63
  • 移動端獲取全文高度 - https://www.cnblogs.com/xiaomingBlog/p/7822937.html
  • 資源預加載 - http://www.createjs.cc/preloadjs
  • pixi 精靈排序問題 - https://www.cnblogs.com/afrog/p/4056378.html
  • 移動端 ios 軟鍵盤收起時頁面不見了 - https://www.cnblogs.com/zhouqiaoyun/p/10515607.html
  • reuiqre.context - https://juejin.im/post/5c10dbcbf265da61441fe8e2
  • 兼容 iphone x * 劉海的正確姿勢 - https://imweb.io/topic/5baa38c279ddc80f36592efb
  • ios 13.4.1 html2canmvas 不執行 - https://github.com/niklasvh/html2canvas/issues/2205
  • js 處理表情符號 - https://blog.csdn.net/rainbow8590/article/details/80967932

ps: 上述問題的答案基本都是看了這些文章的內容並融入了自己的思考,得到的答案。感謝各位大佬的付出[抱拳]

本文首發:

最後,祝大家,五一Happy~> 這是近期的一個 h5 項目,由於某些原因,預覽地址不能放出來。不過這不是重點,沒有 demo 不就可以好好看文章了嗎 哈哈哈~

文中提到的 pixi 是 pixiJs,精靈是 pixiJs 中的概念。閱讀本文假設你已經知道了這些東西,不過這在本篇文章中並沒有太多關於這個庫的內容

覺得這篇文章有幫助到自己,就讓它去收藏夾吃灰;覺得沒用或覺得寫的不好的,可以留下你的足跡;覺得我的代碼或文字可以改善的,咱們可以進行多人運動一起交流~

下面就開始正經的東西了:

適配方案

這個項目裏用的是 rem 適配方案,通過計算 設備寬度/設計稿寬度 的比例,來設置 html 的 font-size 屬性,達到適配的目的,代碼如下:

function setSize() {
  // 設備寬度
  let deviceWidth = window.screen.width;
  // 設計稿寬度
  const baseValue = 750;
  // html的字體大小 = (設備寬度 / 設計稿寬度) * 100
  document.documentElement.style.fontSize = (deviceWidth / baseValue) * 100 + 'px';
}

// DOM樹加載完執行
window.addEventListener("DOMContentLoaded", function () {
  setSize();
})

// 屏幕變化就執行
window.addEventListener("resize", function () {
  setSize();
})

setSize();

資源的預加載

資源的預加載用的是 preloadjs

中文官網:http://www.createjs.cc/preloadjs

用法也是極其簡單:

  var queue = new window.createjs.LoadQueue(true);
  queue.on("complete", this.allLoadComplete);	// 所有文件加載完成時觸發
  queue.on("fileload", this.aloneLoadComplete);	// 單個文件加載完成時觸發
  queue.on("progress", this.fileProgress);	// 加載進度
  queue.loadManifest(allImg);	// 需要加載的資源數組
  queue.load();

如何解決需要引入很多圖片的問題

這裏用到了 webpack 的 api: require.context,當項目需要引入很多資源時,這項技術是必須要掌握的

可以閱讀 使用require.context自動導入ES模塊 - yeyan1996 這位大佬的文章,本文不做深入探討

如何實現換裝

如何讓人物換裝也是一個問題,經過嘗試後發現,直接切換精靈的 texture 可以達到這個目的

this.personContainers[key].children.map((item, index) => {
    if (item.type == type) {
      item.texture = loadSources[name].texture
    }
})

pixi 多個容器的排序問題

在 pixi 裏,要想動態的改變某個精靈或容器的層級,不能只改一個,,還需要把其他不相干的元素的層級設低

舉個栗子:

personContainers.map((item, i) => {
    item.zIndex = 0;	// 不相干的元素 層級設爲最低
    if (index == i) {
      item.zIndex = 99;	// 目標元素 層級設爲最高
    }
})

精靈的 touchend 事件移動時會失效

具體爲什麼會失效還不知道,我的解決方法是:在給精靈綁定一個 touchendoutside 事件

touchendoutside:觸摸開始、移出對象鬆開時觸發

html2canvas 截取頁面時圖片模糊

如果截取的區域裏有涉及到圖片,不要用 background 設置圖片,全部替換成 img 標籤

這樣可以大大提升圖片的清晰度

ios 鍵盤會把頁面頂上去 不會自動下來

問題描述:移動端 ios 鍵盤彈起後,會把頁面頂上去,輸入完成後頁面不會自動下來

解決辦法:

document.body.addEventListener('focusout', function () {
    window.scrollTo(0,0);
});

當監聽到 body 裏有元素失去焦點時,就把頁面滾上去

focusout: 當元素即將失去焦點時,focusout 事件被觸發。focusout 事件和 blur 事件之間的主要區別在於後者不會冒泡

—— MDN

如何監聽 textarea 的輸入

這個項目用了多行輸入框 textarea ,發現直接在標籤上加了監聽事件後啥也沒有…,後來找到了解決辦法:

this.$refs.textarea.addEventListener('input', e => {
	console.log(e.target.value);	// textarea 輸入的文字
}, false)

滑動加載以及獲取body實際高度的坑

滑動加載的關鍵就是如果頁面滑動到了底部,就進行數據的請求,要事先和後端溝通好數據怎麼返回

滑動到頁面底部的條件:滾動條離頂部的距離(document.body.scrollTop)+ 窗口的文檔顯示區的高度(window.innerHeight)>= 文檔實際高度(document.body.scrollHeight)

這裏有個坑,關於獲取文檔實際高度的:

document.body.scrollHeight 可以在手機上獲取到實際文檔高度,但在 chrome 裏獲取到的高度是 0

document.documentElement.scrollHeight 在 chrome 裏可以獲取到正常的,但在手機上獲取的高度是 0

這樣的話,還要判斷當前設備是手機還是 pc 然後再去獲取嗎,No No No,有個優雅的寫法:

// 獲取文檔實際高度/移動端
var bodyHeight = Math.max(
  document.documentElement.scrollHeight,
  document.body.scrollHeight
);

沒有把基礎的東西丟掉,此處應該有掌聲 [啪啪啪]

vscode 返回上一個編輯點

當代碼寫的像又臭又長的意大利式代碼時,需要去調試某個函數,發現另一個函數又有問題,看完之後還需要翻回來,這就很難頂了

後來發現了這個釋放雙手的快捷鍵 - 返回上/下一個編輯點:Alt + ←/→ (windows)

去除 iphone x 的小尾巴

大家管這玩意叫鬍子,我比較喜歡叫小尾巴~,就是 iphone x 下面那一根玩意

想要了解更多請點擊:https://imweb.io/topic/5baa38c279ddc80f36592efb

我在這裏就說說我是怎麼用的

meta 標籤里加上 viewport-fit=cover

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover" />

然後在底部的樣式里加上樣式:

bottom: env(safe-area-inset-bottom);
bottom: 0;	// 這一句也要加上 沒有小尾巴的機型需要用到這個樣式

這裏的 safe-area-inset-bottom 的意思是:在 Viewport底部的安全區域內設置量(CSS像素),更多方向看下圖

img

(ps: 圖片來源 https://imweb.io/topic/5baa38c279ddc80f36592efb 侵刪)

小程序跳轉頁面傳值的問題

小程序跳轉到其他組件時,如果需要帶網址這類的參數的話,記得要轉碼,不然是傳不過去滴

栗子:

let link = "https://www.baidu.com/"
wx.redirectTo({
  url: "/pages/index/index?url=" + encodeURIComponent(url),	// 解碼: decodeURIComponent
})

爲什麼要轉碼呢?

假設現在需要獲取用戶信息後傳個網址給 index 組件,這時候,這個鏈接裏是帶有中文或者其他符號的,如果不轉碼,小程序會覺得你這個不是個可以識別的地址,會直接把域名後面的值給你去掉

想要了解更多 轉/解碼 的知識請點擊:https://www.w3school.com.cn/js/jsref_encodeURIComponent.asp

ios 最新版系統 微信瀏覽器 html2canvas 生成圖片失敗

這個項目裏有個生成圖片的功能,需要保存用戶操作過的一些東西,其他設備都正常,唯獨 ios 最新版的系統有問題

debug 了一波後發現,這他瞄的根本沒有執行這個函數,找一半天也沒找到爲什麼,後來看 issues 發現有人說把版本換成 rc.4 的就可以了

issues:https://github.com/niklasvh/html2canvas/issues/2205

emoji 表情轉碼

項目測試的時候,發現 textarea 標籤裏可以輸入表情,緊接着,接口就報錯了,一查看,雖然支持輸入表情,但是不會自動對錶情轉碼,所以提交接口的時候報錯了,下面分享個 emoji 表情轉字符的方法:

// 表情轉字符
utf16toEntities(str) {
  var patt = /[\ud800-\udbff][\udc00-\udfff]/g // 檢測utf16字符正則
  str = str.replace(patt, function(char) {
    var H, L, code
    if (char.length === 2) {
      H = char.charCodeAt(0) // 取出高位
      L = char.charCodeAt(1) // 取出低位
      code = (H - 0xd800) * 0x400 + 0x10000 + L - 0xdc00 // 轉換算法
      return '&#' + code + ';'
    } else {
      return char
    }
  })
  return str
}

教訓

  • 全局事件卸載組件時一定要註銷事件
  • 自己寫的東西要多測幾遍
  • npm 包切換版本後要去文件裏看下是不是真的切換了

參考文章

  • 原生 js 監聽 textarea 的輸入 - https://www.jianshu.com/p/66c205c6ef63
  • 移動端獲取全文高度 - https://www.cnblogs.com/xiaomingBlog/p/7822937.html
  • 資源預加載 - http://www.createjs.cc/preloadjs
  • pixi 精靈排序問題 - https://www.cnblogs.com/afrog/p/4056378.html
  • 移動端 ios 軟鍵盤收起時頁面不見了 - https://www.cnblogs.com/zhouqiaoyun/p/10515607.html
  • reuiqre.context - https://juejin.im/post/5c10dbcbf265da61441fe8e2
  • 兼容 iphone x * 劉海的正確姿勢 - https://imweb.io/topic/5baa38c279ddc80f36592efb
  • ios 13.4.1 html2canmvas 不執行 - https://github.com/niklasvh/html2canvas/issues/2205
  • js 處理表情符號 - https://blog.csdn.net/rainbow8590/article/details/80967932

ps: 上述問題的答案基本都是看了這些文章的內容並融入了自己的思考,得到的答案。感謝各位大佬的付出[抱拳]

本文首發:

最後,祝大家,五一Happy~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章