1

希望你今天过得愉快。我目前正在开发一个网站,其中几乎所有的测量值(字体大小、填充、边距、宽度、高度等)都是使用视口单位 vw 和 vh 进行的。

我使用这些单位是因为它们最能使页面在不同的屏幕分辨率上看起来像我想要的,与像素大小不同。

我想知道是否有可能,是在页面加载后,获取所有这些测量值的非相对值(例如,如果我说 1vw,而我的屏幕是 1000px,那么非相对值应该是 10px)和用那些替换我的css3工作表上的相对值。这听起来可能很荒谬,但我的观点是允许用户放大和缩小页面,并让事物实际放大或缩小。目前,无论用户进行何种缩放,页面都保持不变,除了我拥有的重复图像。

我想在 javascript 中执行此操作,因为由于我的 java 起源,它是我最了解 html 客户端脚本的语言。

或者,也许有一个我不知道的功能在放大时会忽略相对值?如果是这样,请告诉我。

4

1 回答 1

1

那将是这样的(在 Chrome 和 IE 中测试);它适应页面加载和重新加载时的视口,但不适应随后的视口调整大小和缩放。

<!DOCTYPE HTML>
<HTML>
<HEAD>
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=ISO-8859-1">
<META NAME="viewport" CONTENT="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
BODY {font-size: 2vw;}
DIV {width: 50vw; height: 66vh; background-color: pink; overflow: hidden;}
H1 {font-size: 200%; font-weight: bold; margin-bottom: -.5vw}
@media screen and (min-width: 500px) {H1 {color: blue;}}
H2 {font-size: 4vmin; font-style: italic;}
P {font-size: 100%; line-height: 1.5em;}
</STYLE>
<SCRIPT>
function fixedSizes()
{
    var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    var h = window.innerHeight || document.documentElement.clientHeight || document.body.clientheight;
    var units = {vw: w / 100, vh: h / 100, vmin: (w > h ? h : w) / 100, vmax: (w > h ? w : h) / 100};
    var sheet = addSheet();

    for (var s = 0; s < document.styleSheets.length - 1; s++)
    {
        var rules = document.styleSheets[s].cssRules || document.styleSheets[s].rules;

        for (var r = 0; r < rules.length; r++)
        {
            var rule = rules[r];

            if (rule.type == CSSRule.STYLE_RULE)
            {
                var selector = rule.selectorText;
                var styles = rule.style.cssText.match(/[\w-]+\s?:\s?-?[\d\.]+(vw|vh|vmin|vmax)/g);

                for (var t = 0; styles && t < styles.length; t++)
                {
                    var style = styles[t];
                    var prop = style.match(/^[\w-]*/)[0];
                    var unit = style.match(/(vw|vh|vmin|vmax)$/)[0];
                    var val = parseFloat(style.match(/-?[\d\.]+(vw|vh|vmin|vmax)/)[0]) * units[unit];
                    addStyle(sheet, selector, prop + ": " + val + "px");
                }
            }
        }
    }

    function addSheet()
    {
        var s = document.createElement("style");
        s.type = "text/css";
        s.rel = "stylesheet";
        s.media = "screen";
        document.getElementsByTagName("head")[0].appendChild(s);
        return(document.styleSheets[document.styleSheets.length - 1]);
    }

    function addStyle(sheet, selector, style)
    {
        if (sheet.addRule)
        {
            sheet.addRule(selector, style);
        }
        else if (sheet.insertRule)
        {
            sheet.insertRule(selector + " { " + style + " }");
        }
    }       
}

if (CSSRule)
{
    if (document.addEventListener)
    {
        document.addEventListener("DOMContentLoaded", fixedSizes, false);
    }
    else if (window.attachEvent)
    {
        window.attachEvent("onload", fixedSizes);
    }
}
</SCRIPT>
</HEAD>
<BODY>
<DIV>
<H1>Viewport Units</H1>
<H2>Converted to Pixel Values</H2>
<P>Probably the best way to do this for fonts,<BR>is to set the font sizes as percentages,<BR>
   and then have javascript change the BODY font size.</P>
</DIV>
</BODY>
</HTML>

只是为了解释发生了什么:这会检查当前视口大小,然后遍历所有样式表,查找在视口单位中设置了值的属性,将值转换为像素,并将转换后的 css 规则添加到新样式表中附加在其他样式表之后。

当然,如果只有少数样式需要更新,您可以将它们放在一个单独的样式表中,让脚本只查看这些样式。或者您甚至可以逐字添加样式,例如:

addStyle(document.styleSheets[0], "H1", "font-size: " + w * 0.04 + "px");
addStyle(document.styleSheets[0], "P", "font-size: " + w * 0.02 + "px");

另外,不要在媒体查询中设置任何大小;这会在调整大小和缩放时改变布局。

于 2015-05-30T04:06:11.210 回答