必须指出,实际上并没有一种确切的方法可以判定终端是否一个桌面浏览器,但是,我们总是可以把多种条件的组合一起去检查,进而来综合判断出,对方终端是否一个非移动类型的终端。这里尝试列出几点:
- ua 字符串没有返回 Android/iPhone/WinPhone 等特征的,很可能是桌面浏览器;
- window.screenX 该值返回浏览器窗体左上角在屏幕的坐标位置。因为移动终端通常总是独占屏幕的,也是在0, 0的坐标。如果 screenX 返回非 0,很可能是桌面浏览器;
- window.devicePixelRatio and screen.width 若然屏幕密度 devicePixelRatio 为 1,并且等于屏幕分辨率 screen.width,很可能是桌面浏览器;
- 分辨率能不能判断是否移动终端?有些手机的屏幕非常高,据此来判断也不容易;
- window.orientation 桌面浏览器很少是 portrait 纵向的。
外国已经有人利用以上的特性写成一个 js 库,源码如下:
/* ReView.js 0.65b. The Responsive Viewport. responsiveviewport.com. Developed by Edward Cant. @opticswerve. */ function Viewport() { this.viewport = function(a) { var b = document, d = b.documentElement; b.head = b.head || b.getElementsByTagName("head")[0]; var e = screen, c = this, f = window; c.bScaled = !1; c.bSupported = !0; b.addEventListener === a ? c.bSupported = !1 : b.querySelector === a ? c.bSupported = !1 : f !== parent ? c.bSupported = !1 : f.orientation === a && (c.bSupported = !1); c.updateOrientation(); c.updateScreen(); c.dpr = 1; var g = f.devicePixelRatio; g === a ? c.bSupported = !1 : c.dpr = g; c.fromHead(); this.meta !== a && (c.iHeight = c.height, c.iMaxScale = c.maxScale, c.iMinScale = c.minScale, c.iUserScalable = c.bUserScalable, c.iWidth = c.width); c.defaultWidth = 980; e.width > c.defaultWidth && (c.defaultWidth = e.width); e.height > c.defaultWidth && (c.defaultWidth = e.height); c.ready(function() { if (c.bSupported) { if (f.screenX !== 0) c.bSupported = false; else if (c.width !== a) { var e; if (d.offsetHeight <= d.clientHeight) { e = d.style.height; d.style.height = d.clientHeight + 128 + "px" } if (c.width === "device-width") { if (d.clientWidth !== c.screenWidth) c.bSupported = false } else if (c.width !== d.clientWidth) c.bSupported = false; e === "" ? d.style.height = "auto" : e !== a && (d.style.height = e) } if (c.bSupported) { b.addEventListener("touchend", function() { var b = (new Date).getTime(); if (c.lastTouch !== a && b - c.lastTouch < 500 && c.bUserScalable === true) c.bScaled = true; c.lastTouch = b }, false); b.addEventListener("gestureend", function(a) { if (a.scale !== 1 && c.bUserScalable === true) c.bScaled = true }, false); b.addEventListener("resize", function() { c.updateCheck() }, false); b.addEventListener("orientationchange", function() { var b = c.orientation; c.updateOrientation(); if (b !== c.orientation) { c.updateScreen(); if (c.bUserScalable === true) c.bScaled = true; c.orientationChangePolicy !== a && c.orientationChangePolicy() } }, false) } } c.readyPolicy !== a && c.readyPolicy() }) }; this.fromContentString = function(a) { for (var a = a.split(","), b, d, e = 0; e < a.length; e++) b = a[e].split("="), 2 === b.length && (d = b[0].trim(), b = b[1].trim(), isNaN(parseFloat(b)) || (b = parseFloat(b)), "width" === d ? this.width = b : "height" === d ? this.height = b : "initial-scale" === d ? this.initialScale = b : "maximum-scale" === d ? this.maxScale = b : "minimum-scale" === d ? this.minScale = b : "user-scalable" === d && (this.bUserScalable = "no" === b ? !1 : !0)) }; this.fromHead = function() { var a = this.meta = document.head.querySelector("meta[name=viewport]"); null === a ? this.meta = void 0 : a.hasAttribute("content") && this.fromContentString(a.getAttribute("content")) }; this.ready = function(a) { var b = document; b.addEventListener && b.addEventListener("DOMContentLoaded", function() { b.removeEventListener("DOMContentLoaded", arguments.callee, !1); a() }, !1) }; this.setDefault = function(a, b) { this.bUserScalable = !0; this.height = void 0; this.maxScale = 5; this.minScale = 0.25; this.width = this.defaultWidth; this.update(a, b) }; this.setMobile = function(a, b) { this.bScaled ? b() : (void 0 === this.iWidth ? (this.bUserScalable = !1, this.height = void 0, this.minScale = this.maxScale = 1, this.width = "device-width") : (this.bUserScalable = this.iUserScalable, this.height = this.iHeight, this.maxScale = this.iMaxScale, this.minScale = this.iMinScale, this.width = this.iWidth), this.update(a, b)) }; this.toString = function() { var a = ""; void 0 !== this.width && (a += "width=" + this.width + ", "); void 0 !== this.height && (a += "height=" + this.height + ", "); void 0 !== this.maxScale && (a += "maximum-scale=" + this.maxScale + ", "); void 0 !== this.minScale && (a += "minimum-scale=" + this.minScale + ", "); !0 === this.bUserScalable ? a += "user-scalable=yes" : !1 === this.bUserScalable && (a += "user-scalable=no"); return a }; this.update = function(a, b) { var d = this; if (d.bSupported) { d.updateFailure = b; d.updateSuccess = a; var e = d.width; "device-width" === e && (e = d.screenWidth); e = d.prevWidth; "device-width" === e ? e = d.screenWidth : void 0 === e && (e = document.documentElement.clientWidth); d.updateMeta(); d.updateTimeout = setTimeout(function() { d.updateCheck() }, 500) } else b() }; this.updateCheck = function() { if (void 0 !== this.updateTimeout) { var a = !1, b = document.documentElement.clientWidth; this.width === b ? a = !0 : "device-width" === this.width && this.screenWidth === b && (a = !0); clearTimeout(this.updateTimeout); this.updateTimeout = void 0; a ? (this.prevWidth = this.width, this.updateSuccess(), this.viewportChange()) : (this.bSupported = !1, this.updateFailure()); this.updateSuccess = this.updateFailure = void 0 } }; this.updateMeta = function() { var a = document, b = this.meta; void 0 === b ? (b = this.meta = a.createElement("meta"), b.setAttribute("name", "viewport"), b.setAttribute("content", this.toString()), a.head.appendChild(b)) : b.setAttribute("content", this.toString()) }; this.updateOrientation = function() { var a = window.orientation; this.orientation = a = 0 === a || 180 === a ? "portrait" : 90 === a || -90 === a ? "landscape" : document.documentElement.clientWidth > document.documentElement.clientHeight ? "landscape" : "portrait" }; this.updateScale = function() { this.scale = this.screenWidth / window.innerWidth }; this.updateScreen = function() { var a = this.screenHeight = screen.height, b = this.screenWidth = screen.width; "portrait" === this.orientation ? b > a && (this.screenHeight = b, this.screenWidth = a) : b < a && (this.screenHeight = b, this.screenWidth = a) }; this.viewportChange = function() { var a = document.createEvent("Event"); a.initEvent("viewportChange", !0, !0); a.bUserScalable = this.bUserScalable; a.maxScale = this.maxScale; a.minScale = this.minScale; a.width = this.width; document.dispatchEvent(a) }; return !0 } var reView; (function(a) { reView = new ReView; if (reView.v.bSupported) try { if ("sessionStorage" in a && null !== a.sessionStorage) { var b = sessionStorage.getItem("reViewMode"); "core" === reView.mode && "default" === b ? reView.setDefault() : "default" === reView.mode && "core" === b && reView.setCore() } else reView.v.bSupported = !1 } catch (d) { reView.v.bSupported = !1 } })(window); function ReView() { this.mode = "default"; this.v = new Viewport; this.v.viewport(); this.v.readyPolicy = function() { reView.ready() }; this.v.bSupported && "device-width" === this.v.width && (this.mode = "core"); this.failure = function() { var a = reView; a.mode === "default" && a.v.iWidth !== void 0 && window.location.reload(); a.failurePolicy !== void 0 && a.failurePolicy() }; this.ready = function() { var a = document.getElementsByClassName("reView"), b = a.length, d = reView; if (d.v.bSupported) { for (d.mode === "default" && sessionStorage.getItem("reViewMode") !== "core" && d.success(); b--;) a[b].style.display = "inline"; document.body.addEventListener("click", function(a) { if (a.target.hasAttribute("class") && a.target.getAttribute("class").indexOf("reView") > -1) { a.preventDefault(); d.mode === "default" ? d.setCore() : d.mode === "core" && d.setDefault() } }) } else for (screen.width >= 1024 && d.success(); b--;) a[b].style.display = "none" }; this.setCore = function() { if (this.mode === "core") this.success(); else if (this.v.bSupported) { try { sessionStorage.setItem("reViewMode", "core") } catch (a) {} this.v.setMobile(function() { reView.mode = "core"; reView.success() }, reView.failure) } else this.failure() }; this.setDefault = function() { if (this.mode === "default") this.success(); else if (this.v.bSupported) { try { sessionStorage.setItem("reViewMode", "default") } catch (a) {} this.v.setDefault(function() { reView.mode = "default"; reView.success() }, reView.failure) } else this.failure() }; this.success = function() { var a = reView; a.v.bSupported && a.updateAnchors(); a.successPolicy !== void 0 && a.successPolicy() }; this.updateAnchors = function() { var a = document.getElementsByClassName("reView"), b = a.length; if (this.mode === "core") for (; b--;) a[b].innerHTML = a[b].hasAttribute("data-coreText") ? a[b].getAttribute("data-coreText") : "Default View"; else for (; b--;) a[b].innerHTML = a[b].hasAttribute("data-defaultText") ? a[b].getAttribute("data-defaultText") : "Core View" }; return !0 };
随着有越来越多的高分辨率设备,所以依靠分辨率的这个方法也不灵了。
时间: 2024-09-17 04:23:18