移动端自适应解决方法(原理是rem布局)

2024-01-23 19:04

本文主要是介绍移动端自适应解决方法(原理是rem布局),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

adaptive

点击跳转官方Git地址
此博客参考笔记

也可以直接复制下方的js文件直接使用

index.js

var adaptive = {};
(function (win, lib) {var doc = win.document;var docEl = doc.documentElement;// 设备像素比var devicePixelRatio = win.devicePixelRatio;// 我们设置的布局视口与理想视口的像素比var dpr = 1; // viewport缩放值var scale = 1; // 设置viewportfunction setViewport() {// 判断IOSvar isIPhone = /iphone/gi.test(win.navigator.appVersion);if (lib.scaleType === 2 && isIPhone || lib.scaleType === 3) {dpr = devicePixelRatio;}// window对象上增加一个属性,提供对外的布局视口与理想视口的值win.devicePixelRatioValue = dpr;// viewport缩放值,布局视口缩放后刚好显示成理想视口的宽度,页面就不会过长或过短了scale = 1 / dpr;// 获取已有的viewportvar hasMetaEl = doc.querySelector('meta[name="viewport"]');var metaStr = 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no';if (dpr === 1) {metaStr = 'width=device-width, '.concat(metaStr);}if (!isIPhone && dpr !== 1) {metaStr = metaStr.concat(', target-densitydpi=device-dpi');}// 如果有,改变之if (hasMetaEl) {hasMetaEl.setAttribute('content', metaStr);}// 如果没有,添加之else {var metaEl = doc.createElement('meta');metaEl.setAttribute('name', 'viewport');metaEl.setAttribute('content', metaStr);if (docEl.firstElementChild) {docEl.firstElementChild.appendChild(metaEl);}else {var containDiv = doc.createElement('div');containDiv.appendChild(metaEl);docEl.appendChild(containDiv);}}}var newBase = 100;lib.errDpr = 1;function setRem() {// 布局视口// var layoutView = docEl.clientWidth; 也可以 获取布局视口的宽度var layoutView;if (lib.maxWidth) {layoutView = Math.min(docEl.getBoundingClientRect().width, lib.maxWidth * dpr);}else {layoutView = docEl.getBoundingClientRect().width;}// 为了计算方便,我们规定 1rem === 100px设计图像素,我们切图的时候就能快速转换// 有人问,为什么不让1rem === 1px设计像素呢?// 设计图一般是640或者750px// 布局视口一般是320到1440// 计算一个值,使layout的总宽度为 (desinWidth/100) rem// 那么有计算公式:layoutView / newBase = desinWidth / 100// newBase = 100 * layoutView / desinWidth// newBase = 介于50到200之间// 如果 1rem === 1px 设计像素,newBase就介于0.5到2之间,由于很多浏览器有最小12px限制,这个时候就不能自适应了newBase = 100 * layoutView / lib.desinWidth * (lib.errDpr || 1);docEl.style.fontSize = newBase + 'px';// rem基准值改变后,手动reflow一下,避免旋转手机后页面自适应问题doc.body&&(doc.body.style.fontSize = lib.baseFont / 100 + 'rem');// 重新设置rem后的回调方法lib.setRemCallback&&lib.setRemCallback();lib.newBase = newBase;}var tid;lib.desinWidth = 750;lib.baseFont = 28;// 局部刷新的时候部分chrome版本字体过大的问题lib.reflow = function() {docEl.clientWidth;};// 检查安卓下rem值是否显示正确function checkRem() {if (/android/ig.test(win.navigator.appVersion)) {var hideDiv = document.createElement('p');hideDiv.style.height = '1px';hideDiv.style.width = '2.5rem';hideDiv.style.visibility = 'hidden';document.body.appendChild(hideDiv);var now = hideDiv.offsetWidth;var right = lib.newBase * 2.5; if (Math.abs(right / now - 1) > 0.05) {lib.errDpr = right / now;setRem();}document.body.removeChild(hideDiv);}}lib.init = function () {// resize的时候重新设置rem基准值// 触发orientationchange 事件时也会触发resize,故不需要再添加此事件了win.addEventListener('resize', function () {clearTimeout(tid);tid = setTimeout(setRem, 300);}, false);// 浏览器缓存中读取时也需要重新设置rem基准值win.addEventListener('pageshow', function (e) {if (e.persisted) {clearTimeout(tid);tid = setTimeout(setRem, 300);}}, false);// 设置body上的字体大小if (doc.readyState === 'complete') {doc.body.style.fontSize = lib.baseFont / 100 + 'rem';checkRem();}else {doc.addEventListener('DOMContentLoaded', function (e) {doc.body.style.fontSize = lib.baseFont / 100 + 'rem';checkRem();}, false);}setViewport();// 设置rem值setRem();// html节点设置布局视口与理想视口的像素比docEl.setAttribute('data-dpr', dpr);};// 有些html元素只能以px为单位,所以需要提供一个接口,把rem单位换算成pxlib.remToPx = function (remValue) {return remValue * newBase;};
})(window, adaptive);
if (typeof module != 'undefined' && module.exports) {module.exports = adaptive;
} else if (typeof define == 'function' && define.amd) {define(function() {return adaptive;});
} else {window.adaptive = adaptive;
}

在index.html使用

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./index.js"></script><script>window['adaptive'].desinWidth = 750// 设计图宽度window['adaptive'].baseFont = 28// 没有缩放时的字体大小window['adaptive'].maxWidth = 750// 页面最大宽度 默认540window['adaptive'].init()// 调用初始化方法</script><style>div {width: 0.3rem;height: 0.3rem;background-color: red;}</style>
</head><body><div>123</div>
</body></html>

hotcss

点击跳转官网

index.js文件

;(function (window, document) {'use strict'//给hotcss开辟个命名空间,别问我为什么,我要给你准备你会用到的方法,免得用到的时候还要自己写。var hotcss = {};(function () {//根据devicePixelRatio自定计算scale//可以有效解决移动端1px这个世纪难题。var viewportEl = document.querySelector('meta[name="viewport"]'),hotcssEl = document.querySelector('meta[name="hotcss"]'),dpr = window.devicePixelRatio || 1,maxWidth = 540,designWidth = 0dpr = dpr >= 3 ? 3 : dpr >= 2 ? 2 : 1//允许通过自定义name为hotcss的meta头,通过initial-dpr来强制定义页面缩放if (hotcssEl) {var hotcssCon = hotcssEl.getAttribute('content')if (hotcssCon) {var initialDprMatch = hotcssCon.match(/initial\-dpr=([\d\.]+)/)if (initialDprMatch) {dpr = parseFloat(initialDprMatch[1])}var maxWidthMatch = hotcssCon.match(/max\-width=([\d\.]+)/)if (maxWidthMatch) {maxWidth = parseFloat(maxWidthMatch[1])}var designWidthMatch = hotcssCon.match(/design\-width=([\d\.]+)/)if (designWidthMatch) {designWidth = parseFloat(designWidthMatch[1])}}}document.documentElement.setAttribute('data-dpr', dpr)hotcss.dpr = dprdocument.documentElement.setAttribute('max-width', maxWidth)hotcss.maxWidth = maxWidthif (designWidth) {document.documentElement.setAttribute('design-width', designWidth)}hotcss.designWidth = designWidth // 保证px2rem 和 rem2px 不传第二个参数时, 获取hotcss.designWidth是undefined导致的NaNvar scale = 1 / dpr,content ='width=device-width, initial-scale=' +scale +', minimum-scale=' +scale +', maximum-scale=' +scale +', user-scalable=no'if (viewportEl) {viewportEl.setAttribute('content', content)} else {viewportEl = document.createElement('meta')viewportEl.setAttribute('name', 'viewport')viewportEl.setAttribute('content', content)document.head.appendChild(viewportEl)}})()hotcss.px2rem = function (px, designWidth) {//预判你将会在JS中用到尺寸,特提供一个方法助你在JS中将px转为rem。就是这么贴心。if (!designWidth) {//如果你在JS中大量用到此方法,建议直接定义 hotcss.designWidth 来定义设计图尺寸;//否则可以在第二个参数告诉我你的设计图是多大。designWidth = parseInt(hotcss.designWidth, 10)}return (parseInt(px, 10) * 320) / designWidth / 20}hotcss.rem2px = function (rem, designWidth) {//新增一个rem2px的方法。用法和px2rem一致。if (!designWidth) {designWidth = parseInt(hotcss.designWidth, 10)}//rem可能为小数,这里不再做处理了return (rem * 20 * designWidth) / 320}hotcss.mresize = function () {//对,这个就是核心方法了,给HTML设置font-size。var innerWidth =document.documentElement.getBoundingClientRect().width ||window.innerWidthif (hotcss.maxWidth && innerWidth / hotcss.dpr > hotcss.maxWidth) {innerWidth = hotcss.maxWidth * hotcss.dpr}if (!innerWidth) {return false}document.documentElement.style.fontSize = (innerWidth * 20) / 320 + 'px'hotcss.callback && hotcss.callback()}hotcss.mresize()//直接调用一次window.addEventListener('resize',function () {clearTimeout(hotcss.tid)hotcss.tid = setTimeout(hotcss.mresize, 33)},false)//绑定resize的时候调用window.addEventListener('load', hotcss.mresize, false)//防止不明原因的bug。load之后再调用一次。setTimeout(function () {hotcss.mresize()//防止某些机型怪异现象,异步再调用一次}, 333)window.hotcss = hotcss//命名空间暴露给你,控制权交给你,想怎么调怎么调。
})(window, document)

index.html使用

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./index.js"></script><style>div {width: 0.3rem;height: 0.3rem;background-color: red;}</style>
</head><body><div>123</div>
</body></html>

具体效果打开浏览器终端看根元素HTML的font-size大小

这篇关于移动端自适应解决方法(原理是rem布局)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/637228

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

如何解决线上平台抽佣高 线下门店客流少的痛点!

目前,许多传统零售店铺正遭遇客源下降的难题。尽管广告推广能带来一定的客流,但其费用昂贵。鉴于此,众多零售商纷纷选择加入像美团、饿了么和抖音这样的大型在线平台,但这些平台的高佣金率导致了利润的大幅缩水。在这样的市场环境下,商家之间的合作网络逐渐成为一种有效的解决方案,通过资源和客户基础的共享,实现共同的利益增长。 以最近在上海兴起的一个跨行业合作平台为例,该平台融合了环保消费积分系统,在短

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip