Механизм, который мы часто используем, заключается в том, что на теле есть несколько общих слушателей событий, и все необходимые события всплывают. После обнаружения мы проверяем определенное имя className (или шаблон className) в инициирующем элементе. Если такое имя класса найдено, мы считаем его идентификатором состояния и запускаем поведение на основе таких состояний.
Например, мы определили пары className (такие как «selected» и «unselected») с переключением по умолчанию. Или сделайте их эксклюзивными, предоставив родительскому элементу className «exclusive-selected».
Простой механизм, подобный этому, может быть расширен по вашему вкусу и может быть очень мощным.
Позвольте мне опубликовать простую демонстрацию. Не является общим, но это просто для иллюстрации внутренней работы такого механизма. В этом примере я считаю, что пара className "selected" и "unselected" является эксклюзивной.
<html>
<head>
<script>
document.onclick = function(evt) {
var el = window.event? event.srcElement : evt.target;
if (el && el.className == "unselected") {
el.className = "selected";
var siblings = el.parentNode.childNodes;
for (var i = 0, l = siblings.length; i < l; i++) {
var sib = siblings[i];
if (sib != el && sib.className == "selected")
sib.className = "unselected";
}
}
}
</script>
<style>
.selected { background: #f00; }
</style>
</head>
<body>
<a href="#" class="selected">One</a>
<a href="#" class="unselected">Two</a>
<a href="#" class="unselected">Three</a>
</body>
</html>
Должно работать в IE, Firefox и других браузерах. Конечно, этот механизм можно сделать универсальным и реализовать все виды состояний и поведений className.