在方向改变时重新呈现网页的最佳方法是什么
What is the best method of re-rendering a web page on orientation change?
我有一个流畅的CSS布局,当我改变方向时,它在iphone上的表现很糟糕。(刷新后看起来很好(。
我正在使用下面的代码来刷新方向更改页面,这很好-只是感觉这样做有点错误。有什么方法可以在不重新加载整个页面的情况下实现这一点吗?这是一个移动网站,我真的不想强迫用户加载页面两次。
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
window.addEventListener(orientationEvent, function() {
window.location.reload()
}, false);
编辑:
在iphone上测试时的两个主要问题是:
我有一个100%宽的,有一个右对齐的背景图像。当我将方向从纵向更改为横向时,身体宽度保持为在纵向模式下的渲染方式,反之亦然。从横向到纵向,这更像是一个问题,因为页面太宽,而且似乎要渲染两次图像。
假设您的CSS已经在各种大小的移动设备屏幕上愉快地呈现,则需要在<头部>的模板。
例如,这将页面宽度设置为设备的屏幕宽度和100%的初始缩放。初始缩放在页面加载时应用,但在方向更改时不应用。
<meta name="viewport" content="width=device-width, initial-scale=1.0">
通过在视口中添加最大比例=1.0参数,您将强制iPad/iPhone保持缩放级别,并在方向更改时重新布局页面。这样做的缺点是它将禁用缩放。但是,其优点是可以通过媒体查询进行布局调整,以适合当前方向的方式呈现内容。你可以在这里阅读更多关于viewport的信息:选择viewport
现在转到媒体查询。您应该将媒体查询放在CSS文件的底部,并按照屏幕宽度从最小到最大的顺序。例如,取自Html5BoilerPlate CSS示例:
@media only screen and (min-width: 480px) {
/* Style adjustments for viewports 480px and over go here */
}
@media only screen and (min-width: 768px) {
/* Style adjustments for viewports 768px and over go here */
}
所以你所有的普通样式都在这之上,并且首先应用,然后如果屏幕是480px或更宽,则应用下一个样式块,然后如果页面是768px或更广,则应用最后一个样式区块。
通过将固定缩放级别合并为1.0和媒体查询,您可以在没有javascript的情况下根据屏幕大小和方向调整网站的大小。显然,你需要确保网站设计良好,这样用户就不需要缩放。如果你的网站针对移动设备进行了优化,这应该不会成为问题。
请注意:其他非safari移动浏览器可能会在不设置视口最大比例的情况下重新布局页面。但这种行为是不一致的,大多数开发人员似乎都在迎合苹果设备,即使实现比其他设备更糟糕。其他一些设备将保持缩放级别,并在方向更改时重新居中视口。但所有设备都可以将缩放级别固定为1.0。
2015更新
所有其他答案都不正确或过时了。以下是有效的:
window.addEventListener('orientationchange', function () {
var originalBodyStyle = getComputedStyle(document.body).getPropertyValue('display');
document.body.style.display='none';
setTimeout(function () {
document.body.style.display = originalBodyStyle;
}, 10);
});
该代码侦听orientationchange事件,并通过隐藏body
元素并在10毫秒后显示它来强制其重新流动。它不依赖于任何<meta>
标签或媒体查询。
其他答案建议使用媒体查询,但您已经使用了,因为您说过"刷新后看起来很好"。
其他一些答案建议使用location.reload()
。这是非常低效的,因为它会重新加载整个页面,包括图像等。特别是在移动设备上,你不想这样做。
然而,其他答案建议添加<meta name="viewport" content="width=device-width, initial-scale=1.0">
或其变体。从Safari 7开始,此功能不再有效。这是一个演示。为了确保你看到它是如何不起作用的,从横向模式下的iPad开始,加载页面,然后旋转。请注意,尽管一直使用flexbox,但页面并没有完全展开。
将其与我们在生产中使用隐藏/显示主体技术的本页进行比较。
使用了一种方法,该方法会在单个javascript堆栈帧中导致重新绘制和回流。不热衷于视口特定的答案,因为保持缩放等通常是对可访问性的要求。
$(window).on('orientationchange', function() {
document.body.style.display='none';
document.body.offsetHeight; //cause a reflow
document.body.style.display='block'; //cause a repaint
});
或非jquery等效
window.addEventListener('orientationchange', function () {
document.body.style.display='none';
document.body.offsetHeight; //cause a reflow
document.body.style.display='block'; //cause a repaint
});
根据我的经验,最好的方法是像这样使用
<meta name = "viewport" content = "user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width /">
<meta name="apple-mobile-web-app-capable" content="yes"/>
根据我的经验,像@BenSwayne那样操作不会在更改方向时重新缩放回初始比例。不知道为什么是
我也遇到过类似的问题,这就是我使用jQuery解决问题的方法。
在我的情况下,<nav>
元素的样式没有正确更改。我使用了kidkaos77代码的修改版本和$.get()
,只加载页面的某个部分:
$(window).bind("resize",function() {
//on resize reload only nav & replace
$.get("index.php" + ' nav', function(data) {
$("nav").replaceWith($(data).find("nav"));
});
});
使用这种方法,您不必重新加载整个页面,但您必须准确地指定哪些元素受到方向更改的影响,在您的情况下,似乎只需要一个div。
另一个选项可以是添加&从html元素(div、var、span等(中删除CSS类。这样,您可以只修改给您带来麻烦的元素,如果用户调整浏览器窗口的大小,您还可以调整非移动浏览器上的内容。
以下是您需要的Javascript/JQuery代码:
// Code to run when page has finished loading
$(function() {
// Add CSS-class to body depending on device platform using user agent string
// You can add more validations here and/or separate Android from iPhone or add more customized classes like "landscape_iPad", "landscape_iPhone", etc.
// You can also validate browser types and add classes like "background_IE" or "background_Chrome", etc
if ((navigator.userAgent.indexOf("iPad") != -1)) {
$("#background").addClass("landscape");
} else if ((navigator.userAgent.indexOf("Android") != -1) || (navigator.userAgent.indexOf("iPhone") != -1) ||
(navigator.userAgent.indexOf("iPhone") != -1)) {
$("body").addClass("iPhone");
}
// Get the initial orientation on iOS devices
if (!isNaN(window.orientation)) {
var orientation = ($(window).width() < 980) ? "portrait" : "landscape";
// Index php
$("#background").addClass(orientation);
} else {
// Choose layout depending on viewport/window width
var orientation = ($(window).width() < 980) ? "portrait" : "landscape";
// Index php
$("#background").addClass(orientation);
}
// Bind orientationChange (or viewport/window size changes)
if (window.onorientationchange != undefined) {
window.onorientationchange = function() {
var orientation = ($(window).width() < 980) ? "portrait" : "landscape";
// Index php
$("#background").removeClass("portrait landscape").addClass(orientation);
}
} else {
// Use landscape styling if it's wider than 980 pixels.
// This is for non mobile browsers, this way if the user resize the browser window, content will adjust too.
$(window).bind('resize', function(){
var orientation = ($(window).width() < 980) ? "portrait" : "landscape";
// Index php
$("#background").removeClass("portrait landscape").addClass(orientation);
});
}
});
下面是示例元素"background"的CSS类:
#background.portrait {
position:absolute;
top:0px;
left:0px;
width:768px;
height:946px;
z-index:0;
background:url(background.png) top center no-repeat;
}
#background.landscape {
position:absolute;
top:10px;
left:20px;
width:1024px;
height:724px;
z-index:0;
background:url(background_landscape.png) top center no-repeat;
}
通过这种方式,您可以自定义横向和纵向行为,还可以添加更多类,如:"landscape_iPhone"、"portrait_Android"或控制每个特定设备的页面渲染所需的任何类。
此外,您不需要重新加载页面,它会动态调整页面。
希望它能帮助你或其他人=(,这使我能够使用相同的HTML但不同的CSS类为每个屏幕大小、移动品牌甚至浏览器类型创建自定义网站。
试试这样的东西:
$(function(){
changeOrientation(window.orientation == 0 ? "portrait" : "landscape");
$('body').bind('orientationchange',function(event){
changeOrientation(event.orientation)
});
function changeOrientation(ori){
$("#orientation").removeClass('portrait landscape');
$("#orientation").addClass(ori);
}
});
$(window).bind('resize', function() { location.reload(); });
这个代码对我有效。
- 有条件更新d3.js力图中节点的最佳方法
- 将jQuery.ech()方法转换为本地JavaScript抽象的最佳方法是什么
- 处理浮点错误的最佳方法是什么
- 从数组中删除元素的最佳方法是:javascript/jquery
- 以编程方式填充组合框道场 (1.8) 的最佳方法是什么?
- 列出没有 mysql 的元素的最佳方法是什么
- 在jquery库中重新定义方法的最佳方法
- Javascript,用vars创建对象的最佳方法
- 使用 jQuery 从 HTML 中获取某些值的最佳方法
- 在变量中保存值的最佳方法是在应用程序关闭后使用,然后使用apachecordova在android中重新启动
- 在d3.json中使用d3.csv组合多个csv文件数据输入的最佳方法是什么
- 用jasmine测试JavaScriptUI的最佳方法
- 使用javascript:在没有阻止html标记(<b>、<p>等)的情况下,阻止脚本的最佳方法
- 如果我返回表,检查 Ajax 调用是否为 200 OK的最佳方法是什么
- JavaScript - 创建可链接函数时的最佳方法是什么
- 在上下文菜单项单击上显示侧边栏/弹出窗口的最佳方法是什么
- 在 JavaScript 中获取范围的随机数的最佳方法
- 在对象类上实现 jquery 作用域的最佳方法
- 将同步函数包装到承诺中的最佳方法是什么?
- 使用 MVC 删除 JavaScript 中硬编码字符串 Asp.Net 最佳方法