flexible.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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. .match(/initial\-scale=([\d\.]+)/);
  15. if (match) {
  16. scale = parseFloat(match[1]);
  17. dpr = parseInt(1 / scale);
  18. }
  19. } else if (flexibleEl) {
  20. var content = flexibleEl.getAttribute("content");
  21. if (content) {
  22. var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
  23. var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
  24. if (initialDpr) {
  25. dpr = parseFloat(initialDpr[1]);
  26. scale = parseFloat((1 / dpr).toFixed(2));
  27. }
  28. if (maximumDpr) {
  29. dpr = parseFloat(maximumDpr[1]);
  30. scale = parseFloat((1 / dpr).toFixed(2));
  31. }
  32. }
  33. }
  34. if (!dpr && !scale) {
  35. var isAndroid = win.navigator.appVersion.match(/android/gi);
  36. var isIPhone = win.navigator.appVersion.match(/iphone/gi);
  37. var devicePixelRatio = win.devicePixelRatio;
  38. if (isIPhone) {
  39. // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
  40. if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
  41. dpr = 3;
  42. } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {
  43. dpr = 2;
  44. } else {
  45. dpr = 1;
  46. }
  47. } else {
  48. // 其他设备下,仍旧使用1倍的方案
  49. dpr = 1;
  50. }
  51. scale = 1 / dpr;
  52. }
  53. docEl.setAttribute("data-dpr", dpr);
  54. if (!metaEl) {
  55. metaEl = doc.createElement("meta");
  56. metaEl.setAttribute("name", "viewport");
  57. metaEl.setAttribute(
  58. "content",
  59. "initial-scale=" +
  60. scale +
  61. ", maximum-scale=" +
  62. scale +
  63. ", minimum-scale=" +
  64. scale +
  65. ", user-scalable=no"
  66. );
  67. if (docEl.firstElementChild) {
  68. docEl.firstElementChild.appendChild(metaEl);
  69. } else {
  70. var wrap = doc.createElement("div");
  71. wrap.appendChild(metaEl);
  72. doc.write(wrap.innerHTML);
  73. }
  74. }
  75. function refreshRem() {
  76. var width = docEl.getBoundingClientRect().width;
  77. if (width / dpr > 5760) {
  78. width = 5760 * dpr;
  79. }
  80. var rem = width / 10;
  81. docEl.style.fontSize = rem + "px";
  82. flexible.rem = win.rem = rem;
  83. }
  84. win.addEventListener(
  85. "resize",
  86. function () {
  87. clearTimeout(tid);
  88. tid = setTimeout(refreshRem, 300);
  89. },
  90. false
  91. );
  92. win.addEventListener(
  93. "pageshow",
  94. function (e) {
  95. if (e.persisted) {
  96. clearTimeout(tid);
  97. tid = setTimeout(refreshRem, 300);
  98. }
  99. },
  100. false
  101. );
  102. if (doc.readyState === "complete") {
  103. doc.body.style.fontSize = 12 * dpr + "px";
  104. } else {
  105. doc.addEventListener(
  106. "DOMContentLoaded",
  107. function (e) {
  108. doc.body.style.fontSize = 12 * dpr + "px";
  109. },
  110. false
  111. );
  112. }
  113. refreshRem();
  114. flexible.dpr = win.dpr = dpr;
  115. flexible.refreshRem = refreshRem;
  116. flexible.rem2px = function (d) {
  117. var val = parseFloat(d) * this.rem;
  118. if (typeof d === "string" && d.match(/rem$/)) {
  119. val += "px";
  120. }
  121. return val;
  122. };
  123. flexible.px2rem = function (d) {
  124. var val = parseFloat(d) / this.rem;
  125. if (typeof d === "string" && d.match(/px$/)) {
  126. val += "rem";
  127. }
  128. return val;
  129. };
  130. })(window, window["lib"] || (window["lib"] = {}));