flexible.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. (function(win, lib) {
  2. var doc = win.document;
  3. var docEl = doc.documentElement;
  4. var metaEl = doc.querySelector('meta[name="viewport"]');
  5. var flexibleEl = doc.querySelector('meta[name="flexible"]');
  6. var dpr = 0;
  7. var scale = 0;
  8. var tid;
  9. var flexible = lib.flexible || (lib.flexible = {});
  10. if (metaEl) {
  11. console.warn("将根据已有的meta标签来设置缩放比例");
  12. var match = metaEl
  13. .getAttribute("content")
  14. // eslint-disable-next-line no-useless-escape
  15. .match(/initial\-scale=([\d\.]+)/);
  16. if (match) {
  17. scale = parseFloat(match[1]);
  18. dpr = parseInt(1 / scale);
  19. }
  20. } else if (flexibleEl) {
  21. var content = flexibleEl.getAttribute("content");
  22. if (content) {
  23. // eslint-disable-next-line no-useless-escape
  24. var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
  25. // eslint-disable-next-line no-useless-escape
  26. var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
  27. if (initialDpr) {
  28. dpr = parseFloat(initialDpr[1]);
  29. scale = parseFloat((1 / dpr).toFixed(2));
  30. }
  31. if (maximumDpr) {
  32. dpr = parseFloat(maximumDpr[1]);
  33. scale = parseFloat((1 / dpr).toFixed(2));
  34. }
  35. }
  36. }
  37. if (!dpr && !scale) {
  38. // eslint-disable-next-line no-unused-vars
  39. var isAndroid = win.navigator.appVersion.match(/android/gi);
  40. var isIPhone = win.navigator.appVersion.match(/iphone/gi);
  41. var devicePixelRatio = win.devicePixelRatio;
  42. if (isIPhone) {
  43. // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
  44. if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
  45. dpr = 3;
  46. } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {
  47. dpr = 2;
  48. } else {
  49. dpr = 1;
  50. }
  51. } else {
  52. // 其他设备下,仍旧使用1倍的方案
  53. dpr = 1;
  54. }
  55. scale = 1 / dpr;
  56. }
  57. docEl.setAttribute("data-dpr", dpr);
  58. if (!metaEl) {
  59. metaEl = doc.createElement("meta");
  60. metaEl.setAttribute("name", "viewport");
  61. metaEl.setAttribute(
  62. "content",
  63. "initial-scale=" +
  64. scale +
  65. ", maximum-scale=" +
  66. scale +
  67. ", minimum-scale=" +
  68. scale +
  69. ", user-scalable=no"
  70. );
  71. if (docEl.firstElementChild) {
  72. docEl.firstElementChild.appendChild(metaEl);
  73. } else {
  74. var wrap = doc.createElement("div");
  75. wrap.appendChild(metaEl);
  76. doc.write(wrap.innerHTML);
  77. }
  78. }
  79. function refreshRem() {
  80. var width = docEl.getBoundingClientRect().width;
  81. // 最小1366px,最大适配2560px
  82. if (width / dpr < 1366) {
  83. width = 1366 * dpr;
  84. } else if (width / dpr > 2560) {
  85. width = 2560 * dpr;
  86. }
  87. // 设置成24等份,设计稿时1920px的,这样1rem就是80px
  88. var rem = width / 24;
  89. docEl.style.fontSize = rem + "px";
  90. flexible.rem = win.rem = rem;
  91. }
  92. win.addEventListener(
  93. "resize",
  94. function() {
  95. clearTimeout(tid);
  96. tid = setTimeout(refreshRem, 300);
  97. },
  98. false
  99. );
  100. win.addEventListener(
  101. "pageshow",
  102. function(e) {
  103. if (e.persisted) {
  104. clearTimeout(tid);
  105. tid = setTimeout(refreshRem, 300);
  106. }
  107. },
  108. false
  109. );
  110. if (doc.readyState === "complete") {
  111. doc.body.style.fontSize = 12 * dpr + "px";
  112. } else {
  113. doc.addEventListener(
  114. "DOMContentLoaded",
  115. // eslint-disable-next-line no-unused-vars
  116. function(e) {
  117. doc.body.style.fontSize = 12 * dpr + "px";
  118. },
  119. false
  120. );
  121. }
  122. refreshRem();
  123. flexible.dpr = win.dpr = dpr;
  124. flexible.refreshRem = refreshRem;
  125. flexible.rem2px = function(d) {
  126. var val = parseFloat(d) * this.rem;
  127. if (typeof d === "string" && d.match(/rem$/)) {
  128. val += "px";
  129. }
  130. return val;
  131. };
  132. flexible.px2rem = function(d) {
  133. var val = parseFloat(d) / this.rem;
  134. if (typeof d === "string" && d.match(/px$/)) {
  135. val += "rem";
  136. }
  137. return val;
  138. };
  139. })(window, window["lib"] || (window["lib"] = {}));