Nic*_*ick 11 html javascript android viewport ios
我正在开发一个适合特定宽度和高度的网站(885x610 div,1px边框和3px上边距).我希望用户永远不必滚动或缩放以查看整个div; 它应该始终完全可见.由于设备具有多种分辨率和宽高比,因此我想到的想法是使用JavaScript动态设置"视口"元标记.这样,div将始终具有相同的尺寸,不同的设备必须以不同的方式进行缩放,以便在视口中适合整个div.我尝试了我的想法并得到了一些奇怪的结果.
以下代码适用于第一页加载(在Android 4.4.0上的Chrome 32.0.1700.99中测试),但在刷新时,缩放级别会发生变化.此外,如果我注释掉alert它,它甚至在第一页加载时也不起作用.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0">
<script type="text/javascript">
function getViewportWidth() {
if (window.innerWidth) {
return window.innerWidth;
}
else if (document.body && document.body.offsetWidth) {
return document.body.offsetWidth;
}
else {
return 0;
}
}
function getViewportHeight() {
if (window.innerHeight) {
return window.innerHeight;
}
else if (document.body && document.body.offsetHeight) {
return document.body.offsetHeight;
}
else {
return 0;
}
}
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) {
var actual_width = getViewportWidth();
var actual_height = getViewportHeight();
var min_width = 887;
var min_height = 615;
var ratio = Math.min(actual_width / min_width, actual_height / min_height);
if (ratio < 1) {
document.querySelector('meta[name="viewport"]').setAttribute('content', 'initial-scale=' + ratio + ', maximum-scale=' + ratio + ', minimum-scale=' + ratio + ', user-scalable=yes, width=' + actual_width);
}
}
alert(document.querySelector('meta[name="viewport"]').getAttribute('content'));
</script>
<title>Test</title>
<style>
body {
margin: 0;
}
div {
margin: 3px auto 0;
width: 885px;
height: 610px;
border: 1px solid #f00;
background-color: #fdd;
}
</style>
</head>
<body>
<div>
This div is 885x610 (ratio is in between 4:3 and 16:10) with a 1px border and 3px top margin, making a total of 887x615.
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我该怎么做才能让这个网站扩展到适合宽度和高度?
可以获得一致的行为.但不幸的是,它非常复杂.我正在编写一个脚本来检测欺骗代理并相应地将视口动态地重新缩放到桌面或其他欺骗代理.我还面临着Android/Chrome以及iOS模拟器的缩放问题......
要绕过它,您需要禁用缩放和/或设置视口两次.在第一遍中,最好在<head>你现在的内联中,你设置你的比例并暂时禁用用户缩放以防止缩放问题,对所有3个比例使用相同的固定值,如:
document.querySelector('meta[name=viewport]').setAttribute('content', 'width='+width+',minimum-scale='+scale+',maximum-scale='+scale+',initial-scale='+scale);
Run Code Online (Sandbox Code Playgroud)
然后,要恢复缩放DOMContentLoaded,请使用相同的比例再次设置视口,但这次设置正常的最小/最大比例值以恢复用户缩放:
document.querySelector('meta[name=viewport]').setAttribute('content', 'width='+width+',minimum-scale=0,maximum-scale=10');
Run Code Online (Sandbox Code Playgroud)
在您的上下文中,因为布局是固定的并且大于视口,initial-scale='+scale所以可能需要更合理的替代方案DOMContentLoaded:
document.querySelector('meta[name=viewport]').setAttribute('content', 'width='+width+',minimum-scale=0,maximum-scale=10,initial-scale='+scale);
Run Code Online (Sandbox Code Playgroud)
这应该让视口在Webkit浏览器中重新调整,而不会出现缩放问题.我只说在webkit中,因为遗憾的是IE和Firefox不支持更改视口,因为视频端口,尺寸和设备像素比率的浏览器兼容性表显示:http://www.quirksmode.org/mobile/tableViewport.html
IE有自己的方式来动态更改视口,实际上IE快照模式需要响应. http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/
因此,对于IEMobile和IE SNAPMODE(IE10和11),你需要动态插入一个内嵌<style>在<head>喜欢的东西.
<script>
var s = document.createElement('style');
s.appendChild(document.createTextNode('@-ms-viewport{width:'+width+'px')+';}'));
document.head.appendChild(s);
</script>
Run Code Online (Sandbox Code Playgroud)
不幸的是,Firefox既没有:视口是一次性设置的,如上面的兼容性表所示.目前,由于缺乏其他方法,使用CSS Transform(如@imcg所指出的)是在Android或Gecko OS上改变FireFox Mobile视口的唯一方法.我刚刚测试了它,它适用于固定尺寸设计的环境.(在"响应式设计上下文"中,布局可以通过CSS Transform重新调整,例如在手机上的桌面大小,但Firefox仍然可以读取手机大小的MQ.所以这在RWD上下文中应该注意./除了webkit )
虽然,我注意到一些随机的Webkit崩溃与Android上的CSSTransform,所以我建议将Safari/Chrome/Opera的视口方法更可靠.
此外,为了获得视口宽度的跨浏览器可靠性,您还必须面对/修复内部宽度的浏览器之间的整体不一致(注意,documentElement.clientWidth在内部宽度上获得准确的布局像素宽度更加可靠)必须处理devicePixelRatioquirksmode.org表中指出的差异.
更新:实际上经过多次考虑解决我自己的Firefox问题的解决方案后,我发现了一种方法来覆盖Firefox Mobile中的视口,使用document.write(),仅应用一次:
document.write('<meta name="viewport" content="width='+width+'px,initial-scale='+scale+'">');
Run Code Online (Sandbox Code Playgroud)
刚刚在Webkit和Firefox中成功测试了这一点,没有缩放问题.我不能在Window Phones上测试,所以我不确定itf document.write适用于IEMobile ......
我知道这晚了两年,但我花了很多时间解决这个问题,并想分享我的解决方案。我发现最初的问题非常有帮助,所以我觉得发布这个答案是我回馈的方式。我的解决方案适用于 iPhone6 和 7" Galaxy Tab。我不知道它在其他设备上的表现如何,但我猜它应该主要表现。
我将视口逻辑分离到一个外部文件中,以便于重用。首先,您将如何使用代码:
<HTML>
<HEAD>
<SCRIPT type="text/javascript" src="AutoViewport.js"></SCRIPT>
</HEAD>
<BODY>
<SCRIPT>
AutoViewport.setDimensions(yourNeededWidth, yourNeededHeight);
</SCRIPT>
<!-- The rest of your HTML goes here -->
</BODY>
</HTML>
Run Code Online (Sandbox Code Playgroud)
实际上,我将所需的宽度和高度填充了少量(15 像素左右),以便我想要的显示效果很好。另请注意使用代码中您不必在 HTML 中指定视口标签。如果一个图书馆不存在,我的图书馆会自动为你创建一个。这是 AutoViewport.js:
/** Steven Yang, July 2016
Based on http://stackoverflow.com/questions/21419404/setting-the-viewport-to-scale-to-fit-both-width-and-height , this Javascript code allows you to
cause the viewport to auto-adjust based on a desired pixel width and height
that must be visible on the screen.
This code has been tested on an iPhone6 and a 7" Samsung Galaxy Tab.
In my case, I have a game with the exact dimensions of 990 x 660. This
script allows me to make the game render within the screen, regardless
of whether you are in landscape or portrait mode, and it works even
when you hit refresh or rotate your device.
Please use this code freely. Credit is appreciated, but not required!
*/
function AutoViewport() {}
AutoViewport.setDimensions = function(requiredWidth, requiredHeight) {
/* Conditionally adds a default viewport tag if it does not already exist. */
var insertViewport = function () {
// do not create if viewport tag already exists
if (document.querySelector('meta[name="viewport"]'))
return;
var viewPortTag=document.createElement('meta');
viewPortTag.id="viewport";
viewPortTag.name = "viewport";
viewPortTag.content = "width=max-device-width, height=max-device-height,initial-scale=1.0";
document.getElementsByTagName('head')[0].appendChild(viewPortTag);
};
var isPortraitOrientation = function() {
switch(window.orientation) {
case -90:
case 90:
return false;
}
return true;
};
var getDisplayWidth = function() {
if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
if (isPortraitOrientation())
return screen.width;
else
return screen.height;
}
return screen.width;
}
var getDisplayHeight = function() {
if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
if (isPortraitOrientation())
return screen.height;
else
return screen.width;
}
// I subtract 180 here to compensate for the address bar. This is imperfect, but seems to work for my Android tablet using Chrome.
return screen.height - 180;
}
var adjustViewport = function(requiredWidth, requiredHeight) {
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)){
var actual_height = getDisplayHeight();
var actual_width = getDisplayWidth();
var min_width = requiredWidth;
var min_height = requiredHeight;
var ratio = Math.min(actual_width / min_width, actual_height / min_height);
document.querySelector('meta[name="viewport"]').setAttribute('content', 'initial-scale=' + ratio + ', maximum-scale=' + ratio + ', minimum-scale=' + ratio + ', user-scalable=yes, width=' + actual_width);
}
};
insertViewport();
adjustViewport(requiredWidth, requiredHeight);
window.addEventListener('orientationchange', function() {
adjustViewport(requiredWidth, requiredHeight);
});
};
Run Code Online (Sandbox Code Playgroud)
如果您将我的代码与问题中找到的原始代码密切比较,您会注意到一些差异。例如,我从不依赖视口宽度或高度。相反,我依赖于屏幕对象。这很重要,因为当您刷新页面或旋转屏幕时,视口的宽度和高度可能会改变,但 screen.width 和 screen.height 永远不会改变。你会注意到的下一件事是我不检查 (ratio<1)。刷新或旋转屏幕时,该检查导致不一致,因此我将其删除。此外,我还包含了一个用于屏幕旋转的处理程序。
最后,我要感谢创建这个问题的人打下了基础,这为我节省了时间!
将 div 父元素(html和body)的高度和宽度设置为 100%,并将边距归零。
html, body {
margin: 0;
height: 100%;
width: 100%;
}
Run Code Online (Sandbox Code Playgroud)
接下来,因为您想要在 div 上添加边框,所以需要确保在指定元素的宽度/高度时包含边框宽度,以便box-sizing: border-box在 div 上执行此操作。
因为您希望 div 的上边距为 3px,所以 div 的相对定位将导致高度高出 3px。要解决此问题,请在 div 上使用绝对定位并将顶部、左侧和底部设置为 0。
div {
position: absolute;
top: 3px;
left: 0;
bottom: 0;
box-sizing: border-box;
width: 100%;
border: 1px solid #f00;
background-color: #fdd;
}
Run Code Online (Sandbox Code Playgroud)
这是一个工作示例。
更新:我想我误解了这个问题。这是根据设备视口调整“缩放”的示例代码
http://jpanagsagan.com/viewport/index2.html
请注意,我使用 jquery 附加元标记,因为我在使用普通附加时遇到问题。
我注意到的一件事是,如果您在 HTML 中进行硬编码并通过 JS 进行更改,则该文档将不会应用更正(需要验证)。如果 HTML 中没有先前的标签,我可以通过 JS 更改它,因此我使用了追加。
您可以使用该比率,但在示例中我使用视口的宽度除以 div 的宽度。
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
43431 次 |
| 最近记录: |