多屏幕尺寸测试

多屏幕尺寸测试

Chrome 有一个非常诱人的功能就是能够模拟不同设备的尺寸,在 Chrome 的 Inspector 中点击toggle device mode按钮,然后就可以在不同的设备屏幕尺寸下进行调试:

无线模拟

无线模拟方案主要有三点
    http 协议修改 - userAgent
    视图渲染 - 无线模拟
    事件模拟 - touch

HTTP 协议修改

js 本身无法修改 http 协议,我们需要借助于 chrome extension,开发一个 chrome 扩展插件用于修改 http 协议,通过插件我们可以通过浏览器获取设备、通信的底层信息。开发插件是一件很简单的事件,这里涉及的重点在于修改 httt.userAgent
1
/**
2
* 更新ua
3
*/
4
function replaceHeader(requestHeaders) {
5
var newHeaders = [];
6
for (var i = 0; i < requestHeaders.length; i++)
7
if (requestHeaders[i].name != 'User-Agent')
8
newHeaders.push(requestHeaders[i]);
9
else {
10
var new_value = requestHeaders[i].value;
11
//这里将user-agent声明为iphone
12
newHeaders.push({
13
name: 'User-Agent',
14
value:
15
'Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25'
16
});
17
}
18
return newHeaders;
19
}
20
21
/**
22
* 监听通信
23
*/
24
function updateListeners() {
25
let listener = function(details) {
26
var header_map = {
27
requestHeaders: details.requestHeaders
28
};
29
if (!uaIsPhone) {
30
return header_map;
31
}
32
if (
33
details &&
34
details.url &&
35
details.requestHeaders &&
36
details.requestHeaders.length > 0
37
)
38
header_map = {
39
requestHeaders: replaceHeader(details.requestHeaders)
40
};
41
return header_map;
42
};
43
chrome.webRequest.onBeforeSendHeaders.addListener(
44
listener,
45
{
46
urls: ['http://*/*', 'https://*/*']
47
},
48
['requestHeaders', 'blocking']
49
);
50
}
Copied!
监听 chrome.webRequest.onBeforeSendHeaders,在发送前修改 ua 为无线。
服务端收到的 ua 为无线的 http 请求,判断为无线终端返回无线页面。
此时浏览器的 navigator.userAgent 还显示为 pc,为了保持与 http 请求一致,我们需要注入页面 js,来修改 navigator.user
1
function toMobile() {
2
var head = document.querySelector('head');
3
if (!head) {
4
setTimeout(turnPhone, 100);
5
return;
6
}
7
var _turnP = document.createElement('script');
8
_turnP.type = 'text/javascript';
9
_turnP.innerText = [
10
"Object.defineProperty(window.navigator, 'userAgent', { get: function(){ return 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1'; } });",
11
"Object.defineProperty(window.navigator, 'vendor', { get: function(){ return 'Apple, Inc.'; } });",
12
"Object.defineProperty(window.navigator, 'platform', { get: function(){ return 'iPhone'; } });"
13
].join('');
14
head.appendChild(_turnP);
15
}
Copied!

视图渲染

通常我们可以使用 iframe,不过这个涉及到跨域,对 dom 入侵大等一系列问题,针对这里的场景特点废弃了 iframe。使用在 dom 里渲染,首先需要修改 html 大小,这里也要通过插件,插件可以设置 content-script,并且指定其在 document_start 时执行,这样就保证了在页面返回前,就设置了 css,否则等 html 已经渲染一部分了再设置就无效了。
1
"content_scripts": [ {
2
"all_frames": true,
3
"js": [ "js/main.js" ],
4
"css": ["css/main.css"],
5
"matches": [ "http://*/*", "https://*/*" ],
6
"run_at": "document_start"
7
} ]
Copied!
main.css 里设置
1
html.terminal-mobile {
2
width: 400px !important;
3
}
Copied!
main.js 里设置
1
document.querySelector('html').setAttribute('class', 'udata-mobile');
Copied!
现在从显示宽度上,似乎像手机的宽度了,但是有些元素却超出 html 的宽度,这类是样式主要是因为 dom 设置了 position: fixed 的元素,其定位是参照 window,非 html,所以其宽度是 window.innerWidth,所以我们需要修改参照项,可以通过修改 html 的 transform
1
html.terminal-mobile {
2
width: 400px !important;
3
transform: translate3d(0px, 0px, 0px);
4
}
Copied!
现在再看,html 的内容完全参照 html 定位了
我们加上手机外框,通常会考虑会上下 padding 一定大小后使用 background-image,而这里样式我们需要在页面渲染前就设置,此时无法计算出 html.height 高度,所以只能用百分比,又不准确,所以使用 border-box
1
html.udata-mobile {
2
transform: translate3d(0px, 0px, 0px);
3
height: 100%;
4
border-left-width: 10px;
5
border-right-width: 10px;
6
border-top-width: 80px;
7
border-bottom-width: 80px;
8
box-sizing: border-box; //将border设置进html height
9
margin-left: 200px;
10
width: 400px;
11
border-color: transparent;
12
border-style: solid;
13
border-image: url(https://s.tbcdn.cn/g/udata/udata-pi/iphoneBg.png) 146 20
14
stretch;
15
background-color: rgb(255, 255, 255) !important;
16
}
Copied!
box-sizing: border-box; 将 html:100%算进了 border,再通过 border-image 来添加手机框,下图是 demo 的操作

事件模拟

Last modified 2yr ago