Преобразование относительного размера/размера области просмотра в фиксированный размер при загрузке страницы с использованием JavaScript/JQuery

надеюсь, у вас хороший день. В настоящее время я разрабатываю веб-сайт, в котором почти все мои измерения (размер шрифта, отступы, поля, ширина, высота и т. д.) выполняются с единицами просмотра vw и vh.

Я использую эти единицы, потому что они лучше всего подходят для того, чтобы страница выглядела так, как я хочу, на разных разрешениях экрана, в отличие от размеров пикселей.

Мне было интересно, возможно ли это, чтобы после загрузки страницы получить неотносительное значение всех этих измерений (например, если я скажу 1vw, а мой экран 1000 пикселей, неотносительное значение должно быть 10 пикселей) и замените относительные значения на моем листе css3 теми. Это может звучать нелепо, но моя цель состоит в том, чтобы позволить пользователю увеличивать и уменьшать масштаб страницы, а также увеличивать или уменьшать масштаб. в настоящее время, независимо от того, какое масштабирование делает пользователь, страница остается неизменной, за исключением повторяющегося изображения, которое у меня есть.

Я хотел бы сделать это в javascript, так как это язык, который я знаю больше всего для клиентских скриптов в html из-за моего происхождения java.

В качестве альтернативы, может быть, есть функция, о которой я не знаю, которая просто игнорирует относительные значения при увеличении? Если это так, пожалуйста, дайте мне знать.


person RaKXeR    schedule 28.05.2015    source источник
comment
черт возьми, это должно быть действительно сложный вопрос, даже не предположение :| я буду ждать   -  person RaKXeR    schedule 29.05.2015
comment
Почему? Вы я использую эти единицы, потому что они лучше всего подходят для того, чтобы страница выглядела так, как я хочу, при разных разрешениях экрана, в отличие от размеров в пикселях. Итак, почему вы меняете размер на пиксели при загрузке страницы? Какая польза? Или проблема, которую вы пытаетесь решить? Потому что это действительно не имеет смысла.   -  person David says reinstate Monica    schedule 30.05.2015
comment
@DavidThomas Страница выглядит нормально и адаптируется к разным размерам разрешения (как я и хотел), но не позволяет пользователю увеличивать/уменьшать масштаб. Если пользователь находит шрифты слишком большими/маленькими, он не может изменить размер чего-либо, потому что он изменяется в зависимости от области просмотра, поэтому размер масштабируется, и все выглядит одинаково.   -  person RaKXeR    schedule 01.06.2015


Ответы (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");

Кроме того, не устанавливайте размеры внутри медиа-запросов; это изменило бы макет при изменении размера и масштабировании.

person m69 ''snarky and unwelcoming''    schedule 30.05.2015
comment
эй, спасибо за ответ, я сейчас иду, чтобы проверить это. просто к вашему сведению: при использовании тега script в html5 вам больше не нужно объявлять, что это за скрипт, вы можете просто сделать ‹script›‹/script›. - person RaKXeR; 01.06.2015
comment
Итак, я проверил ваш код (кстати, вам не хватает ; в вашей последней строке скрипта), и, похоже, он у меня не работает. Я разместил предупреждение в конце вашего кода, но, похоже, оно не срабатывает, поэтому я думаю, что оно не доходит до конца вашей функции. Однако ошибок нет, поэтому, возможно, это логическая ошибка, которую я еще не получил. Вы можете загрузить демо, пожалуйста? - person RaKXeR; 01.06.2015
comment
К сожалению, я забыл проверить, существуют ли стили перед использованием styles.length; Вероятно, я потом изменил css, поэтому ошибка сначала не появлялась. - person m69 ''snarky and unwelcoming''; 01.06.2015
comment
Я немного подправил скрипт для совместимости с браузером. Однако я обнаружил, что, например. IE8 полностью отбрасывает правила css, которые он не понимает (например, с единицами области просмотра), поэтому они отсутствуют в интерфейсе document.styleSheets. Так что нет особого смысла пытаться заставить этот скрипт работать с браузерами устаревшего IE8; Не знаю, важно ли это для тебя. Вы можете предоставить запасной вариант для старых браузеров, установив сначала разумное значение в пикселях, например P {font-size: 16px; размер шрифта: 2vh}. - person m69 ''snarky and unwelcoming''; 02.06.2015
comment
ну, на самом деле это не сработало для меня, но кажется, что это хороший сценарий для тех, кто попытается сделать это в будущем, поэтому я отмечаю это как правильный ответ и собираюсь найти обходной путь. (Я, вероятно, многое изменю в том, как работает мой веб-сайт, так как сейчас это немного запутанно). - person RaKXeR; 02.06.2015
comment
Спасибо. Просто поясню будущим читателям: - Как бы то ни было, скрипт работает только для современных браузеров, которые понимают единицы измерения окна просмотра. Идея обходного пути: предположим, например. ширина окна просмотра 1024 пикселя в качестве запасного варианта для старых браузеров, используйте двойные стили, такие как {width: 512px; width: 50vw}, то, если скрипт находит значение в пикселях, умножает его на (w/1024). - Стили внутри медиа-запросов игнорируются, поскольку в данном конкретном случае они не имеют смысла. Сначала вам придется разделить правило мультимедиа на отдельные правила стиля. - !важно игнорируется. Проверьте CSSStyleDeclaration.getPropertyPriority(). - person m69 ''snarky and unwelcoming''; 02.06.2015
comment
еще одна вещь @ m69, если вы считаете, что этот вопрос был полезен, проголосуйте за него (если вы не возражаете). как только я получу 15 повторений, я проголосую за ваш ответ :) - person RaKXeR; 02.06.2015