Приховати - показати html елементи за допомогою javascript
CSS-властивість «невидимість», яке можна було б вільно додавати і прибирати, у HTML елементів не існує. Його потрібно семуліровать, в цьому і полягає правильна постановка питання show-hide toggle.
Спеціаліст - людина, яка, уникаючи дрібних помилок, неухильно рухається до глобального омані.
Закон програмування Мерфі, ст. 17
Спеціаліст подібний флюсу: повнота його одностороння.
Козьма Прутков. Думки і афоризми: думка 101
На веб-сторінках особливо помітні недоліки роботи вузьких спеціалістів. Створення сайту як гра в шахи: не можна думати тільки про пішки королівського флангу. Або як виконання симфонії: не можна диригувати тільки контрабас, забувши про скрипках і сопілках.
Основна проблема, розбирається в статті, виникає при спробі приховування елемента шляхом призначення йому властивості:
Призначаючи HTML елементу style.display = "none". ми змінюємо існуюче властивість, а потім не знаємо, як повернути його значення назад. Це погано і тупиково, і у хорошого диригента повинен виникнути питання. - а ось це якраз найважче - сформулювати! «Чи можна зробити елемент невидимим, не змінюючи існуюче властивість style.display?» - м питання, в питанні повинна міститися половина відповіді!
Правильне питання такий: як зробити «невидимість» окремим властивістю, яке можна додавати-прибирати, не чіпаючи інших властивостей елемента. Чи не «можна чи», а саме «як», тому що при наполегливому пошуку можна вирішити будь-яку проблему.
Зрозуміло, ніякого такого властивості «невидимість» у HTML елементів не існує. Існує саме display (ну, або visibility). Окремо додається властивість «невидимість» потрібно семуліровать. в цьому і полягає правильна постановка питання. Ми додаємо до елементу щось, якийсь об'єкт, і елемент змінюється в строго заданому напрямку. Потім просто прибираємо доданий об'єкт, і з ним зникають внесені зміни.
Таке рішення передбачає, що у атрибуту class може бути кілька значень відразу, розділених пробілами. І це дійсно так (про що я, наприклад, дізнався з великим подивом - погано вчив свого часу W3C!). Зі складної рядки (кілька слів) видаляти значення доведеться за допомогою регулярних виразів. Непогано було б також, щоб даремно не смикати зайвий раз DOM, перевіряти наявність видаляється значення у атрибута class. Ось як виглядає вся тріада класснейм-функцій на стор. Openjs.com:
Що цілком може привести до появи у атрибута значення "element_hide element_hide element_hide" (не фатально, але якось. Неестетично). Справа в тому, що show-hide не завжди буває в прямому сенсі перемикачем (toggle). Наприклад, я часто використовую приховування спливаючих об'єктів після натискання клавіші Esc. і не можу виключити ситуацію, коли будь-якої енергійний користувач захоче натиснути Esc кілька разів поспіль.
У своїй бібліотеці ir2.js я до сих пір використовував тільки дві функції (додавання-видалення класу) з однаковим регулярним виразом (для перевірки-заміни) в кожній. Мені сподобалася ідея винести перевірку в окрему функцію. Але регекспи (в клас-маніпулюють функціях на openjs.com) все одно повторюються двічі! До того ж регексп складений так, що при перемиканні туди-сюди в className накопичуватимуться зайві прогалини. Ну, якщо вже взявся оптимізувати, треба йти до кінця. В результаті деяких мозкових зусиль вийшло наступне:
Приховати-показати кілька елементів відразу
В даному випадку описана вище «правильна» система (міняти class замість style) сама по собі дає малий виграш - все одно потрібен цикл. Однак обійтися без циклу цілком можливо. Забавно, що навіть в своєму старенькому, 7-річної давності підручнику, я вже наполегливо шукав (і знайшов!) Рішення цієї проблеми. Чи не найкраще, але в багатьох випадках все одно краще циклу: у сторінки просто змінювався один із зовнішніх файлів стилів. Просто і грубо:
Зрозуміло, що при першому запуску це повинно буде гальмувати (поки обидва файли стиль не закешіруются). Ну, да мова не про те. А про хороше, ідеальне рішення (яке таки існує). Воно засноване на тому, що в CSS можна призначати селекторам правила не безпосередньо, а через батьківський елемент. Щось на зразок:
і двома рядками CSS: