背景
我們?cè)谶M(jìn)行h5開發(fā)時(shí)则拷,通常使用的設(shè)計(jì)稿是750px(考慮retina)玖喘,我們會(huì)直接根據(jù)設(shè)計(jì)稿的尺寸去開發(fā)甩牺,然后進(jìn)行適配(常用的有淘寶的flexible方案以及近期流行的vw適配方案)。但有時(shí)累奈,我們又想直接使用現(xiàn)有移動(dòng)端框架的一些組件(如簡(jiǎn)潔大方的weui)贬派。weui作為基礎(chǔ)組件,大多數(shù)是使用px為單位的澎媒,比如直接在自己的項(xiàng)目中用upload組件搞乏,看起來(lái)就小了一號(hào)。
這是由于<meta>中的 viewport已經(jīng)被相關(guān)js改成 640 或 750 之類的值戒努,WeUI中的 13px 等字號(hào)或尺寸就顯得捉襟見肘了请敦。
解決方案
1. 最笨的
要解決這個(gè)問題侍筛,最直接的方式就是把框架里相關(guān)代碼拷貝過來(lái)萤皂,自己默默地覆蓋樣式,這樣做的好處是可以精確控制像素匣椰,缺點(diǎn)自然是浪費(fèi)生命~~
2. 與適配方案相關(guān)的
如果你使用rem的適配方案裆熙,有現(xiàn)成的工具可以將px轉(zhuǎn)化成rem(如,px2rem)弛车,或者在webpack工程中使用postcss-px2rem插件,并在處理css的相關(guān)rules中添加
{
loader: 'postcss-loader',
options: {
plugins: [
px2rem({
remUnit: 375 / 20,
remPrecision: 5
})
]
}
}
需要注意的是
- remPrecision指的是生成的rem數(shù)值精度喻括,避免過長(zhǎng)
- 而 remUnit 中用 375邀杏,是基于 iphone6 的尺寸做一個(gè)基準(zhǔn),計(jì)算出來(lái)的尺寸基本在各自手機(jī)型號(hào)中都可以接受
- 20 則參考了小程序中的標(biāo)準(zhǔn)唬血,這個(gè)值其實(shí)也可以自定義望蜡,和相關(guān)rem輔助工具中的設(shè)置一致即可
該方案參考自《WeUI在rem項(xiàng)目中的一種適配方法》 一文,該文還提出“使用 webpack2-replace-loader 插件”的方式拷恨,但本人測(cè)試后無(wú)法編譯通過脖律,如果有同學(xué)成功了,請(qǐng)多多指教~
3. 字符串替換方式腕侄,修改原來(lái)的px(大概2倍大小比較合適)
這個(gè)方式的思路是找出框架中所有以px為單位的數(shù)字小泉,乘以2。借用node文件處理冕杠,按行讀取文件微姊,對(duì)每行文件進(jìn)行正則匹配,并替換所有以px結(jié)尾的數(shù)值分预。代碼如下:
let output = ''; // 最終輸出的結(jié)果
const readline = require('readline');
const path = require('path');
const fs = require('fs');
let filepath = path.join(__dirname, "weui.css"); // 需要轉(zhuǎn)化的css文件
let input = fs.createReadStream(filepath);
const rl = readline.createInterface({
input: input
});
rl.on('line', (line) => {
var exp = new RegExp(/\b(\d+(\.\d+)?)px\b/g); // 獲取所有以px結(jié)尾的數(shù)值
var out = line.replace(exp, function ($0, $1) {
return $1 * 2 + 'px';
}); // 將匹配到的數(shù)值進(jìn)行計(jì)算
output += `${out}\n`;
});
rl.on('close', (line) => {
fs.writeFile(__dirname + '/output.css', output, function (err) {
if (err) {
throw err;
}
console.log('已保存!');
});
console.log("讀取完畢兢交!");
});
將輸出的文件引入項(xiàng)目,可以看到剛才的上傳組件變成正常大小啦
踩過的幾個(gè)坑:
- 一開始沒想到replace函數(shù)可以直接用替換函數(shù)笼痹,還在那里自己拼字符串配喳,如下:
var result = exp.exec(line);
var out = line;
if (result !== null) {
out = line.substring(0, result.index) + parseInt(result[1])*2 + line.substring(result.index+result[1].length);
}
但這也只能解決一行只出現(xiàn)一次px的情況,如果有多個(gè)匹配串凳干,拼起來(lái)太痛苦了晴裹,就想著px轉(zhuǎn)rem的工具肯定已經(jīng)解決了這個(gè)問題,所以屁顛屁顛跑去參考了px2rem的源碼(思路!!!)纺座,發(fā)現(xiàn)replace可以這么用息拜,馬上解決了我的痛點(diǎn),開心!
- 本來(lái)想每行處理的時(shí)候順便寫入到文件少欺,但寫入文件的過程是異步的喳瓣,所以生成出來(lái)的文件會(huì)錯(cuò)位。一般css文件都不會(huì)很大赞别,因此我直接把結(jié)果緩存起來(lái)畏陕,最后一起寫入文件。畢竟讀寫文件的開銷比較大仿滔。
本人初入移動(dòng)端惠毁,希望各位多多吐槽,一起討論解決問題的思路崎页。