Javascript функция за скриване и показване на HTML елементи

29 януари 2007, 03:41 ч  •  Уеб дизайн и програмиране  •  коментари: 5

В много сайтове се налага даден HTML елемент да се скрива и показва последователно при случване дадено събитие, наример клик на мишката. Обикновено за целта се ползват разни набързо скалъпени javascript функции или направо се пише в onclick атрибута на HTML елемента. Днес ме вдъхновиха да сътворя нещо по-смислено и универсално, и ето какво излезе.

Набързо скалъпена версия на скрипт за скриване и показване може да бъде нещо такова:

function toggleDisplay(elementID)
{
if(document.getElementById(elementID).style.display == 'none')
{
  document.getElementById(elementID).style.display = 'block';
}
else
{
  document.getElementById(elementID).style.display = 'none';
}
}

Очевидният недостатък на функцията е, че работи само с блокови елементи. Целта сега е да може да се скриват и показват всякакви елементи, без да се интересуваме от тяхното display property. Затова вместо задаване на inline стил, ще ползваме класове и ще сменяме тях:

function toggleDisplay(elementID)
{
var displayNoneClass = 'hideit';
if (document.getElementById(elementID)/*без нов ред*/
.className.indexOf(displayNoneClass) != -1)
{
document.getElementById(elementID).className =
document.getElementById(elementID)/*без нов ред*/
.className.replace(displayNoneClass, '');
}
else
{
document.getElementById(elementID)/*без нов ред*/
.className += ' '+displayNoneClass;
}
}

Идеята на indexOf и replace методите е, че може елементът, който скриваме и показваме, да си има и други зададени класове. Ако не ползваме replace, ще ги затрием.

Променливата displayNoneClass пази името на класа, за който в CSS-а сме казали, че е display:none. Изнесох го като променлива, за да се сменя по-лесно, без да трябва човек да се разхожда из цялата функция.

Във функцията toggleDisplay() може да се вкарат няколко екстри за дуракоустойчивост, като например проверка дали елемент с подаденото като параметър ID съществува, или дали няма сложен inline стил display на елемента, който ще пречи на правилното скриване и показване. В този случай функцията се раздува, но работи безотказно.

Целият пример може да се види в действие тук: http://dev.dimodi.com/javascript-display/

Коментари

Можеш да следиш коментарите към този сайт и чрез RSS.

Илия Горанов gravatar

Илия Горанов  •  04 февруари 2007, 01:28 ч

В първата функция, ако не искаш да се интересуваш дали елементът е блоков или не, можеш просто да задаваш .style.display = '';

Новият проблем (може и да не е проблем) е, че .style всъщност е съдържанието на style атрибута на съответния елемент, а не неговия реален стил. Реалния стил е currentStyle в MSIE или една сложна хава в Mozilla базираните браузъри. Та като зададеш на някое property да е празно - всъщност ти го премахваш от style атрибута и по този начин, елементът придобива нормалното си състояние или го наследява от някоя CSS дефиниция. Та ако за елемента не е дефинирано да е скрит в някоя CSS дефиниция - можеш да го криеш и показваш така, без да се интересуваш дали е блоков :)

Димо gravatar

Димо  •  04 февруари 2007, 02:54 ч

@Илия

Да, може и със style.display = ''; , само че това няма да сработи, ако с inline стил е сетнато display property с различна стойност от нормалната за елемента. Както и ти отбеляза - след първото скриване и показване, ще се върне към нормалното си състояние ;)

Mariush Minkov gravatar

Mariush Minkov  •  04 февруари 2007, 08:26 ч

Честно казано идеята за toggle не ми се вписва особено в контекста за универсалност - резултата от нея е зависим от текущото състояние на елемента. Но ако имаме няколко елемента и е нобходимо да поддържаме комбинации от състоянията им, било трудно да изградим подобна логика без да се се съсипем от излишни проверки с цел да разберем да викаме ли сега тогъл или не.

Стефан gravatar

Стефан  •  05 февруари 2007, 23:16 ч

Не, че тая версия на функцията няма недостатъци, но:

function toggleDisplay(elementID)
{
var el = document.getElementById(elementID);

if(!el.visibleState)
{
el.visibleState = el.style.display != "none" ? el.style.display : "block";
}

el.style.display = el.style.display == "none" ? el.visibleState : "none";
}

abozhilov gravatar

abozhilov  •  25 март 2007, 04:08 ч

Ето универсално решение:

function getDisplayProperty(sender)
{
var objStyle = (sender.currentStyle) ? sender.currentStyle : window.getComputedStyle(sender, '');
return objStyle['display'];
}

var defaultDisplay = null;

function toggleDisplay(sender)
{
var obj = document.getElementById(sender);
if (!defaultDisplay) defaultDisplay = getDisplayProperty(obj);

obj.style.display = (obj.style.display != 'none') ? 'none' : defaultDisplay;
}

Хич не ми харесва идеята два пъти да се прави достъп до един елемент чрез:
document.getElementById('someId')
Далече по-добре ми се струва да се присвои обекта на една променлива и след това да си осигуряваме достъп до пропъртитата на съответния обект.Не за друго а просто това е излишно и два пъти караме DOM парсера да намира този обект.
Същото е и в кода на @Стефан, там се сетва ново пропърти на обекта и след това пак чрез DOM парсера се осигурява достъп до това свойство когато ни потрябва.

Коментирай

Полетата с по-тъмен етикет са задължителни. Email-ът ти няма да бъде публикуван. Писането на кирилица е желателно. Сайтът поддържа граватари.

сайтът е обновен на

(cc) dimodi web.

dimodi web : уебсайт на Димо Димов