在方向改变时重新渲染网页的最佳方法是什么?
我有一个流畅的 CSS 布局,当我改变方向时,它在 iPhone 上渲染得很糟糕。 (刷新后看起来不错)。
我使用下面的代码来刷新方向更改的页面,效果很好 - 只是感觉这样做有点不对。有没有什么方法可以实现这一点而无需重新加载整个页面?这是一个移动网站,我真的不想强迫用户加载页面两次。
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
window.addEventListener(orientationEvent, function() {
window.location.reload()
}, false);
编辑:
在 iPhone 上测试时的两个主要问题是:
我的宽度为 100%,背景图像右对齐。 当我将方向从纵向更改为横向时,主体宽度保持在纵向模式下呈现的方式,反之亦然。从横向到纵向,这更是一个问题,因为页面太宽,并且似乎渲染了两次图像。
I have a fluid CSS layout which is rendering badly on an iphone when I change the orientation. (It looks fine when it is refreshed).
I am using the code below to refresh the page on orientation change, which works fine - it just feels a little wrong doing so. Is there any way of achieving this without having to reload the entire page? It is a mobile site, I don't really want to force the user to load the page twice.
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
window.addEventListener(orientationEvent, function() {
window.location.reload()
}, false);
Edit:
The two main issues when testing on an iphone are:
I have a which is 100% width, with a right aligned background image.
When I change the orientation from portrait to landscape the body width remains as how it rendered on portrait mode and vice versa. It is more of an issue from landscape to portrait as the page is too wide and it seems to render the images twice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
假设您的 CSS 已经在各种尺寸的移动设备屏幕上顺利呈现,您需要在 中定义视口。你的模板。
例如,这将页面宽度设置为设备的屏幕宽度,并将初始缩放设置为 100%。初始缩放在页面加载时应用,但在方向更改时不应用。
通过向视口添加 Maximum-scale=1.0 参数,您将强制 iPad/iPhone 保持缩放级别并在方向更改时重新布局页面。这样做的缺点是它将禁用缩放。但是,优点是您可以使用媒体查询进行布局调整,以适合当前方向的方式呈现内容。您可以在此处阅读有关视口的更多信息:选择 ViewPort< /a>
现在进入媒体查询。您应该将媒体查询放在 CSS 文件的底部,并按照屏幕宽度从最小宽度到最大宽度的顺序。例如,取自 Html5BoilerPlate CSS 示例:
因此,所有正常样式都在此之上并首先应用,然后如果屏幕为 480px 或更宽,则应用下一个样式块,如果屏幕为 768px 或更宽,则应用最后一个样式块。
通过将固定缩放级别设置为 1.0 和媒体查询相结合,您可以使您的网站响应式地调整大小以适应屏幕尺寸和方向,而无需使用 JavaScript。显然,您需要确保网站设计良好,以便用户不需要缩放。如果您的网站针对移动设备进行了优化,那么这应该不是问题。
请注意:其他非 safari 移动浏览器可能会重新布局页面,而不在视口上设置最大比例。但这种行为是不一致的,大多数开发人员似乎都迎合苹果设备,即使实现比其他设备差。当方向改变时,其他一些设备将保持缩放级别并重新调整视口的位置。但所有设备都可以将缩放级别固定为 1.0。
Assuming your CSS is already happily rendering on your various size mobile device screens, you need to define the viewport in the <head> of your template.
Example, this sets the page width to be the device's screen width and an initial zoom of 100%. Initial zoom is applied at page load, but not when the orientation is changed.
By adding a maximum-scale=1.0 parameter to the viewport you will force the iPad/iPhone to maintain the zoom level and re-layout the page on orientation change. The disadvantage of this is that it will disable zooming. However, the advantage is that you can make layout adjustments with media queries to present the content in a suitable fashion for the current orientation. You can read more about viewport here: Choosing a ViewPort
Now onto media queries. You should put media queries at the bottom of your CSS file and in the order of smallest width to largest width for screen widths. For example, taken from the Html5BoilerPlate CSS example:
So all your normal styles are above this and applied first, then if the screen is 480px or wider the next block of styles are applied, then if the screen is 768px or wider the last block of styles are applied.
By combining the fixed zoom level to 1.0 and the media-queries, you can make your site responsively resize to the screen size and orientation without javascript. Obviously you need to make sure the site is then well designed so users don't need zooming. If your site is optimized for mobile this shouldn't be a problem.
Please note: other non-safari mobile browsers may re-layout the page without setting the maximum-scale on the viewport. But this behavior is inconsistent and most developers seem to cater to apple devices even if the implementation is worse than other devices. Some other devices would maintain the zoom level and recenter the viewport when the orientation changes. But all devices are ok to fix the zoom level to 1.0.
2015 更新
所有其他答案都不正确或已过时。这是有效的:
该代码监听 orientationchange 事件并强制重新执行通过隐藏
body
元素并在 10 毫秒后显示它来控制其流程。它不依赖于任何标签或媒体查询。
其他答案建议使用媒体查询,但您已经使用它们,因为您说“刷新后看起来很好”。
一些其他答案建议使用
location.reload()
。这是非常低效的,因为它将重新加载整个页面,包括图像等。特别是在移动设备上,您不想这样做。还有其他答案建议添加
或其变体。从 Safari 7 开始,这不再有效。这是一个演示。为了确保您明白它是如何不起作用的,请从 iPad 的横向模式开始,加载页面,然后旋转。请注意,尽管一直使用 Flexbox,但页面并未扩展到完整高度。
与此页面进行比较,我们在生产中使用隐藏/显示正文技术。
2015 update
All the other answers are incorrect or outdated. Here's what works:
The code listens to the orientationchange event and forces a re-flow of the
body
element by hiding it and showing it 10 milliseconds later. It does not depend on any<meta>
tags or media queries.Other answers suggested using media queries, but you already use them, since you said "It looks fine when it is refreshed".
Some other answers suggest using
location.reload()
. This is very inefficient, because it will reload the entire page, including images etc. Especially on mobile, you don't want to do that.Yet other answers suggested adding
<meta name="viewport" content="width=device-width, initial-scale=1.0">
or variations thereof. As of Safari 7, this no longer works. Here's a demo. To make sure you see how it doesn't work, start with the iPad in landscape mode, load the page, then rotate. Notice the page doesn't expand to full height, despite using flexbox all the way.Compare that to this page, where we use the hide/show body technique in production.
使用了在单个 JavaScript 堆栈帧中导致重绘和回流的方法。不热衷于视口特定的答案,因为通常需要可访问性来保持捏缩放等。
或非 jquery 等效项
Used a method that causes a repaint and a reflow in a single javascript stack frame. Not keen on viewport specific answers as it is often a requirement for accessibility to keep pinch zooming etc.
Or non-jquery equivalent
根据我的经验,最好的方法是像这样做,
当你改变方向时,像@BenSwayne那样做不会重新缩放回初始比例。不知道为什么
In my experience the best way is to have it like this
Doing it like @BenSwayne in my experience does not rescale back to the initial scale when you change the orientation. Dont know why that is
我有一个类似的问题,这就是我用 jQuery 修复它的方法。
就我而言,我的
使用此方法,您不必重新加载整个页面,但您会准确指定哪些元素受到方向变化的影响,在您的情况下,您似乎只需要一个 div。
I had a similar problem and this is how I fixed it with jQuery.
In my case the styles were not changing correctly for my
<nav>
element. I used a modified version of kidkaos77's code combined with$.get()
to only load a certain part of the page:With this method you don't have to reload the entire page, but you would have to specify exactly which elements are being affected by the orientation change, which in your case it seems like you just need one div.
另一种选择可能是添加 &从 html 元素(div、var、span 等)中删除 CSS 类。
这样您就可以只修改给您带来麻烦的元素,并且如果用户调整浏览器窗口的大小,您还可以调整非移动浏览器上的内容。
这是您需要的 Javascript/JQuery 代码:
这是示例元素“背景”的 CSS 类:
这样您就可以自定义横向和纵向行为,并且可以添加更多类,例如:“landscape_iPhone”、“portrait_Android”或者您需要控制每个特定设备的页面呈现的任何内容。
此外,您不需要重新加载页面,它会即时调整。
希望它对您或其他人有所帮助 =),这使我能够使用相同的 HTML 但不同的 CSS 类创建针对每个屏幕尺寸、移动品牌甚至浏览器类型定制的网站。
Another option could be to add & remove CSS classes from your html elements (div, var, span, etc).
This way you can modify only the elements that are giving you troubles and also you can adjust the content on non-mobile browsers if the user resize the browser window.
Here is the Javascript/JQuery code you will need:
And here is the CSS class for the sample element "background":
This way you can customize the landscape and portrait behavior and you can add more clases like: "landscape_iPhone", "portrait_Android" or whatever you need to control the rendering of the page for each specific device.
Also, you don't need to reload the page, it will adjust it on the fly.
Hope it helps you or someone else =), this has enabled me to create web sites customized for each screen size, mobile brand or even browser type with the same HTML but different CSS classes.
尝试这样的事情:
Try something like this:
这段代码对我有用。
This code worked for me.