Мне нужен был какой-то метод добавления / удаления классов родительского элемента при щелчке по дочерним элементам, чтобы отразить, какой дочерний элемент выбран в данный момент. В этом случае родитель UL и дочерние элементы LI в схеме вкладок. Мне нужен был способ пометить текущую вкладку в UL, чтобы я мог стилизовать фоновый спрайт в UL; поскольку стилизация фона моего LI не будет работать с графикой в этом случае.
Я новичок в jQuery / Javascript / DOM, но для начала смог собрать уродливое решение,
HTML
<!-- tabs -->
<ul class="tabs currenttab-info">
<li id="tab-info" class="info"><strong><a href="#">Information</a></strong></li>
<li id="tab-write" class="write"><strong><a href="#">Write Feedback</a></strong></li>
<li id="tab-read" class="read"><strong><a href="#">Read Feedback</a></strong></li>
</ul>
Javascript
// send '.currenttab-x' to '.tabs' and remove '.currenttab-y' + '.currenttab-z'
// when LI #tab-X is clicked ...
$( '#tab-info' ).click(function() {
// ... find the UL and remove the first possible conflicting class
$('.tabs').removeClass("currenttab-read");
// ... find the UL and remove the other possible conflicting class
$('.tabs').removeClass("currenttab-write");
// ... find the UL and add the class for this LI
$('.tabs').addClass("currenttab-info");
});
// ... repeat ...
$( '#tab-write' ).click(function() {
$('.tabs').removeClass("currenttab-info");
$('.tabs').removeClass("currenttab-read");
$('.tabs').addClass("currenttab-write");
});
$( '#tab-read' ).click(function() {
$('.tabs').removeClass("currenttab-info");
$('.tabs').removeClass("currenttab-write");
$('.tabs').addClass("currenttab-read");
});
Кажется, это действительно работает, НО это неуклюжее решение, и я уверен , что есть способ получше. Некоторые из вас, ниндзя jQuery, будут знать, как очень элегантно объединить эту функциональность, какая-нибудь помощь?
Также я хотел бы добавить к этому, чтобы щелкнувший LI также получил класс, чтобы показать, что он выбран, в то время как другие LI лишены любого такого класса. То же самое я уже делаю для UL; Я вижу, как это сделать, используя свой неудобный подход, но это будет означать, что будет появляться все больше и больше строк беспорядочного кода. Если бы ваше улучшение также включало способ изменения классов LI, я был бы признателен
FYI: я использую вкладки jQuery Tools с этим, поэтому jQuery больше, чем я показал, но только тот бит, который я процитировал, кажется актуальным .
Я удалю id
из li
, если вы не используют его для других целей.
<ul class="tabs currenttab-info">
<li class="info"><strong><a href="#">Information</a></strong></li>
<li class="write"><strong><a href="#">Write Feedback</a></strong></li>
<li class="read"><strong><a href="#">Read Feedback</a></strong></li>
</ul>
$('.tabs li').click(function() {
var $li = $(this);
$li.addClass('current').siblings().removeClass('current'); // adds a current class to the clicked li
var $ul = $li.parent();
$ul.removeClass("currenttab-info currenttab-read currenttab-write")
.addClass("currenttab-" + this.class ); // assuming li only holds one class e.g. class="write"
});
$("UL.tabs LI A").bind('click',function(e){ //bind a Click-Event handler to the Links
var $target = $(e.target); //the jQuery-Object-Reference to the clicked target ( $(this) should work too)
var LIClasses = $target.parents('LI').attr('class'); //A list of all Classes the parrent LI of the clicked Link have
$target
.parents('UL.tabs')
//now you can remove and add classes to the parent "UL.tabs"
.removeClass('...')
.addClass('...')
.end() //after .end() the chain for .parents-match is broken
.parents('LI')
//here you can add and remove classes from the parent LI
.removeClass('...')
.addClass('...')
.end() //after .end() the chain for .parents-match is broken
;
});
Примечания:
.removeClass()
и .addClass()
могут работать с несколькими именами классов одновременно, оперируя с пробелом (например, .removeClass('class1 class2')
)Полное решение:
var relevantClasses = ['read','write','info'];
$("UL.tabs LI A").bind('click',function(e){
var $target = $(e.target);
var relevantClass = '';
for( var cl in $target.parents('LI').attr('class').split(' ') )
if( jQuery.inArray(relevantClasses , cl) > -1 ){
relevantClass = cl;
break;
}
$target
.parents('UL.tabs')
.removeClass(jQuery.map(relevantClasses , function (className) { return 'currenttab-' + className; }).join(' '))
.addClass('currenttab-'+relevantClass )
.end()
;
});
Вы можете просто сделать что-то вроде этого:
$('.tabs > li').click(function() {
$(this).parent().attr('class', 'tabs').addClass('currenttab-'+$(this).attr('class'));
});
Прежде всего, вы можете связать вызовы методов...
$('.tabs').removeClass("currenttab-read currenttab-write").addClass("currenttab-write");
Это сделает код намного чище...
EDIT: я попробую такие вещи в Fiddle http://jsfiddle.net/JvtAz/