Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Как применить стиль position: fixed для IE6


Автор: mielnir 26.1.2007, 18:09
Создавал тему в Верстке, но, похоже, надо было здесь. В общем чем суть проблемы. Есть блок( внутри него у меня навигация ), как сделать так, чтобы при пролитывании страницы этот блок тоже двигался. В FF и Опере это - position: fixed, в IE такое не работает. Может, есть какой-то скрипт, решающий задачу?

Автор: AKS 26.1.2007, 18:28
Подключите данный .htc, указав его адрес в значении св-ва CSS behavior:
Код

<public:component lightweight='true'> 
<public:attach event='ondocumentready' onevent='init_element()' />
<script type='text/jscript'>
/*<![CDATA[*/

/**
 * This function initializes coordinates, saving them in two arrays.
 * Also it registers two handlers for onresize*onscroll events. 
 */

function init_element() {
    var doc = window.document,
        csscompat = (doc.compatMode == 'CSS1Compat'),
        canvas;
    if (window.XMLHttpRequest && csscompat
        || currentStyle.position != 'fixed')
        return;
    else {
        style.position = 'absolute';
        init_element.scroll_params = (init_element.resize_params
            = [(canvas = (csscompat) ? doc.documentElement : doc.body),
            parseInt(currentStyle.top) || offsetTop,
            parseInt(currentStyle.left) || offsetLeft,
            parseInt(currentStyle.bottom), parseInt(currentStyle.right),
            canvas.offsetHeight, canvas.offsetWidth]).slice(0, 3);
        window.attachEvent('onscroll', element_onscroll);
        window.attachEvent('onresize', element_onresize);
    }
}

/**
 * This function establishes new values of coordinates of an element 
 * depending on its initial position and a condition of scrolling. 
 */

function element_onscroll() {
    var params = init_element.scroll_params;
    style.top = params[0].scrollTop + params[1] + 'px';
    style.left = params[0].scrollLeft + params[2] + 'px';
}

/**
 * This function also establishes new values of coordinates 
 * of an element depending on its initial position and a condition 
 * of scrolling, and also saves current coordinates.
 */

function element_onresize() {
    var params = init_element.resize_params,
        height = params[0].offsetHeight,
        width = params[0].offsetWidth,
        top = (params[3])
               ? params[1] - (params[5] - height)
               : params[1],
        left = (params[4])
                ? params[2] - (params[6] - width)
                : params[2];
    style.top = params[0].scrollTop +  top + 'px';
    style.left =  params[0].scrollLeft + left + 'px';
    init_element.scroll_params[1] = top;
    init_element.scroll_params[2] = left;
}

/*]]>*/
</script>
</public:component>


P.S. Забыл добавить, что поведение фиксированного таким образом блока будет немного отличаться от поведения блока "fixed". Надеюсь на комментарии по поводу работы данного сценария...

Автор: mielnir 26.1.2007, 18:49
AKS, не могли бы Вы поподробнее про установку/использование - с JS у меня пока туговато )))

Автор: AKS 26.1.2007, 20:46
mielnir
Этот код Вам нужно сохранить в файле с расширением .htc. Затем в таблице стилей для блока, которому Вы указываете position:fixed, надо добавить еще одно правило - behavior:url([путь к файлу].htc).
На всякий случай, справочная информация "из первых рук" вот http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/properties/behavior_1.asp.

Автор: Sardar 27.1.2007, 00:13
Возможно более элегантное http://www.howtocreate.co.uk/fixedPosition.html.

Автор: AKS 27.1.2007, 10:20
Sardarmielnir, не "возможно", а действительно - по ссылке выше лежит решение, которое "более" в любом отношении.
Господи, сколько времени я потратил напрасно на написание своего .htc! Приговор - "в мусор мою писанину"!

Автор: mielnir 27.1.2007, 11:18
AKS, все отлично )) Гляньте подпись Sardar'a. 
А за код всем спасибо. Все работает ))

Автор: AKS 28.1.2007, 16:07
Цитата(mielnir)
...все отлично )) Гляньте подпись Sardar'a. 

Действительно, все отлично (я просто "огласил приговор" своему варианту, чтобы всем было ясно - он не пригоден для использования ;) )!
Сегодня, "побаловавшись" с этой темой, написал кое-что поинтересней. Конечно же я отказался от использования обработчиков событий onscroll&onresize в пользу метода setExpression (пускай браузер сам "разруливает" позиционирование ;) ). Но для того, чтобы избежать длинных-предлинных выражений в таблице стилей, я не стал отказываться от применения behavior. Думаю, что достаточно сравнить описание стиля элемента, которое использует г-н http://www.howtocreate.co.uk/fixedPosition.html (и это только одно выражение св-ва left):
Код

left: expression( ( -20 - fixme.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );

вот с такой записью:
Код

#ID {
    position:fixed;
    top:0px;
    left:0px;
    behavior:url(position-fixed.htc);
}

и будет понятно, что второй вариант проще. Очевидно также, что он удобен еще и тем, что нет нужды писать кроссбраузерный стиль, используя условные комментарии и селекторы, не поддерживаемые IE. Пишется одно правило для всех браузеров. Кроме того, в моем варианте не используются ненужные глобальные переменные (ignoreMe&ignoreMe2) - вместо них создается дополнительная функция. 
Вот код из файла position-fixed.htc:
Код

<public:component lightweight='true'> 
<public:attach event='ondocumentready' onevent='fixPosition()' />
<script type='text/jscript'>
/*<![CDATA[*/
if (!window.__getDimensionsForFixPosition__) {
    window.__getDimensionsForFixPosition__ = function (method) {
        var d = this.document;
        return (d.documentElement[method] || d.body[method]);
    }
}
function fixPosition() {
    if (!/MSIE (5|6)/.test(navigator.userAgent)) return;
    style.position = 'absolute';
    var l = parseInt(currentStyle.left),
        t = parseInt(currentStyle.top),
        r = parseInt(currentStyle.right),
        b = parseInt(currentStyle.bottom),
        s1 = '+__getDimensionsForFixPosition__("clientWidth")',
        s2 = '+__getDimensionsForFixPosition__("scrollLeft")',
        l_p = (isNaN(l))
               ? -r - offsetWidth + s1
               : l,
        t_p = (isNaN(t))
               ? -b - offsetHeight + s1.replace(/Width/, 'Height')
               : t;
    style.setExpression('left', l_p + s2);
    style.setExpression('top', t_p + s2.replace(/Left/, 'Top'));
}
/*]]>*/
</script>
</public:component>

Надеюсь на комментарии, которые могут помочь исправить то, что возможно было упущено...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)