h5 小游戲總結(jié)及踩坑記錄(全是干貨~)??

這是近期的一個(gè) h5 項(xiàng)目,由于某些原因,預(yù)覽地址不能放出來(lái)。不過(guò)這不是重點(diǎn),沒有 demo 不就可以好好看文章了嗎 哈哈哈~

文中提到的 pixi 是 pixiJs,精靈是 pixiJs 中的概念。閱讀本文假設(shè)你已經(jīng)知道了這些東西,不過(guò)這在本篇文章中并沒有太多關(guān)于這個(gè)庫(kù)的內(nèi)容

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

下面就開始正經(jīng)的東西了:

適配方案

這個(gè)項(xiàng)目里用的是 rem 適配方案,通過(guò)計(jì)算 設(shè)備寬度/設(shè)計(jì)稿寬度 的比例,來(lái)設(shè)置 html 的 font-size 屬性,達(dá)到適配的目的,代碼如下:

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

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

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

setSize();

資源的預(yù)加載

資源的預(yù)加載用的是 preloadjs

中文官網(wǎng):http://www.createjs.cc/preloadjs

用法也是極其簡(jiǎn)單:

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

如何解決需要引入很多圖片的問(wèn)題

這里用到了 webpack 的 api: require.context,當(dāng)項(xiàng)目需要引入很多資源時(shí),這項(xiàng)技術(shù)是必須要掌握的

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

如何實(shí)現(xiàn)換裝

如何讓人物換裝也是一個(gè)問(wèn)題,經(jīng)過(guò)嘗試后發(fā)現(xiàn),直接切換精靈的 texture 可以達(dá)到這個(gè)目的

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

pixi 多個(gè)容器的排序問(wèn)題

在 pixi 里,要想動(dòng)態(tài)的改變某個(gè)精靈或容器的層級(jí),不能只改一個(gè),,還需要把其他不相干的元素的層級(jí)設(shè)低

舉個(gè)栗子:

personContainers.map((item, i) => {
    item.zIndex = 0;    // 不相干的元素 層級(jí)設(shè)為最低
    if (index == i) {
      item.zIndex = 99; // 目標(biāo)元素 層級(jí)設(shè)為最高
    }
})

精靈的 touchend 事件移動(dòng)時(shí)會(huì)失效

具體為什么會(huì)失效還不知道,我的解決方法是:在給精靈綁定一個(gè) touchendoutside 事件

touchendoutside:觸摸開始、移出對(duì)象松開時(shí)觸發(fā)

html2canvas 截取頁(yè)面時(shí)圖片模糊

如果截取的區(qū)域里有涉及到圖片,不要用 background 設(shè)置圖片,全部替換成 img 標(biāo)簽

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

ios 鍵盤會(huì)把頁(yè)面頂上去 不會(huì)自動(dòng)下來(lái)

問(wèn)題描述:移動(dòng)端 ios 鍵盤彈起后,會(huì)把頁(yè)面頂上去,輸入完成后頁(yè)面不會(huì)自動(dòng)下來(lái)

解決辦法:

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

當(dāng)監(jiān)聽到 body 里有元素失去焦點(diǎn)時(shí),就把頁(yè)面滾上去

focusout: 當(dāng)元素即將失去焦點(diǎn)時(shí),focusout 事件被觸發(fā)。focusout 事件和 blur 事件之間的主要區(qū)別在于后者不會(huì)冒泡

—— MDN

如何監(jiān)聽 textarea 的輸入

這個(gè)項(xiàng)目用了多行輸入框 textarea ,發(fā)現(xiàn)直接在標(biāo)簽上加了監(jiān)聽事件后啥也沒有...,后來(lái)找到了解決辦法:

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

滑動(dòng)加載以及獲取body實(shí)際高度的坑

滑動(dòng)加載的關(guān)鍵就是如果頁(yè)面滑動(dòng)到了底部,就進(jìn)行數(shù)據(jù)的請(qǐng)求,要事先和后端溝通好數(shù)據(jù)怎么返回

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

這里有個(gè)坑,關(guān)于獲取文檔實(shí)際高度的:

document.body.scrollHeight 可以在手機(jī)上獲取到實(shí)際文檔高度,但在 chrome 里獲取到的高度是 0

document.documentElement.scrollHeight 在 chrome 里可以獲取到正常的,但在手機(jī)上獲取的高度是 0

這樣的話,還要判斷當(dāng)前設(shè)備是手機(jī)還是 pc 然后再去獲取嗎,No No No,有個(gè)優(yōu)雅的寫法:

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

沒有把基礎(chǔ)的東西丟掉,此處應(yīng)該有掌聲 [啪啪啪]

vscode 返回上一個(gè)編輯點(diǎn)

當(dāng)代碼寫的像又臭又長(zhǎng)的意大利式代碼時(shí),需要去調(diào)試某個(gè)函數(shù),發(fā)現(xiàn)另一個(gè)函數(shù)又有問(wèn)題,看完之后還需要翻回來(lái),這就很難頂了

后來(lái)發(fā)現(xiàn)了這個(gè)釋放雙手的快捷鍵 - 返回上/下一個(gè)編輯點(diǎn):Alt + ←/→ (windows)

去除 iphone x 的小尾巴

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

想要了解更多請(qǐng)點(diǎn)擊:https://imweb.io/topic/5baa38c279ddc80f36592efb

我在這里就說(shuō)說(shuō)我是怎么用的

meta 標(biāo)簽里加上 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;  // 這一句也要加上 沒有小尾巴的機(jī)型需要用到這個(gè)樣式

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

img

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

小程序跳轉(zhuǎn)頁(yè)面?zhèn)髦档膯?wèn)題

小程序跳轉(zhuǎn)到其他組件時(shí),如果需要帶網(wǎng)址這類的參數(shù)的話,記得要轉(zhuǎn)碼,不然是傳不過(guò)去滴

栗子:

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

為什么要轉(zhuǎn)碼呢?

假設(shè)現(xiàn)在需要獲取用戶信息后傳個(gè)網(wǎng)址給 index 組件,這時(shí)候,這個(gè)鏈接里是帶有中文或者其他符號(hào)的,如果不轉(zhuǎn)碼,小程序會(huì)覺得你這個(gè)不是個(gè)可以識(shí)別的地址,會(huì)直接把域名后面的值給你去掉

想要了解更多 轉(zhuǎn)/解碼 的知識(shí)請(qǐng)點(diǎn)擊:https://www.w3school.com.cn/js/jsref_encodeURIComponent.asp

ios 最新版系統(tǒng) 微信瀏覽器 html2canvas 生成圖片失敗

這個(gè)項(xiàng)目里有個(gè)生成圖片的功能,需要保存用戶操作過(guò)的一些東西,其他設(shè)備都正常,唯獨(dú) ios 最新版的系統(tǒng)有問(wèn)題

debug 了一波后發(fā)現(xiàn),這他瞄的根本沒有執(zhí)行這個(gè)函數(shù),找一半天也沒找到為什么,后來(lái)看 issues 發(fā)現(xiàn)有人說(shuō)把版本換成 rc.4 的就可以了

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

emoji 表情轉(zhuǎn)碼

項(xiàng)目測(cè)試的時(shí)候,發(fā)現(xiàn) textarea 標(biāo)簽里可以輸入表情,緊接著,接口就報(bào)錯(cuò)了,一查看,雖然支持輸入表情,但是不會(huì)自動(dòng)對(duì)表情轉(zhuǎn)碼,所以提交接口的時(shí)候報(bào)錯(cuò)了,下面分享個(gè) emoji 表情轉(zhuǎn)字符的方法:

// 表情轉(zhuǎn)字符
utf16toEntities(str) {
  var patt = /[\ud800-\udbff][\udc00-\udfff]/g // 檢測(cè)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 // 轉(zhuǎn)換算法
      return '&#' + code + ';'
    } else {
      return char
    }
  })
  return str
}

教訓(xùn)

  • 全局事件卸載組件時(shí)一定要注銷事件
  • 自己寫的東西要多測(cè)幾遍
  • npm 包切換版本后要去文件里看下是不是真的切換了

參考文章

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

本文首發(fā):

最后,祝大家,五一Happy~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容