摘要:从概念来说,就是设备的物理像素与设备独立像素也就是逻辑像素,以下就称为逻辑像素的比率。通过这个标签,我们可以实现初始缩放,就可以达到的逻辑像素眼睛在设备上看起来的,换句话说可以在上充满竖屏的整个宽度。
前言:18年12月24日项目成功上线了,在经历了两周的线上bug、UI以及代码优化后,解决了不少问题,于是再完善与优化一下这个项目。
布局优化
高清配置
antd-mobile 自定义配置
antd-mobile Toast组件封装
布局优化布局优化在这篇文章完成了 → [移动端优雅布局实践](),最后我使用的方案是——absolute脱离文档流(好处是设置容器的height: 100%,可以直接继承html窗口高度)。
高清配置 问题发现开始项目之前没有对dpr(device pixel radio)与缩放做过多的了解,在项目开发的时候就将它们都直接写死为1了。到后来UI验收的时候发现并没有实现UI设计师预期的细线效果。我在解决这个问题的时候才去认真看了一下dpr的介绍。这篇详解dpr的文章写得还不错。
从概念来说,dpr就是设备的物理像素与设备独立像素(也就是css逻辑像素,以下就称为css逻辑像素)的比率。
比如:iPhone 6的分辨率是750*1334,window.screen.width(css逻辑像素)为375,因此
dpr = 750 /375 = 2
再比如:iPhone X的分辨率是1125*2436,window.screen.width(css逻辑像素)也是375,因此
dpr = 1125 /375 = 3
那么dpr有什么用呢?
在这之前先提一下我们移动端必备的一个meta标签:
device-width在html中也同样被解读为理想(基准)视口的宽度,即320px,375px,414px,这里的px就是指css像素,通常也被称为逻辑像素;那我们可以认为html中的css像素的显示尺寸应该和NA中的pt、dp的显示尺寸相等。
通过这个meta标签,我们可以实现initial-scale=1初始缩放100%,就可以达到1px的css逻辑像素 = 眼睛在设备上看起来的1px,换句话说body { width: 375px; }可以在iPhone 6上充满竖屏的整个宽度。
那么问题就来了,如果我们要给一个盒子加上一个1px的细线:
border-bottom: 1px solid red;。那么在iPhone 6上真的是1px吗?
iPhone 6真机截图(宽度为702px):
可以看出高度明显不止1像素。这就是由于dpr造成的,因为iPhone 6的dpr为2,且缩放比例为100%,1px的css渲染出来就是2px物理像素。
这就是我们UI粑粑和产品们不满意的地方。
那接下来如何去解决这个问题呢?
解决方案根据设备的dpr来动态计算缩放比例,以及根节点的font-size。
// rem.js (function(doc, win) { var docEl = doc.documentElement, dpr = Math.min(win.devicePixelRatio, 3); dpr = window.top === window.self ? dpr : 1; //被iframe引用时,禁止缩放 var scale = 1 / dpr, resizeEvt = "orientationchange" in window ? "orientationchange" : "resize"; docEl.dataset.dpr = dpr; var metaEl = doc.createElement("meta"); metaEl.name = "viewport"; metaEl.content = "initial-scale=" + scale + ",maximum-scale=" + scale + ", minimum-scale=" + scale + ",user-scalable=no,viewport-fit=cover"; docEl.firstElementChild.appendChild(metaEl); var recalc = function() { var width = docEl.clientWidth; // 大于1280按1280来算 if (width / dpr > 1280) { width = 1280 * dpr; } // px : rem = 100 : 1 docEl.style.fontSize = 100 * (width / 375) + "px"; }; recalc(); if (!doc.addEventListener) return; win.addEventListener(resizeEvt, recalc, false); })(document, window);
如果有显示富文本元素,则需要处理富文本元素的样式
移动端为了适配不同的机型,使用rem为单位是一个不错的选择,而且我们也一直在用它。
这里除了根据dpr来计算initial-scale,还调整了根节点的font-size,以至于在缩放的时候能够还原到视窗大小(因为要缩放,所以要相应的增加rem的基数)。
这样我们上面写的border-bottom: 1px solid red;在这个方案显示出来就是这样的:
哇咔咔,可以看出明显变细了,这才是我们UI粑粑们想要的O(∩_∩)O~~
但是这样的设置在结合ant-design-mobile的时候,发现ant-design-mobile的组件都被缩小了。原来是,它的元素都是以px为单位,而我们缩放前没有对它的最小单位乘以相应的基数。那么,我们需要给它配置一个基数!
antd-mobile自定义配置查文档发现ant-design-mobile提供了主题配置,而且它提供了一个@hd的变量做为长度基本单位,它的默认值是1px。
这个主题配置的文档是以webpack项目来做的例子。那如何在next.js项目中完成自定义配置呢?
我在next.js的examples中没有找到我所需要的example,不过找到了两个相关的例子:一个是with-antd-mobile,一个是with-ant-design-less。第二个是ant-design的自定义主题配置,那应该就可以仿照这个example去增加with-antd-mobile的自定义主题配置。
这里提一下,这个with-antd-mobile在我写Next框架与主流工具的整合之后更新了next.config.js的配置,这里也改成了最新的配置。
安装解析 Less 与 normalize.css 的包
npm i @zeit/next-less @zeit/next-css less less-vars-to-js -S
修改.babelrc配置
{ "presets": ["next/babel"], "plugins": [ [ "import", { "libraryName": "antd-mobile", "style": true } ] ] }
修改next.config.js配置
/* eslint-disable */ const withCSS = require("@zeit/next-css"); const withSass = require("@zeit/next-sass"); const withLess = require("@zeit/next-less"); const lessToJS = require("less-vars-to-js"); const fs = require("fs"); const path = require("path"); // Where your antd-custom.less file lives const themeVariables = lessToJS(fs.readFileSync(path.resolve(__dirname, "./antd-custom.less"), "utf8")); // fix: prevents error when .less files are required by node if (typeof require !== "undefined") { require.extensions[".less"] = file => {}; require.extensions[".css"] = file => {}; } module.exports = withCSS( withLess( withSass({ lessLoaderOptions: { javascriptEnabled: true, modifyVars: themeVariables } }) ) );
在项目下新建Less变量文件 antd-custom.less
@hd: 0.01rem;
重启项目,就大功告成了。
antd-mobile Toast组件封装antd-mobile的Toast.info()组件在显示的时候不能点击背景就消失,与原生的Toast有些差异,为了体验,这里再做了一层封装,在点击背景的时候隐藏Toast。
// utils/toast.js static info = (content, duration, onClose, mask) => { Toast.info(content, duration, onClose, mask); const toastElement = document.getElementsByClassName("am-toast-mask")[0]; toastElement && toastElement.addEventListener("click", () => { Toast.hide(); onClose && onClose(); }); };
antd-mobile的loading图在Android上有些怪异,这里也自定义了Loading:
static loading = (content, duration, onClose, mask) => { Toast.info(写在最后, duration, onClose, mask ); };{content}
一个项目需要在不断的优化与完善中才能变得更好。搭建项目是对一个项目负责人很大的考验,如果在项目设计的初期有许多的问题没有考虑到,就很有可能导致优化的时候需要耗费很大的精力。
总之,不要逃避困难与问题,这些都是成长路上不可或缺的。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/101188.html
摘要:又从开始学习新的东西了,想着还是记录一下学习历程,有输入就要有输出吧,免得以后给忘记学了些什么框架与主流工具的整合地址首先,项目,学习里面的。如有错误和问题欢迎各位大佬不吝赐教轻量级框架与主流工具的整合二完善与优化 前言 老大说以后会用 next 来做一下 SSR 的项目,让我们有空先学学。又从 0 开始学习新的东西了,想着还是记录一下学习历程,有输入就要有输出吧,免得以后给忘记学了些...
摘要:为进一步提升我国云计算发展与应用水平,积极抢占信息技术发展的制高点,制定本行动计划。支持骨干企业及行业协会实质性参与云计算技术管理服务等方面国际标准的制定。二产业发展行动支持软件企业向云计算转型。 发文机关:工业和信息化部标 题:工业和信息化部关于印发《云计算发展三年行动计划(2017-2019年)》的通知 发文字号:工信部信软〔2017〕49号 成文日期:2017-04-06发布日期:2...
摘要:的网站仍然使用有漏洞库上周发布了开源社区安全现状报告,发现随着开源社区的日渐活跃,开源代码中包含的安全漏洞以及影响的范围也在不断扩大。与应用安全是流行的服务端框架,本文即是介绍如何使用以及其他的框架来增强应用的安全性。 showImg(https://segmentfault.com/img/remote/1460000012181337?w=1240&h=826); 前端每周清单专注...
阅读 2012·2021-08-21 14:09
阅读 479·2019-08-30 15:44
阅读 2106·2019-08-29 16:32
阅读 1368·2019-08-29 15:36
阅读 3432·2019-08-29 12:43
阅读 2775·2019-08-29 11:14
阅读 428·2019-08-28 18:26
阅读 2244·2019-08-26 13:57