移动端自适应解决方法(原理是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大小

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/640683.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript 示例: jsencrypt 私钥 16位密码短语 + cryptojs AES加解密

JavaScript 示例: jsencrypt 私钥 16位密码短语 cryptojs AES加解密 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

[go] Stringer 类型

Stringer是Golang的fmt包中的一个类型。 Stringer由任何具有String方法的值来实现。 实现Stringer的类型与字符串的打印方式相同。Stringer会返回一个字符串。 type Stringer type Stringer interface {String() string }让我们看一个例子&#xff0c;我们有一个结构&#…

【图形学】实现二维几何变换

二维点类 class CPoint2 { public:CPoint2();CPoint2(double x, double y);~CPoint2();friend CPoint2 operator (const CPoint2& p0, const CPoint2& p1);friend CPoint2 operator -(const CPoint2& p0, const CPoint2& p1);friend CPoint2 operator *(const…

云原生 - 微信小程序 COS 对象存储图片缓存强制更新解决方案

问题描述 遇到一个这样的情况&#xff1a;在微信小程序里图片缓存十分麻烦&#xff0c;网上很多说在腾讯云里的 COS 存储对象服务里设置对应的图片缓存&#xff08;Header 头 Cache-Contorl&#xff09;&#xff0c;说实话真不好用&#xff0c;一会儿生效&#xff0c;一会儿没…

excel学习1

直接ctrl cctrl v会报错位移选择粘贴时用123那个数字粘贴而不是ctrl V 只要结果不要公式 上面复制的为数值这里是复制的公式他们两个不一样 这个方法太麻烦了直接用格式刷&#xff0c;选择一个区域一个单元格&#xff0c;不要选择多个一刷就出来了 第一个计算后向下拖就行了&…

FastDFS分布式文件存储

为什么会有分布式文件系统&#xff1f; 分布式文件系统是面对互联网的需求而产生。因为互联网时代要对海量数据进行存储。很显然靠简单的增加硬盘个数已经满足不了我们的要求。因为硬盘传输速度有限但是数据在急剧增长&#xff0c;另外我们还要要做好数据备份、数据安全等。采用…

Git的安装与配置

目录 前言 Linux-centos&#xff1a;下安装 Linux_ubuntu下安装 创建Git本地仓库 配置用户名和Email 前言 Git是一种版本控制器&#xff0c;能够让我们了解一个文件的历史&#xff0c;以及它的发展过程。通俗的将就是可以记录一个工程的每一次改动和版本迭代的一个管理系统…

【vscode】6、调试 shell

文章目录 经常在 IDE 下使用 高级语言后&#xff0c;往往并不习惯 shell 编程&#xff0c;因为没有酷炫的界面。但现在 vscode 可以很方便的调试 shell 脚本。 配置方法如下&#xff1a; vscode 下载 Bash Debug 插件 mac 升级 bash 版本&#xff08;因为此 vscode 插件需要 b…

蓝桥杯重要知识点和赛题直通车

<蓝桥杯软件赛>零基础备赛20周 第 1周(2023-10-23): 蓝桥杯软件赛介绍官方链接零基础能得奖吗&#xff1f; 第 2周(2023-10-30): 常考知识点蓝桥杯怎么判题备赛计划 第 3周(2023-11-06): 填空题&#xff08;分数少但越来越不好做&#xff09; 第 4周(2023-11-13): &#…

Qt系统托盘的学习

参考&#xff1a; Qt系统托盘程序的实现_qt托盘程序-CSDN博客 QT系统托盘应用程序-CSDN博客 代码&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QSystemTrayIcon> #include <QDebug> #include <QMenu> #include &l…

更改wpf原始默认按钮的样式

样式 代码 <Window x:Class"WpfApp4.Window1"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/2008…

141基于matlab的齿轮系统非线性动力学特性分析

基于matlab的齿轮系统非线性动力学特性分析&#xff0c;综合考虑齿侧间隙、时变啮合刚度、综合啮合误差等因素下&#xff0c;参数阻尼比变化调节下&#xff0c;输出位移、相图、载荷、频率幅值结果。程序已调通&#xff0c;可直接运行。 141 matlab齿轮非线性动力学 (xiaohongs…

【C++】多项式输出

记录一下这个WA了三遍才AC的题......QAQ 题目描述 一元 n 次多项式可用如下的表达式表示&#xff1a; 其中&#xff0c;aixi称为 i 次项&#xff0c;ai 称为 i 次项的系数。给出一个一元多项式各项的次数和系数&#xff0c;请按照如下规定的格式要求输出该多项式&#xff1a; f…

使用VSCode开发 Python虚拟环境配置说明

这里给大家介绍下怎么配置VSCode的环境来开发Python。 介绍&#xff1a; VSCode是一款由Microsoft开发的免费、开源的代码编辑器。它具有许多优势&#xff0c;使其成为许多开发者喜爱的工具之一。以下是一些VSCode的主要优势&#xff1a; 轻量且快速启动&#xff1a; VSCode是…

【ASP.NET Core 基础知识】--依赖注入(DI)--什么是依赖注入

依赖注入&#xff08;Dependency Injection&#xff0c;简称DI&#xff09;是一种设计模式&#xff0c;用于解耦和管理类之间的依赖关系。它的核心思想是将原本需要在代码中显式创建的依赖关系&#xff0c;交给外部容器进行控制和管理。 具体来说&#xff0c;依赖注入的实现方式…

每日一题——LeetCode1299.将每个元素替换为右侧最大元素

方法一 个人方法&#xff1a; 题目意思就是求在i1;i的循环条件下&#xff0c;arr[i]-arr[arr.length-1]的最大值分别为多少&#xff0c;最后一项默认为-1 用slice方法可以每次把数组第一位去除&#xff0c;得到求最大值的目标数组 Math的max方法可以直接返回数组里的最大值 …

基于yolov5-master和pyqt5的森林火灾监测软件

文章目录 项目背景效果演示一、实现思路① 算法原理② 程序流程图 二、系统设计与实现三、模型评估与优化 项目背景 火灾作为威胁人类生命生产安全的隐患之一&#xff0c;一直是人们关注的重点。传统的火灾监测装置根据温度来检测火灾&#xff0c;不仅灵敏度差&#xff0c;而且…

《Learning to Reweight Examples for Robust Deep Learning》笔记

[1] 用 meta-learning 学样本权重&#xff0c;可用于 class imbalance、noisy label 场景。之前对其 (7) 式中 ϵ i , t 0 \epsilon_{i,t}0 ϵi,t​0&#xff08;对应 Algorithm 1 第 5 句、代码 ex_wts_a tf.zeros([bsize_a], dtypetf.float32)&#xff09;不理解&#xff…

LeetCode 每日一题 Day 47 - 50

2171. 拿出最少数目的魔法豆 给定一个 正整数 数组 beans &#xff0c;其中每个整数表示一个袋子里装的魔法豆的数目。 请你从每个袋子中 拿出 一些豆子&#xff08;也可以 不拿出&#xff09;&#xff0c;使得剩下的 非空 袋子中&#xff08;即 至少还有一颗 魔法豆的袋子&a…

数据结构课程设计 仓储管理系统

仓储管理系统 【基本功能】 把货品信息表抽象成一个线性表&#xff0c;货品信息&#xff08;包括ID、货品名、定价、数量等&#xff09;作为线性表的一个元素&#xff0c;实现&#xff1a;按ID、货品名分别查找某货品信息&#xff08;包括ID、货品名、定价、数量等&#xff0…