Как получить (элемент с) самым высоким z-индексом CSS в документе?

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

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

Граци


Получить 5 лучших элементов + z-индексы:

Array.from(document.querySelectorAll('*')).map(el => [el, getComputedStyle(el).zIndex]).filter(v => !isNaN(parseInt(v[1]))).sort((a, b) => b[1] - a[1]).slice(0, 5)

person Rudie    schedule 21.12.2010    source источник
comment
Дубликат: stackoverflow.com/questions/1118198/   -  person Evan Mulawski    schedule 22.12.2010
comment
Я бы использовал для этого PHP Simple HTML DOM, и вы даже можете редактировать значения элементов, их атрибуты и т. д., а затем сохранять их обратно в файл или другой файл и т. д. и возвращать данные в json в ваш javascript, чтобы обновить любой элемент, возвращенный вашим sHTMLdom ... Вы также можете вернуть список элементов, для которых установлен атрибут стиля z-index, и упорядочить их на основе их значения, что приведет к ответу на ваш вопрос.   -  person Gregory Bowers    schedule 29.12.2020
comment
10 лет спустя лол   -  person Gregory Bowers    schedule 29.12.2020


Ответы (5)


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

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

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

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

person meder omuraliev    schedule 21.12.2010
comment
Согласен с Мэттом - я совершенно забыл о некоторых других проблемах. - person Charles Boyung; 22.12.2010
comment
На самом деле это так же просто, как найти (элемент с) самым высоким z-индексом, потому что это был мой вопрос. Но спасибо за развернутый ответ. - person Rudie; 23.12.2010
comment
Я бы не согласился с тем, что это не так просто, как найти элемент с самым высоким значением z-index. Например, если бы я хотел загрузить html из случайных файлов, сгенерированных программой, которую я создал, которая, как я знаю, имеет значение индекса иерархии, ожидающее, чтобы сказать мне, в каком порядке размещать элементы друг над другом. Извините, я немного поздно, это безумие, как старые проблемы все еще могут быть новыми проблемами. Чтобы решить эту проблему, я использовал PHP Simple HTML Dom, поскольку он позволяет загружать таблицы стилей CSS или исключать их. в основном результатом являются обработанные стили, которые вы можете запрашивать и изменять. - person Gregory Bowers; 29.12.2020

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

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

  • Только нестационарно расположенные элементы имеют значение в контексте наложения.
  • Непозиционированные элементы не начинают новый контекст стека. Таким образом, их потомки могут существовать в текущем контексте стека. Отсюда и рекурсия.
  • Кроме того, если z-индекс имеет значение «авто», элемент не запускает новый контекст стека, поэтому вы должны выполнить рекурсию по его элементам.
  • элементы со значением непрозрачности меньше 1 начинают новый контекст наложения. Если элемент с непрозрачностью меньше 1 не позиционирован, реализации должны рисовать создаваемый им слой в его родительском контексте наложения в том же порядке наложения, который использовался бы, если бы это был позиционированный элемент с «z-index: 0» и «Непрозрачность: 1». Если позиционируется элемент с непрозрачностью меньше 1, применяется свойство «z-index», как описано в [CSS21], за исключением того, что «авто» обрабатывается как «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 || "";
    }
    
person Praveen    schedule 26.03.2011
comment
Хороший. Я заметил ваш ответ после того, как прокомментировал тот, который вы исправили. Грустно, что твой далеко здесь. Единственное, что я хотел бы отметить, это то, что, хотя позиционирование может создать новый стек, другие факторы также влияют на стек (статический [блок перед плавающей запятой перед встроенным] перед позиционированием, упорядоченным по z-индексу), и что отрицательное z-index делает вещи еще более весело... - person Kevin Peno; 19.08.2011

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

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

person Charles Boyung    schedule 21.12.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())

person kennebec    schedule 21.12.2010
comment
К сожалению, это просто неправда. У братьев и сестер может быть разный порядок укладки в зависимости от контекста их родителей, да. Тем не менее, у 3 братьев и сестер может быть несколько разных схем порядка укладки в зависимости от множества факторов, связанных с правилами размещения. - person Kevin Peno; 19.08.2011
comment
Пример: родителем является position: absolute, поэтому порядок размещения дочерних элементов всегда начинается внутри него. Sib1 позиционируется, sib2 встроен, sib3 плавает. Ни один из братьев не объявляет z-index. Стек Sib3, Sib2, Sib1. В вашем коде вы получите стек Sib1, Sib2, Sib3. - person Kevin Peno; 19.08.2011
comment
Пример 2: То же, что и выше, с применением z-индекса (даже по ошибке). Sib1 — это z-index -1, Sib2 — это z-index: auto, Sib3 — это z-index: 1. Результат стека должен быть: Sib1, Sib3, Sib2. Это связано с тем, что float не влияет на position, который необходим для применения z-index. Ваша функция даст то же, что и предыдущая: Sib1, Sib2, Sib3. - person Kevin Peno; 19.08.2011

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

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

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;
}
person Kai    schedule 21.12.2010
comment
Это не приведет к набору z-индекса в таблице стилей (в отличие от атрибута стиля). - person Quentin; 22.12.2010
comment
Правильно, и я добавлю это как отказ от ответственности! - person Kai; 22.12.2010
comment
Разве document.getElementsByTagName('*') не было бы проще в DOM? И, возможно, начнем с конца, потому что обычно там самые высокие z-индексы. Я не ищу z-индексы, определенные в таблицах стилей; только для примененных z-индексов (так в элементах). - person Rudie; 23.12.2010
comment
Это будет работать: NodeList.prototype.map = function(fn) { var a=[]; for ( var i=0; i<this.length; i++ ){ a.push(fn(this[i], i, this)); } return a; };, а затем Math.max.apply(null, document.getElementsByTagName('*').map(function(el){ return el.style.zIndex || 0; })); - person Rudie; 23.12.2010
comment
@Rudie - не знаю, почему вы приняли этот ответ, поскольку он явно не отвечает на ваш вопрос - вы хотели получить z-индекс для всех стилей, включая стили, установленные через имя класса, чего это не сделает. - person Charles Boyung; 27.12.2010
comment
@Charles Boyung См. комментарий Руди в ответ на ответ Медера; он был удовлетворен поиском zIndex на уровне элементов. Затем он принял мой ответ, а также прокомментировал фрагмент JS, который выполняет аналогичный поиск на уровне элементов. Очевидно, мой ответ помог ему. Спасибо за минус? :-| - person Kai; 28.12.2010
comment
Чарльз, ты прав. Вместо .style мне пришлось бы использовать .getCalculatedStyle() или что-то в этом роде. Но теперь уже поздно возвращать =) - person Rudie; 31.12.2010
comment
@Rudie, с каких это пор элементы в DOM упорядочены по z-index? Это правда, что внутренне статические элементы упорядочены в стеке в обратном порядке, в котором они объявлены в исходном коде, но z-index не играет никакой роли в DOM. - person Kevin Peno; 19.08.2011
comment
@Kevin Peno Кто сказал, что элементы DOM упорядочены по z-index..? - person Rudie; 20.08.2011
comment
@Rudie, ты в третьем комментарии: ..and maybe start at the end because that's usually where the high z-indexes are. - person Kevin Peno; 20.08.2011
comment
@ Кевин Ну, не так ли? Обычно я создаю веб-страницы так, чтобы элементы, которые должны быть сверху, находились в конце DOM (наложения, уведомления, выделения и т. д.). Хотя на самом деле это не актуально... - person Rudie; 20.08.2011
comment
@Rudie, я бы посоветовал тебе прочитать эту статью. timkadlec.com/2008/01/detailed-look-at -stacking-in-css - person Kevin Peno; 20.08.2011
comment
@Kevin Меня совсем не интересует стекирование в CSS. (И я знаю, как это работает.) Как видно из вопроса, я искал самый высокий z-index. Вот и все. Самый высокий. Не порядок укладки, не отображение или (комбинация) других свойств. Просто самый высокий z-index. position не имеет к этому никакого отношения. Почему все говорят о порядке укладки!? - person Rudie; 21.08.2011
comment
@Rudie, я опубликовал эту статью, потому что вы понимаете, что более высокий z-index находится внизу DOM. Вы можете сделать это таким образом, но обычно это не так. - person Kevin Peno; 22.08.2011