如何处理双端(pc端和移动端)

169 阅读1分钟

1.如何根据设备(电脑和手机)返回不同的页面?

使用请求头中的user-agent字段,通过useragent库处理,判断返回pc端或者移动端页面。 java可根据cn.hutool.http.useragent.UserAgent库,java库更加全面

// app.js
const express = require("express");
const useragent = require("useragent");
const app = express();
const port = 3000;
// 提供静态文件服务
app.use(express.static("public"));
// 定义主页路由
app.get("/", (req, res) => {
  const agent = useragent.parse(req.headers["user-agent"]);
  const isMobile = /iPhone|Android|Mobile/i.test(agent.device.family);
  console.log(agent.device.family);
  if (isMobile) {
    res.sendFile(__dirname + "/public/mobile.html");
  } else {
    res.sendFile(__dirname + "/public/pc.html");
  }
});

// 启动服务器
app.listen(port, () => {
  console.log(`服务器正在运行在 http://localhost:${port}`);
});

2. 移动端响应式处理?

使用lib-flexible库,主要原理为: 页面加载完成后设置html标签(rem基于html计算)的字体大小,并在窗口大小改变时重新设置。

var doc = win.document;
var docEl = doc.documentElement;
var metaEl = doc.querySelector('meta[name="viewport"]');
var flexibleEl = doc.querySelector('meta[name="flexible"]');
var dpr = 0;
var scale = 0;
var tid;
var flexible = lib.flexible || (lib.flexible = {});

if (metaEl) {
  console.warn("将根据已有的meta标签来设置缩放比例");
  var match = metaEl.getAttribute("content").match(/initial\-scale=([\d\.]+)/);
  if (match) {
    scale = parseFloat(match[1]);
    dpr = parseInt(1 / scale);
  }
} else if (flexibleEl) {
  var content = flexibleEl.getAttribute("content");
  if (content) {
    var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
    var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
    if (initialDpr) {
      dpr = parseFloat(initialDpr[1]);
      scale = parseFloat((1 / dpr).toFixed(2));
    }
    if (maximumDpr) {
      dpr = parseFloat(maximumDpr[1]);
      scale = parseFloat((1 / dpr).toFixed(2));
    }
  }
}

if (!dpr && !scale) {
  var isAndroid = win.navigator.appVersion.match(/android/gi);
  var isIPhone = win.navigator.appVersion.match(/iphone/gi);
  var devicePixelRatio = win.devicePixelRatio;
  if (isIPhone) {
    // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
    if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
      dpr = 3;
    } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {
      dpr = 2;
    } else {
      dpr = 1;
    }
  } else {
    // 其他设备下,仍旧使用1倍的方案
    dpr = 1;
  }
  scale = 1 / dpr;
}

docEl.setAttribute("data-dpr", dpr);
if (!metaEl) {
  metaEl = doc.createElement("meta");
  metaEl.setAttribute("name", "viewport");
  metaEl.setAttribute(
    "content",
    "initial-scale=" +
      scale +
      ", maximum-scale=" +
      scale +
      ", minimum-scale=" +
      scale +
      ", user-scalable=no"
  );
  if (docEl.firstElementChild) {
    docEl.firstElementChild.appendChild(metaEl);
  } else {
    var wrap = doc.createElement("div");
    wrap.appendChild(metaEl);
    doc.write(wrap.innerHTML);
  }
}

function refreshRem() {
  var width = docEl.getBoundingClientRect().width;
  if (width / dpr > 540) {
    width = 540 * dpr;
  }
  var rem = width / 10;
  docEl.style.fontSize = rem + "px";
  flexible.rem = win.rem = rem;
}

win.addEventListener(
  "resize",
  function () {
    clearTimeout(tid);
    tid = setTimeout(refreshRem, 300);
  },
  false
);
win.addEventListener(
  "pageshow",
  function (e) {
    if (e.persisted) {
      clearTimeout(tid);
      tid = setTimeout(refreshRem, 300);
    }
  },
  false
);

if (doc.readyState === "complete") {
  doc.body.style.fontSize = 12 * dpr + "px";
} else {
  doc.addEventListener(
    "DOMContentLoaded",
    function (e) {
      doc.body.style.fontSize = 12 * dpr + "px";
    },
    false
  );
}

refreshRem();

flexible.dpr = win.dpr = dpr;
flexible.refreshRem = refreshRem;
flexible.rem2px = function (d) {
  var val = parseFloat(d) * this.rem;
  if (typeof d === "string" && d.match(/rem$/)) {
    val += "px";
  }
  return val;
};
flexible.px2rem = function (d) {
  var val = parseFloat(d) / this.rem;
  if (typeof d === "string" && d.match(/px$/)) {
    val += "rem";
  }
  return val;
};

3. 如何方便的计算rem

使用 Less 编写的混合宏(Mixin),用于将像素值转换为 rem 单位。rem 是一种相对单位,基于根元素的字体大小,通常用于响应式设计中,以确保在不同设备和屏幕尺寸下具有一致的布局和样式。

.remMixin(){
  @functions: ~`(function(){
		function convert(size){
			return typeof size === 'string' ? +size.replace('px', '') : size;
		}
		const baseFontSize = convert('75px');
    this.px2rem = function(size){
      return convert(size) / baseFontSize + 'rem';
    }
		
		this.px2remImp = function(size) {
			return (convert(size) / baseFontSize) + 'rem !important';
		}
  })()`
}

.remMixin();