правильні show

Як правильно реалізувати універсальні функції show і hide для DOM елемента? Є кілька поширених варіантів, з різними граблями, які ми розглянемо, і виберемо оптимальний.

Розглянемо найпростішу функцію toggle:

Недоліки такого підходу легко бачити. Наприклад, посилання мають за замовчуванням display: inline. А цей код поставить display = "block".

Для перевірки - клікніть на будь-якому місці цього жовтого div. при цьому зголоситься toggle посилання. І потім - клікніть ще раз для повторного toggle.

Як видно, ховає воно нормально, а ось показ - некоректний.

Аналогічна проблема буде з елементами таблиці, у яких за стандартом display: table-cell.

Цієї проблеми позбавлений наступний варіант:

Замість block властивість display скидається - при цьому елемент отримує display з CSS за замовчуванням, тобто те, яке було спочатку:

Як бачите, все працює вірно.

Але при цьому виникає інша проблема. Властивість display у елемента може відрізнятися від успадкованого з CSS, наприклад:

При цьому обнулення display скине це особливого значення.

Для кращої застосовності розіб'ємо toggle на дві частини: show і hide і налагодимо їх окремо.

Щоб обійти описану вище проблему з перезапису display - при приховуванні елементу будемо записувати старе значення display в атрибут el.displayOld. а при показі - відновлювати.

Тепер show / hide для посилання зі своїм display буде працювати коректно.

Однак, і цей варіант - для нас не більше ніж проміжний.

Функція hide працює відмінно. Про show такого не скажеш.

  1. По-перше, виклик show до hide скине display. Це поведінка - некоректна, його потрібно поправити.
  2. По-друге, що більш важливо, якщо елемент захований CSS-класом, то show його не здасться.

Наприклад, show буде непереливки посилання з цього прикладу:

Щоб вирішити ці проблеми, функція show повинна знати, чи показується елемент реально чи ні. Це нам допоможе зробити доступ до Computed Style - обчисленому стилю елемента, доступ до якого робиться по-різному, в залежності від браузера.

Наступна функція бере реальне значення display з Computed Style, тобто таке. яке виходить в результаті застосування всіх CSS-класів і властивостей.

Якщо елемент не показується з-за CSS-класу, то getRealDisplay поверне для нього 'none'.

Ви можете захотіти прибрати цю строчку в цілях оптимізації, щоб зробити show швидше.

Але при цьому show стане функціонувати належним чином при виклику без попереднього hide на елементі з нестандартним display.
  • Отримати старе значення display. якщо воно збережено hide і поставити його елементу. Якщо старого значення немає - на безриб'ї і рак риба, просто Обнуляємо display.
  • Показується чи елемент? Елемент може не показуватися, наприклад, через те, що в його CSS класі прописано display: none. Якщо так, то для показу елемента доведеться знайти і застосувати відповідне значення display.

    Де взяти значення display для показу спочатку прихованого елемента? Це зовсім не обов'язково block. тому елемент міг бути посиланням, осередком таблиці, та й взагалі - "правильний" display для показу елемента залежить від місця, часу і настрою програміста.

    У блоці (3.2) функція поміщає елемент з таким же тегом в кінець і отримує його display. яке кешує у допоміжному об'єкті displayCache. Звичайно, це всього лише гіпотеза, однак в простих випадках вона працює.

    Цей display і використовується для призначення елементу.

    1. Спробувати отримати правильне значення display з кешу.
    2. У кеші немає - додаємо порожній тег до . потім беремо його display.
      1. Якщо і цей тег має реальний display: none - вгадати не вийшло. Візьмемо block. що ще робити, елемент-то показати треба.
    3. Вгадані значення display застосовуємо до елементу і зберігаємо для подальшого використання.
  • Отже, тепер на основі show і hide можна зробити функцію toggle. яка видимий елемент приховує, а невидимий - навпаки, показує. Інакше кажучи, перемикає стан елемента.

    Функція toggle сама по собі дуже проста:

    Для її роботи необхідна допоміжна функція isHidden. яка визначає, чи видно елемент. Само собою, мається на увазі реальна видимість, а не властивість display елемента.

    Використовуємо для цього трюк з offsetWidth / offsetHeight:

    Ця реалізація намагається отримати відповідь, по можливості використовуючи перевірку offsetWidth / offsetHeight. тому це швидше, ніж getRealDisplay.

    Отже, ось підсумковий код toggle.js.

    Приклад роботи ви можете побачити на окремій сторінці.

    Ця універсальна функція toggle широко використовується в різних бібліотеках, зокрема, в jQuery.

    Тепер ви знаєте, що вона робить ряд зайвих операцій, і якщо раптом ваш toggle заглючить - уявляєте, в чому може бути справа.

    Нехай ваш toggle завжди працює так, як задумано!

    • Версія для друку

    Схожі статті