width () и height () для современных браузеров без jQuery - PullRequest
9 голосов
/ 18 октября 2010

Я пытаюсь реализовать простой эффект сгиба / разметки для упругих элементов div, т.е. когда фактические размеры элемента не задаются с помощью CSS и, следовательно, не могут быть легко определены.Поэтому мне нужны эквиваленты jQuery width () и height () для произвольных элементов;методы должны возвращать что-то, что можно было бы присвоить * .style.width / height для достижения эффекта сгиба / разворачивания.Методы также могут быть сеттерами, хотя и не обязательно, так как они в любом случае тривиальны (или нет?)

Совместимость: IE8 + и соответствующая группа из 3: Firefox, Chrome, Safari.У SO нет ответа на этот вопрос, кроме как "использовать jQuery", чего я сейчас не хочу делать.Дело в том, что мне не нужно поддерживать такие архаичные браузеры, как IE6 / 7 и Netscape.Я хочу, чтобы мой код был простым, первым JavaScript для современных браузеров.Отбрасывание IE8 для IE9 также является опцией.

Я думаю, что ответ может быть полезен для многих веб-разработчиков.Спасибо!

Редактировать: я понимаю, конечно, что анализ jQuery (и удаление архаичных причуд) является хорошим вариантом, но я подумал, что кто-то уже сделал это и может поделиться с нами.

Ответы [ 4 ]

5 голосов
/ 18 октября 2010

Вот ответ на мой собственный вопрос, который я сформулировал сегодня после игры с IE8, FF, Chrome и Safari.

Допустим, мы хотим сложить и развернуть элемент div по вертикали (поэтому мы будемговорить только о высоте для простоты) с минимально возможным JavaScript и без jQuery.Может быть встроенное окно сообщения об ошибке, которое вы хотите показать и скрыть на странице.Само окно сообщения является эластичным, и вы не знаете его фактических размеров.Здесь необходимо решить две основные проблемы:

Проблема № 1: свойства offsetHeight, clientHeight и scrollHeight общеизвестно несовместимы во всех браузерах.Вы не можете полагаться на них, особенно когда для поля margin / padding / border установлено значение, отличное от 0, и когда высота CSS отличается от значения по умолчанию (т.е. при фактическом сворачивании / разворачивании элемента).Есть getComputedStyle (), но он доступен только в нормальных браузерах, а не в IE.OTOH, свойство IE currentStyle не возвращает вычисленные значения, как вы могли ожидать (например, вы можете увидеть «auto» в качестве значения высоты).Оказывается, без полей / отступов / полей offsetHeight надежен и совместим со всеми современными браузерами.

Проблема №2: единственный способ (насколько мне известно) анимировать ваш элемент div - это изменить стиль.высота, которая, однако, не включает отступы и границы, и, таким образом, вы не можете анимировать блок до 0 или начать анимацию с 0 для элементов с ненулевым заполнением и границей.(Кроме того, IE не принимает 0px как style.height, поэтому минимальный размер в любом случае будет 1px).

Решение обеих проблем состоит в том, чтобы обернуть вашу коробку другим div с использованием стиля по умолчанию.то есть padding / margin / border все установлено в 0, что является стилем по умолчанию для нового div.Поле, которое вы хотите сложить и развернуть, должно быть внутри, и оно не должно иметь настройки полей, только отступы и границы при желании.Таким образом, вы сможете (1) надежно определить высоту вашего эластичного внутреннего блока с помощью offsetHeight и (2) анимировать высоту внешнего блока в 1 пиксель и из него.

Итак, скажем,мы хотим оживить это:

<div id="errmsg" style="display:none">
    <div class="errmsg">
        <div class="window-close" onClick="javascript:showErrMsg('', this.parentNode.parentNode)"></div>
        <div id="errmsg.text"></div>
    </div>
</div>

Ящик невидим в начале.Класс "window-close" - это небольшой прямоугольник справа с крестиком, который используется для скрытия прямоугольника при нажатии.Вызов showErrMsg () с пустой строкой сворачивает окно сообщения (см. Ниже).

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

var ANIMATE_STEPS = 10;
var ANIMATE_DELAY = 20;


function _obj(obj, parent)
{
    if (typeof obj == 'string')
        obj = (parent ? parent : document).getElementById(obj);
    return obj;
}

function _setStyleHeight(obj, h)
{
    _obj(obj).style.height = Math.round(h) + 'px';
}

function _animateVertFold(obj, cur, by, lim)
{
    obj = _obj(obj);
    cur += by;
    if (by < 0 && cur <= 1)
    {
        obj.style.display = 'none';
        _setStyleHeight(obj, 1); // IE doesn't accept 0
    }
    else if (by > 0 && cur >= lim)
    {
        _setStyleHeight(obj, lim);
    }
    else
    {
        _setStyleHeight(obj, cur);
        setTimeout('_animateVertFold(\'' + obj.id + '\', ' +
            cur + ', ' + by + ', ' + lim + ')', ANIMATE_DELAY);
    }
}

function _expandElem(obj)
{
    obj = _obj(obj);
    if (obj.style.display == 'none')
    {
        obj.style.overflow = 'hidden';
        _setStyleHeight(obj, 1);
        obj.style.display = 'block';
        var innerDiv = obj.getElementsByTagName('div')[0]; // better way?
        var h = innerDiv.offsetHeight;
        if (h > 0)
            _animateVertFold(obj, obj.offsetHeight, h /  ANIMATE_STEPS, h);
    }
}

function _shrinkElem(obj)
{
    obj = _obj(obj);
    if (!obj.style.display || obj.style.display != 'none')
    {
        obj.style.display = 'block';
        obj.style.overflow = 'hidden';
        var h = obj.offsetHeight;
        _animateVertFold(obj, h, - h /  ANIMATE_STEPS, h);
    }
}


function showErrMsg(msg, id)
{
    id || (id = '_errmsg');
    obj = _obj(id);
    if (msg != '')
    {
        _obj(id + '.text').innerHTML = msg;
        _expandElem(obj);
    }
    else
        _shrinkElem(obj);
}

Вы можете вызвать showErrMsg (), и код позаботится обо всем остальном.Вы должны будете определить класс закрытия окна как нечто, имитирующее кнопку закрытия окна GUI.И, конечно, класс «errmsg» в виде блока с отличным цветом фона, рамкой и, возможно, шрифтом.

4 голосов
/ 18 октября 2010

element.offsetHeight, element.offsetWidth работают практически одинаково во всех браузерах, возвращают целые числа

element.clientWidth, element.clientHeight возвращают целые числа, но имеют некоторые различия в x-браузере (заполнение, ширина границы)

Браузеры currentStyle или вычисленного стиля возвращают строки, и они могут быть в пикселях, ems, процентах - трудно манипулировать x-browser.

4 голосов
/ 18 октября 2010

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

3 голосов
/ 18 октября 2010

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

Вот описание: https://developer.mozilla.org/en/DOM:window.getComputedStyle

...