jQuery标签点击问题:阻止重复点击边框扩展及元素存在判断
Hey there! Let's work through your two issues step by step:
问题根源
Every time you click mod-2 or mod-3, the code runs $('.vd-list li').wrapInner('<div class="l-item"></div>') — this wraps the existing content inside the li (including any already-existing .l-item div) in a new .l-item container. Since your CSS adds a 3px border to every .l-item, each click adds another layer of border, making it look like the border is expanding.
解决方案
Before wrapping the content, first remove any existing .l-item wrappers using contents().unwrap(). This ensures we start fresh each time, so we only have one .l-item per li, preventing border stacking.
.l-item容器 问题根源
The current code runs wrapInner every time you click mod-2/mod-3, even if the .l-item already exists. We need to either check for its presence first, or reset the state to avoid duplicates.
解决方案
The simplest approach is to combine this fix with the first issue's solution: by unwrapping any existing .l-item before wrapping again, you automatically ensure no duplicates are created. Alternatively, you could target only li elements without .l-item using :not(:has(.l-item)), but the unwrap-then-wrap method is more consistent for your tab switching flow.
JavaScript
$('.mod-1').on('click', function() { $('.display-tab .on').removeClass('on'); $(this).addClass('on'); $('.vd-list').removeClass('mod-2').removeClass('mod-3').addClass('mod-1'); $('.vd-list .l-item').contents().unwrap(); $('.vd-list .v-date, .vd-list .v-info-i:last-child, .vd-list .v-desc').show(); }); $('.mod-2').on('click', function() { $('.display-tab .on').removeClass('on'); $(this).addClass('on'); $('.vd-list').removeClass('mod-1').removeClass('mod-3').addClass('mod-2'); // Fix both issues: clear existing wrappers first, then re-wrap $('.vd-list li .l-item').contents().unwrap(); $('.vd-list li').wrapInner('<div class="l-item"></div>'); $('.vd-list .v-date, .vd-list .v-info-i:last-child').hide(); $('.vd-list .v-desc').show(); return false; }); $('.mod-3').on('click', function() { $('.display-tab .on').removeClass('on'); $(this).addClass('on'); $('.vd-list').removeClass('mod-1').removeClass('mod-2').addClass('mod-3'); // Fix both issues: clear existing wrappers first, then re-wrap $('.vd-list li .l-item').contents().unwrap(); $('.vd-list li').wrapInner('<div class="l-item"></div>'); $('.vd-list .v-date, .vd-list .v-info-i:last-child, .vd-list .v-desc').hide(); });
CSS
.tab-list { display: inline-block; vertical-align: middle; } .tab-list li { float: left; height: 48px; line-height: 48px; margin-right: 20px; cursor: pointer; color: #222; text-align: center; font-size: 14px; font-weight: bold; } .mod-2 .l-item, .mod-3 .l-item { border: 3px solid #111; } .mod-1 .r::after { content: "Mod 1"; color: red; font-weight: bold; } .mod-2 .r::after { content: "Mod 2"; color: green; font-weight: bold; } .mod-3 .r::after { content: "Mod 3"; color: blue; font-weight: bold; } ul { list-style: none; }
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <ul class="tab-list display-tab"> <li class="mod-1 on">Mod 1</li> <li class="mod-2">Mod 2</li> <li class="mod-3">Mod 3</li> </ul> <ul class="vd-list mod-1"> <li> <div class="l"></div> <div class="r"> <div class="v-desc">desc</div> <div class="v-info"> <span class="v-info-i">1</span> <span class="v-info-i">2</span> <span class="v-info-i">3</span> </div> <div class="v-date">date</div> </div> </li> </ul>
内容的提问来源于stack exchange,提问作者luckidtk

