Convert relative/viewport size to fixed size on page load using JavaScript/JQuery

回眸只為那壹抹淺笑 提交于 2019-12-08 08:57:29

问题


hope you are having a nice day. I am currently developing a website, in which pretty much all of my measurements (font size, padding, margin, width, height, etc) are made with the viewport units vw and vh.

I use these units because they are the best to make the page look like what I want on different screen resolutions, unlike pixel sizes.

What I was wondering if it's possible, is to after the page loads, get the non-relative value of all those measurements (for example, if I say 1vw, and my screen is 1000px, the non-relative value should be 10px) and replace the relative values on my css3 sheet with those. This may sound ridiculous, but my point with this is to allow the user to zoom in and out of the page, and have things actually zoom in or out. currently, no matter what kind of zooming the user does, the page stays the same except for a repeating image I have.

I would like to do this in javascript, since its the language I know the most for client-side scripts in html, due to my java origins.

Alternatively, maybe there is a feature I dont know that simply ignores the relative values when zooming in? if so, please let me know.


回答1:


That would be something like this (tested in Chrome and IE); it adapts to the viewport on page load and reload, but doesn't adapt to subsequent viewport resizes and zooms.

<!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>

Just to explain what's happening: this checks the current viewport size, then runs through all the stylesheets, looking for properties that have a value set in viewport units, converts the value to pixels, and adds the converted css rules to a new stylesheets that is appended after the other stylesheets.

Of course, if only a few styles need updating, you could put them together in a seperate stylesheet, and have the script only look at those. Or you could even just add the styles verbatim, like:

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

Also, don't set any sizes inside media queries; that would change the lay-out while resizing and zooming.



来源:https://stackoverflow.com/questions/30503301/convert-relative-viewport-size-to-fixed-size-on-page-load-using-javascript-jquer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!