"getUnComputedStyle" элемента

Я обнаружил различия между браузерами, как они сообщают о вычисляемых размерах стилей при увеличении окна браузера. Пример JSBIN находится в http://jsbin.com/pilohonevo/2/. Код выглядит следующим образом:

$(window).resize(function()
{
  var width1=$(".class1").css("width");
  $(".class1").css("width",width1);

  var width2="200px";
  $(".class2").css("width",width2);

  var width3=$(".class3").css("width");

  $("#width1").html(width1);
  $("#width2").html(width2);
  $("#width3").html(width3);

  $("#overflow1").html($(".overflow1")[0].scrollWidth);
  $("#overflow2").html($(".overflow2")[0].scrollWidth);
  $("#overflow3").html($(".overflow3")[0].scrollWidth);
});

Когда вы приближаетесь к минимуму, нажимая CMD- несколько раз, а затем возвращаетесь на 100%, нажимая CMD + несколько раз, в Chrome (версия Mac 38.0.2125.111) вы получаете следующие значения:

enter image description here

Белый DIV 1 сообщает свою ширину как 203px, хотя DIV 2 и 3 сообщает 200px. Также scrollWidth - 203, что тоже неправильно. Это означает, что вы не можете использовать getComputedStyle или jQuerys .css() для получения измерений, если не уверены, что окно браузера не увеличено. И поскольку масштабирование не отменяется, вы никогда не можете быть уверены, и вы никогда не сможете доверять этим измерениям. Я тестировал также $(elem).scrollLeft() и $(elem).scrollTop(), и они также ненадежны при масштабировании.

Таким обходным решением может быть использование "необработанных" значений, а не "вычисленных" значений.

Существует ли кросс-браузерный метод javascript или jQuery, чтобы получить что-то вроде getUnComputedStyle(), которое определяет измерения с использованием необработанных значений из таблиц стилей и/или атрибутов стиля, потому что они единственные, которые являются масштабируемыми?

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

(Firefox Mac 33.1 и Safari Mac версии 7.1 (9537.85.10.17.1) и IE 11 Win и эмулированные режимы вплоть до версии 7 сообщают правильные значения.

Opera Mac 25.0.1614.68, Safari Win 5.1.7 и выше сообщалось о неверных значениях отчета в Chrome.)

Ответы

Ответ 1

Я воспроизвел это с помощью Chrome 49 и JQuery 1.11, а не в FF, а не в Internet Explorer.

Однако я считаю, что это тоже артефакт кода. Единственные divs, которые показывают эту проблему, - это div1 и overflow1, которые одновременно используют одну и ту же систему установки ширины в вычисленную ширину. Что происходит, так это то, что для некоторых значений масштаба вычисляемое значение равно 201. Вы устанавливаете ширину 201, поэтому для некоторых значений масштабируемого значения значение равно 202 и так далее. Я получил, например, 204.

В отладчике Chrome, при увеличении 67%, указанная ширина отображается как 199.981, но значения, доступные Javascript, являются целыми числами. scrollWidth равен 199, а clientWidth и offsetWidth - 200. Все методы ширины jQuery возвращают 200 (width, innerWidth, outerWidth). При увеличении на 33%, scrollWidth и jQuery widths все возвращают 201, хотя в сообщенной ширине отладки все равно 199.981.

Мое утверждение состоит в том, что проблема связана с ошибкой в ​​Chrome и, вероятно, связана с округлением.

Как описано здесь: Получив фактическую ширину элемента с плавающей запятой, вы можете получить фактическое значение с плавающей запятой, сообщаемое отладчиком, с помощью .getBoundingClientRect(). Если вы хотите быть полностью безопасным, попробуйте использовать его.

Ответ 2

Если я понимаю, что вы пытаетесь выполнить правильно (и если я не скажу так, и я попытаюсь улучшить свой ответ), и если вы уже успели поймать событие масштабирования каким-то образом (что не данный), вы могли бы:

  • Клонировать div, с которого вы пытаетесь получить стили CSS;
  • Добавить клон в дом ненавязчивым способом (т.е. способом, которым он не будет охватывать какие-либо другие элементы в документе);
  • Удалить атрибут style (на всякий случай, если он был установлен другими скриптами или функциями);
  • Получите все стили, которые вам нужны,
  • Наконец, удалите клон из dom, когда вы закончите.

Эта демонстрация работает для меня, независимо от масштаба страницы.

jQuery(function($) {
    function getRawStyles(sel, styles) {
        sel = $(sel);
        var clone = sel.clone().removeAttr("style").attr("class", "cloneDiv").insertBefore(sel);
        $.each(styles, function(index, style) {
            console.log( style + ": " + $(clone[0]).css(style) );
        });
         $(".cloneDiv").remove();  
    }
    $(document).ready(function() {
        $("button", this).on("click", function() {
            getRawStyles("#myDiv", ["height", "width"]);
        });
    });
});
#myDiv {
    background: grey;
    height: 50px;
    width: 200px;
}
.cloneDiv {
    left: -10000;
    opacity: 0;
    top: -10000;
    position: absolute;
    z-index: -1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="myDiv" style="height:200px; width: 100px"></div>
<br/>
<button>Log Computed Styles</button>