前端常见需求——屏幕自适应

233 阅读2分钟

屏幕自适应,可以说是前端的必备需求,但是有些项目,一开始使用的是px,然后需要去将其转换成rem,一个个改?必不可能,我们可以封装一个函数直接将css里的px转换为rem

首先,我们来了解几个概念

1.物理像素比:比如 iphone8的分辨率为1334x750像素,1334为纵向的设备物理像素,750为横向的设备物理像素。设备的物理像素是设备决定的,不可改变

2.dpr(设备像素比)设备一逻辑像素点内能显示多少个物理像素,常见dpr为1 2 3等

思路:
  获取当前屏幕dpr,设置当前根节点的默认字体大小,其他在css中的所有px,根据屏幕放大缩小的比例乘以原来的px
export var flexible = function flexible(window, document, remUnit) {
  var docEl = document.documentElement;
  var dpr = window.devicePixelRatio || 1; // 获取当前dpr

  function setBodyFontSize() {
    if (document.body) {
      document.body.style.fontSize = 12 * dpr + 'px';
    } else {
      document.addEventListener('DOMContentLoaded', setBodyFontSize);
    }
  }

  setBodyFontSize();

  function getRemUnit(size) {
    var docEl = document.documentElement;
    var width = docEl.clientWidth;
    var height = docEl.clientHeight;
    var remUnit = size; //  竖屏

    if (width < height) {
      switch (true) {
        case width >= 1590:
          remUnit *= 1.3;
          break;

        case width <= 1034:
          remUnit *= 0.8;
          break;

        default:
          break;
      }
    } else {
      switch (true) {
        case width >= 3830:
          remUnit *= 2;
          break;

        case width >= 2550:
          remUnit *= 1.3;
          break;

        case width <= 1376:
          remUnit *= 0.8;
          break;

        default:
          break;
      }
    }

    return remUnit;
  } // set 1rem = viewWidth / 10


  function setRemUnit() {
    docEl.style.fontSize = getRemUnit(remUnit) + 'px';
  }

  setRemUnit(); // 重置字体大小

  window.addEventListener('resize', setRemUnit);
  window.addEventListener('pageshow', function (e) {
    if (e.persisted) {
      setRemUnit();
    }
  }); 

  if (dpr >= 2) {
    var fakeBody = document.createElement('body');
    var testElement = document.createElement('div');
    testElement.style.border = '.5px solid transparent';
    fakeBody.appendChild(testElement);
    docEl.appendChild(fakeBody);

    if (testElement.offsetHeight === 1) {
      docEl.classList.add('hairlines');
    }

    docEl.removeChild(fakeBody);
  }
};

我们在App.jsx中调用这个函数就可以了 flexible(window, document, 100) 100是设置根元素字体大小 不过这个函数只能对css中的px自动转换,写在行内样式中的,虽然也可以使用上述的getRemUnit,不过需要自己一个个去修改,很麻烦,,, 所以在项目初期,就要产生适配的想法,不然在后期改起来,很费时间,很费人

其他使用css适配

使用@media媒体查询
@media screen and (max-width: 2560px) {}

最后,作者想说一句,少写行内样式,不要图方便,别人改起来麻烦死了😭