2015-04-08 2 views
0

У меня есть подпрограмма, которая позволяет размеру элементов на странице плотно прилегать к родителям. В большинстве случаев он работает превосходно, но в Firefox (JUST Firefox - Chrome, IE и т. Д. - это хорошо), он вовлекается в первую попытку в одном конкретном экземпляре - div, вложенный в поле, не может изменить размер с первой попытки, но преуспевает во второй (и последующих) попытках.Получение вычисленной ширины элемента после модификации

Каждый элемент имеет размер относительно его родителя, используя следующие:

function resizeChild(elem) { 
    // Get gutter based on margins, borders, padding, etc 
    var gutter = getGutter(elem); // returns obj with x and y properties 
    var parent = elem.parentElement; 
    var parentStyles = window.computedStyle(parent); 
    var targetWidth = (parseInt(parentStyles['width']) - gutter.x; 
    var widthPx = targetWidth + 'px'; 
    // prototype.js setStyle shortcut 
    elem.setStyle({ 
     width: widthPx, 
     maxWidth: widthPx, 
     minWidth: widthPx 
    }); 
} 

Я бегу это в цикле, итерация каждый элемент с определенным классом CSS.

Согласно отладчику Firefox, внешний элемент (набор полей) всегда изменяется до внутреннего div. Я могу проверить элемент и увидеть соответствующие атрибуты стиля. Однако на следующей итерации цикла, когда родитель оценивается (я вижу в инспекторе свойств javascript, что родительский элемент действительно является набором полей), значение ширины, возвращаемое для вычисленного стиля, является предыдущим, немодифицированным значение, поэтому внутренний div изменяется неправильно.

Может кто-нибудь пролить свет на это, пожалуйста?

редактирует после комментариев:

parent.clientWidth возвращает 0.

Не уверен, если это уместно, но родительский DIV из FIELDSET имел display набор к none незадолго до операции изменения размера при вызове. Однако в тот момент, когда размер поля был изменен, display div был установлен в inline-block. Я не думаю, это изменило бы, но тогда я не очень хорошо разбираюсь в некоторых особенностях поведения Firefox в этом сценарии.

+0

Вы видите эту страницу? https: //developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements –

+0

У меня есть :) Проблема в этом случае заключается в том, что многие стандартные методы API для запроса макета родительского div возвращают 0 в первый раз, когда этот конкретный область страницы - только ненулевые значения, которые я получаю, относятся к вычисленному стилю. К сожалению, вычисленный стиль, как представляется, содержит размеры родительского элемента от ** до **, он был изменен, если он также был изменен. – Minouris

+0

Это почти как если бы - просто поместив это там, как бездельное размышление - как если бы Firefox обрабатывал функцию resizeFullWidth() как транзакционную единицу и не применял измененные свойства к DOM, пока не завершилась целая функция. – Minouris

ответ

2

Я нашел решение этой проблемы, хотя это немного ситуативной.

кажется, что если ширина родительского элемента была динамически изменена с помощью prototype.js#Element.setStyle() (и, насколько я знаю, другие библиотеки, которые непосредственно изменяют атрибут style), то метод computedStyle() не будет отражать изменения, пока все изменения завершены.

Решение должно было проверить, не имеет ли родительский элемент изменяемого элемента также класс CSS, который помечен элементами для изменения размера, и если это так, получите размер от атрибута style вместо использования computedStyle(). Вот полная функция, с изменениями:

function resizeFullwidth() { 
    $$('*.fullWidth').each(function(elem, i) { 
     // Get gutter based on margins, borders, padding, etc 
     var gutter = getGutter(elem); // returns obj with x and y properties 
     var parent = elem.parentElement; 
     var parentStyles = (
      parent.hasClassName('fullWidth') 
       ? window.computedStyle(parent) 
       : parent.style); 
     var targetWidth = (parseInt(parentStyles['width']) - gutter.x; 
     var widthPx = targetWidth + 'px'; 
     // prototype.js setStyle shortcut 
     elem.setStyle({ 
      width: widthPx, 
      maxWidth: widthPx, 
      minWidth: widthPx 
     }); 
    }); 
} 

Этот теперь корректно работает во всех браузерах :)

Большое спасибо за вашу помощь, люди :)

0

Вы попробовали var targetWidth = parent.clientWidth?

См: MDN Element.clientWidth

+0

У меня есть. В тот момент, когда это выполняется, parent.clientWidth возвращает 0. Не уверен, что это актуально, но родительский div из набора полей имеет 'display' установленный' none' незадолго до вызывания операции изменения размера. Однако в тот момент, когда размер поля был изменен, 'display' div был установлен в' inline-block'. Я не думаю, что это будет иметь значение, но тогда я не очень хорошо разбираюсь в некоторых особенностях поведения Firefox в этом сценарии. – Minouris

+0

@Minouris. Вы не можете вернуть ширину элемента с помощью 'display: none', возможно, это потому, что код выполняется быстрее, чем Firefox может обновить DOM? –

Смежные вопросы