Как получить (элемент с) самым высоким CSS-z-индексом в документе? - PullRequest
5 голосов
/ 22 декабря 2010

Вопрос не может быть проще. Значения z-index назначаются style=... или className, с Javascript или без. Я не думаю, что это имеет значение. Как мне найти (с помощью Javascript) самый высокий z-индекс? (Элемент, в котором он используется, был бы хорош, но не обязателен.)

Вы не можете использовать (новый) querySelector, потому что он не запрашивает значения CSS. Есть ли способ запросить CSS? (Не таблицы стилей, а фактические используемые значения.)

Grazi

Ответы [ 5 ]

16 голосов
/ 22 декабря 2010

Это не так просто, как найти элемент с самым высоким z-индексом.Порядок размещения также зависит от древовидной структуры, поэтому, если статически позиционированный элемент с наибольшим z-индексом явно установлен, и если ваш код извлекает его, это будет бесполезно, поскольку z-index бесполезен для статически позиционированных элементов.* Кроме того, правила порядка размещения в IE полностью нарушены, поэтому вам также придется учитывать это.И вам, возможно, придется учитывать элементы iframe / select в IE pre 8/9, поскольку они имеют больший приоритет порядка размещения, чем любые другие узлы.

Это, вероятно, будет полезно: http://www.w3.org/TR/CSS21/zindex.html

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

4 голосов
/ 26 марта 2011

Это модифицированная версия кода Кеннебека / Правенса, который находит самый высокий z-индекс в контексте стека. Эта версия также учитывает непрозрачность.

Если все, что вам нужно, это поместить элемент поверх всего остального на странице, просто вызовите highZ (document.body) или просто highZ (). Он находит самый высокий z-индекс корневого стекового контекста, который будет делать именно это.

  • Только не статически расположенные элементы имеют значение в контексте стека.
  • Элементы, которые не расположены, не запускают новый контекст стека. Таким образом, их потомки могут существовать в текущем стековом контексте. Отсюда и рекурсия.
  • Кроме того, если z-index равен 'auto', элемент не запускает новый контекст стека, поэтому вы должны проходить через его элементы.
  • элементы со значением непрозрачности меньше 1 запускают новый контекст стека. Если элемент с непрозрачностью меньше 1 не позиционирован, реализации должны закрасить созданный им слой в пределах родительского контекста стекирования в том же порядке стековки, который использовался бы, если бы это был позиционированный элемент с 'z-index: 0' и «Непрозрачность: 1». Если позиционируется элемент с непрозрачностью менее 1, свойство «z-index» применяется, как описано в [CSS21], за исключением того, что «auto» обрабатывается как «0», так как всегда создается новый контекст стека.

    function highZ(parent, limit){
        limit = limit || Infinity;
        parent = parent || document.body;
        var who, temp, max= 1, opacity, i= 0;
        var children = parent.childNodes, length = children.length;
        while(i<length){
            who = children[i++];
            if (who.nodeType != 1) continue; // element nodes only
            opacity = deepCss(who,"opacity");
            if (deepCss(who,"position") !== "static") {
                temp = deepCss(who,"z-index");
                if (temp == "auto") { // positioned and z-index is auto, a new stacking context for opacity < 0. Further When zindex is auto ,it shall be treated as zindex = 0 within stacking context.
                    (opacity < 1)? temp=0:temp = highZ(who);
                } else {
                    temp = parseInt(temp, 10) || 0;
                }
            } else { // non-positioned element, a new stacking context for opacity < 1 and zindex shall be treated as if 0
                (opacity < 1)? temp=0:temp = highZ(who);
            }
            if (temp > max && temp <= limit) max = temp;                
        }
        return max;
    }
    
    function deepCss(who, css) {
        var sty, val, dv= document.defaultView || window;
        if (who.nodeType == 1) {
            sty = css.replace(/\-([a-z])/g, function(a, b){
                return b.toUpperCase();
            });
            val = who.style[sty];
            if (!val) {
                if(who.currentStyle) val= who.currentStyle[sty];
                else if (dv.getComputedStyle) {
                    val= dv.getComputedStyle(who,"").getPropertyValue(css);
                }
            }
        }
        return val || "";
    }
    
2 голосов
/ 22 декабря 2010

Вам нужны только одноуровневые элементы, чтобы найти самый высокий z-индекс, поэтому начните с родительского элемента или тела.

И часто у вас есть какой-то элемент с действительно высоким z-индексом, который вы хотите всегда быть на вершине - если это так, игнорируйте z индексы более миллиона или что-либо безопасно выше числа братьев и сестер.

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

function highZ(pa, limit){
    limit= limit || Infinity;
    pa= pa || document.body;
    var who, tem, mx= 1, A= [], i= 0, L;
    pa= pa.childNodes, L= pa.length;
    while(i<L){
        who= pa[i++]
        if(who.nodeType== 1){
            tem= parseInt(deepCss(who,"z-index")) || 0;
            if(tem> mx && tem<=limit) mx= tem;
        }
    }
    return mx;
}
function deepCss(who, css){
    var sty, val, dv= document.defaultView || window;
    if(who.nodeType== 1){
        sty= css.replace(/\-([a-z])/g, function(a, b){
            return b.toUpperCase();
        });
        val= who.style[sty];
        if(!val){
            if(who.currentStyle) val= who.currentStyle[sty];
            else if(dv.getComputedStyle){
                val= dv.getComputedStyle(who,"").getPropertyValue(css);
            }
        }
    }
    return val || "";
}

предупреждение (HIGHZ ())

2 голосов
/ 22 декабря 2010

Вам нужно было бы перебрать каждый отдельный элемент в DOM и отслеживать максимальный z-индекс, найденный во время цикла, вместе с элементом, который имеет этот z-индекс.Затем, когда вы закончите, у вас будет элемент, который вы ищете.

Это невероятно интенсивный фрагмент скрипта, который может убить браузеры ваших пользователей.С какой стати вы хотите это сделать?

0 голосов
/ 22 декабря 2010

Медер имеет большое значение! Я все равно пытался его кодировать, потому что мне скучно на работе, и я не могу с собой поделать:

ПРИМЕЧАНИЕ : будет работать только с набором стилей, используя атрибут style (не будет захватывать стиль, установленный таблицами стилей)

function getHighIndex (selector) {
    if (!selector) { selector = "*" };

    var elements = document.querySelectorAll(selector) ||
                   oXmlDom.documentElement.selectNodes(selector),
        i = 0,
        e, s,
        max = elements.length,
        found = [];

    for (; i < max; i += 1) {
        e = elements[i].style.zIndex;
        s = elements[i].style.position;
        if (e && s !== "static") {
          found.push(parseInt(e, 10));
        }
    }

    return found.length ? Math.max.apply(null, found) : 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...