這是近期的一個 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像素),更多方向看下圖
(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像素),更多方向看下圖
(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~