我正在尝试制作一个下拉菜单,其中有由
p
标签组成的选项,其中有 span
标签。问题是,当我在下拉菜单中选择其中一个选项时,它会将 p
和 span
标签中的文本合并在一起,它们应该具有不同的样式,但结果是相同的。
const dropdowns = document.querySelectorAll('.start__dropdown');
dropdowns.forEach(dropdown => {
const select = dropdown.querySelector('.select');
const caret = dropdown.querySelector('.caret');
const menu = dropdown.querySelector('.menu');
const options = dropdown.querySelectorAll('.menu li');
const selected = dropdown.querySelector('.selected');
select.addEventListener('click', () => {
select.classList.toggle('select-clicked');
caret.classList.toggle('caret-rotate');
menu.classList.toggle('menu-open')
});
options.forEach(option => {
option.addEventListener('click', () => {
selected.innerHTML = option.innerText;
select.classList.remove('select-clicked');
caret.classList.remove('caret-rotate');
menu.classList.remove('menu-open');
options.forEach(opt => {
opt.classList.remove('active');
});
option.classList.add('active');
});
});
});
.start__dropdown {
width: 360px;
position: relative;
height: 68px;
border-bottom: 1px solid $text-black;
}
.select {
background-color: $white;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
padding: 16px;
height: 100%;
transition: background 300ms;
}
.selected {
font-size: 16px;
line-height: 28px;
font-weight: bold;
color: $accent-black;
}
.selected span {
color: $text-black;
margin-left: 8px;
}
.caret {
transition: 300ms;
}
.caret-rotate {
transform: rotate(180deg);
}
.menu {
z-index: 1;
list-style: none;
padding: 0px 30px;
background: $white;
border: 1px solid $text-black;
border-radius: 8px;
position: absolute;
top: 76px;
left: 50%;
transform: translateX(-50%);
width: 367px;
opacity: 0;
display: none;
transition: 200ms;
}
.menu li {
font-size: 16px;
line-height: 28px;
font-weight: bold;
color: $accent-black;
cursor: pointer;
width: 100%;
height: 68px;
border-bottom: 1px solid $text-black;
padding: 20px 16px;
}
.menu li:last-child {
border: none;
}
.menu li span {
color: $text-black;
margin-left: 8px;
}
.menu-open {
display: block;
opacity: 1;
}
<div class="start__dropdown">
<div class="select">
<p class="selected">Basic Pack <span>Free</span></p>
<div class="caret"><img src="icons/sign-up/icon-arrow-down.svg" alt="caret"></div>
</div>
<ul class="menu">
<li class="active">Basic Pack <span>Free</span></li>
<li>Pro Pack <span>$9.99</span></li>
<li>Ultimate Pack <span>$19.99</span></li>
</ul>
</div>
我尝试使用
option.innerText
来获取所选选项的文本内容。
我使用
option.querySelector('span').innerText
从所选选项中获取 <span>
内容。
然后我用
.selected
更新了 .innerHTML
元素的内容,将选项的文本及其价格插入到 <span>
中,但价格是重复的,看起来像这样: <p class="selected">Ultimate Pack $19.99 <span>$9.99</span></p>
options.forEach(option => {
option.addEventListener('click', () => {
// Get the text content and the span content of the selected option
const optionText = option.innerText;
const optionPrice = option.querySelector('span').innerText;
// Update the selected item text including the span
selected.innerHTML = `${optionText} <span>${optionPrice}</span>`;
// Close the dropdown and remove classes
select.classList.remove('select-clicked');
caret.classList.remove('caret-rotate');
menu.classList.remove('menu-open');
// Remove 'active' class from all options
options.forEach(opt => {
opt.classList.remove('active');
});
// Add 'active' class to the selected option
option.classList.add('active');
});
});
问题是因为您正在检索所选选项的
innerText
,因此 span
丢失了。将其更改为 innerHTML
:
selected.innerHTML = option.innerHTML;
这是一个完整的工作示例,但请注意,我修改了 CSS,专门将所选
span
的颜色更改为红色以突出显示效果:
const dropdowns = document.querySelectorAll('.start__dropdown');
dropdowns.forEach(dropdown => {
const select = dropdown.querySelector('.select');
const caret = dropdown.querySelector('.caret');
const menu = dropdown.querySelector('.menu');
const options = dropdown.querySelectorAll('.menu li');
const selected = dropdown.querySelector('.selected');
select.addEventListener('click', () => {
select.classList.toggle('select-clicked');
caret.classList.toggle('caret-rotate');
menu.classList.toggle('menu-open')
});
options.forEach(option => {
option.addEventListener('click', () => {
selected.innerHTML = option.innerHTML;
select.classList.remove('select-clicked');
caret.classList.remove('caret-rotate');
menu.classList.remove('menu-open');
options.forEach(opt => {
opt.classList.remove('active');
});
option.classList.add('active');
});
});
});
.start__dropdown {
width: 360px;
position: relative;
height: 68px;
border-bottom: 1px solid $text-black;
}
.select {
background-color: $white;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
padding: 16px;
height: 100%;
transition: background 300ms;
}
.selected {
font-size: 16px;
line-height: 28px;
font-weight: bold;
color: #000;
}
.selected span {
color: #C00;
margin-left: 8px;
}
.caret {
transition: 300ms;
}
.caret-rotate {
transform: rotate(180deg);
}
.menu {
z-index: 1;
list-style: none;
padding: 0px 30px;
background: $white;
border: 1px solid $text-black;
border-radius: 8px;
position: absolute;
top: 76px;
left: 50%;
transform: translateX(-50%);
width: 367px;
opacity: 0;
display: none;
transition: 200ms;
}
.menu li {
font-size: 16px;
line-height: 28px;
font-weight: bold;
color: $accent-black;
cursor: pointer;
width: 100%;
height: 68px;
border-bottom: 1px solid $text-black;
padding: 20px 16px;
}
.menu li:last-child {
border: none;
}
.menu li span {
color: $text-black;
margin-left: 8px;
}
.menu-open {
display: block;
opacity: 1;
}
<div class="start__dropdown">
<div class="select">
<p class="selected">Basic Pack <span>Free</span></p>
<div class="caret"><img src="icons/sign-up/icon-arrow-down.svg" alt="caret"></div>
</div>
<ul class="menu">
<li class="active">Basic Pack <span>Free</span></li>
<li>Pro Pack <span>$9.99</span></li>
<li>Ultimate Pack <span>$19.99</span></li>
</ul>
</div>