带有多选和突出显示关键字的自定义下拉选择框(静态)
带有多选和突出显示关键字的自定义下拉选择框:
Custom Dropdown Select Box with Multiple Selection and Highlighting Keywords:
不使用select元素,用div、ul、li、span元素实现带有多选和突出显示关键字的自定义下拉选择框。
完整控件包含三部分:
- 第一步用div模拟select选择框,ul+li模拟option选项,并用span标记关键词;
- 第二步CSS渲染展示效果;
- 第三步用原生JavaScript脚本实现点击选择,多选,取消选择,获取选中项结果(数组);
1,HTML模拟选择框
核心代码如下:
<!-- 自定义下拉选择框 html 开始 -->
<div class="custom-select">
<div class="selected-options">
<span class="placeholder">请选择...</span>
</div>
<ul class="options-list">
<li class="option" data-value="option1">选项1 <span class="highlight">关键词</span></li>
<li class="option" data-value="option2">选项2</li>
<li class="option" data-value="option3">这个选项3 也有<span class="highlight">关键词</span></li>
<li class="option" data-value="option4">选项4</li>
</ul>
</div>
<!-- 自定义下拉选择框 html 结束 -->
搭配上CSS样式渲染就可以看到静态的选择框。接下来还学通过JavaScript脚本实现功能逻辑。
2,JavaScript脚本实现功能逻辑
我们知道JavaScript是浏览器前端脚本语言,要实现网页动态效果是很合适的。根据面向对象编程思想,首先我们得拿到要处理的对象,即HTML标签(DOM元素),例如:
var customSelect = document.querySelector('.custom-select');
var optionsList = document.querySelector('.options-list');
var selectedOptions = document.querySelector('.selected-options');
var options = document.querySelectorAll('.option');
接着我们对标签元素绑定事件驱动,例如:
监听DOMContentLoaded触发事件
DOMContentLoaded 是一个在网页的文档结构(DOM)加载完成后触发的事件,而不需要等待所有的外部资源(如图片、样式表、脚本等)加载完成。这个事件对于执行依赖于DOM解析完成后的JavaScript代码非常有用,因为它允许你尽早地开始执行代码,而不必等待整个页面完全加载。
在JavaScript中,你可以使用 addEventListener 方法来监听 DOMContentLoaded 事件。以下是一个简单的示例:
// 网页的文档结构(DOM)加载完成后触发的事件
document.addEventListener('DOMContentLoaded', function (event) {
event.stopPropagation(); // 阻止事件冒泡到外层元素
console.log('DOM已加载完成!');
// 在这里执行你的代码
}
在这个示例中,当 DOMContentLoaded 事件触发时,会执行一个匿名函数,该函数在控制台输出一条消息。你可以在这个函数内部执行任何需要在DOM加载完成后运行的JavaScript代码。
需要注意的是,DOMContentLoaded 事件只会在文档的初始加载时触发一次。如果你希望在页面加载完成后执行某些操作,并且这些操作需要在每次页面加载时都执行,你可能需要考虑使用其他方法,如 load 事件或 jQuery 的 $(document).ready() 方法(如果你在使用jQuery)。
另外,如果你正在编写一个库或框架,并且需要确保在DOM加载完成之前不执行任何操作,那么监听 DOMContentLoaded 事件可能是一个很好的选择。这样可以确保你的代码在DOM结构可用时立即执行,而不必等待其他资源加载完成。
监听click触发事件
在JavaScript中,click事件是一个常用的鼠标事件,它在用户点击某个元素(例如,按钮、链接、图片等)时触发。你可以使用addEventListener方法来监听click事件,并在事件触发时执行相应的代码。
通过监听click事件,可以实现各种交互效果,例如按钮点击、链接跳转、图片放大等。可以通过addEventListener方法将click事件绑定到指定的元素上,并在事件触发时执行相应的操作。
以下是一个三种常见的简单示例代码,演示了如何使用click事件:
// 选项标签元素绑定click触发事件
document.querySelectorAll('.option').addEventListener('click', function (event) {
event.stopPropagation(); // 阻止事件冒泡到外层元素
console.log('选项标签元素被点击了!');
});
// 实时创建的标签元素绑定click触发事件
var span = document.createElement('span');
span.addEventListener('click', function (event) {
event.stopPropagation(); // 阻止事件冒泡到外层元素
console.log('实时创建的标签元素被点击了!');
});
// 点击选项以外的地方触发事件
document.addEventListener('click', function (e) {
e.stopPropagation(); // 阻止事件冒泡到外层元素
console.log('选项以外的地方被点击了!');
});
需要注意的是,同一个元素可以添加多个同类型的事件监听器,它们会按照添加的顺序依次执行。此外,你可以使用removeEventListener方法来移除之前添加的事件监听器。
这部分更详细可以参考:JavaScript操作addEventListener监听触发事件
数组的遍历、插入、删除操作
在JavaScript中,数组是一种常见的数据结构,可以包含多个元素,并且可以进行遍历、插入和删除等操作。
这部分更详细可以参考:JavaScript操作数组
调整标签元素展示样式
在JavaScript中,classList.toggle 是一个DOM(Document Object Model)元素的方法,用于切换元素的类名。如果元素已经包含指定的类名,则该类名会被移除;如果元素不包含指定的类名,则该类名会被添加。这个方法在动态修改元素的样式时非常有用。
这部分更详细可以参考:JavaScript操作DOM元素的classList
完整代码
完整代码(DropdownSelectBox.html 单个网页文件):
点击查看代码
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="MobileOptimized" content="240">
<meta name="applicable-device" content="mobile">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no,shrink-to-fit=no">
<meta name="format-detection" content="telephone=no,email=no,adress=no">
<meta name="theme-color" content="#3c80d4" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#9cc8ff" media="(prefers-color-scheme: dark)">
<title>带有多选和突出显示关键字的自定义下拉选择框</title>
<meta name="Description" content="带有多选和突出显示关键字的自定义下拉选择框:Custom Dropdown Select Box with Multiple Selection and Highlighting Keywords">
<meta name="author" content="熊仔其人">
<!-- CSS样式 -->
<style type="text/css">
/* 自定义下拉选择框 CSS 开始 */
.custom-select {
position: relative;
width: 200px;
border: 1px solid #ccc;
border-radius: 5px;
padding: 1px;
}
.selected-options {
padding: 1px;
cursor: pointer;
background-color: #fff;
display: flex;
flex-wrap: wrap;
gap: 5px;
}
.selected-options .selectedOptions-icon-cross {
background-color: #f8f9fa;
border: 1px solid #ccc;
border-radius: 5px;
padding: 1px;
}
.selected-options .selectedOptions-icon-cross::after {
/* content: '\2717'; */
content: '\2715';
}
.placeholder {
color: #999;
}
.options-list {
position: absolute;
top: 100%;
left: 0;
right: 0;
border: 1px solid #ccc;
border-top: none;
border-radius: 0 0 5px 5px;
background-color: #fff;
list-style: none;
padding: 0;
margin: 0;
display: none;
/* 默认隐藏选项列表 */
}
.option {
padding: 5px;
cursor: pointer;
}
.option:hover {
background-color: #f2f2f2;
}
.option.selected {
background-color: #e0e0e0;
}
.option.selected::after {
/* content: '\221A'; */
content: '\2713';
color: #007bff;
margin-left: 5px;
}
.highlight {
color: red;
/* 关键词标红 */
}
/* 显示选项列表 */
.custom-select.active .options-list {
display: block;
}
/* 自定义下拉选择框 CSS 结束 */
</style>
</head>
<body>
带有多选和突出显示关键字的自定义下拉选择框:
Custom Dropdown Select Box with Multiple Selection and Highlighting Keywords:
<hr />
<!-- 自定义下拉选择框 html 开始 -->
<div class="custom-select">
<div class="selected-options">
<span class="placeholder">请选择...</span>
</div>
<ul class="options-list">
<li class="option" data-value="option1">选项1 <span class="highlight">关键词</span></li>
<li class="option" data-value="option2">选项2</li>
<li class="option" data-value="option3">这个选项3 也有<span class="highlight">关键词</span></li>
<li class="option" data-value="option4">选项4</li>
</ul>
</div>
<!-- 自定义下拉选择框 html 结束 -->
<!-- 自定义下拉选择框 JS脚本 开始 -->
<script>
document.addEventListener('DOMContentLoaded', function (event) {
event.stopPropagation(); // 阻止事件冒泡到外层元素
var customSelect = document.querySelector('.custom-select');
var optionsList = document.querySelector('.options-list');
var selectedOptions = document.querySelector('.selected-options');
var options = document.querySelectorAll('.option');
// 显示/隐藏选项列表
selectedOptions.addEventListener('click', function (event) {
event.stopPropagation(); // 阻止事件冒泡到外层元素
customSelect.classList.toggle('active');
});
// 选项点击事件
options.forEach(function (option) {
option.addEventListener('click', function (event) {
event.stopPropagation(); // 阻止事件冒泡到外层元素
var isSelected = this.classList.contains('selected');
this.classList.toggle('selected', !isSelected);
// 更新已选项显示
updateSelectedDisplay();
});
});
// 点击选项以外的地方关闭选项列表
document.addEventListener('click', function (e) {
e.stopPropagation(); // 阻止事件冒泡到外层元素
if (!customSelect.contains(e.target)) {
customSelect.classList.remove('active');
}
});
// 更新已选项的显示
function updateSelectedDisplay() {
var selectedItems = [];
options.forEach(function (option) {
if (option.classList.contains('selected')) {
selectedItems.push({ value: option.getAttribute('data-value'), text: option.textContent.trim() });
}
});
// 清空并重新填充已选项
selectedOptions.innerHTML = '';
if (selectedItems.length === 0) {
selectedOptions.appendChild(document.createTextNode('请选择...'));
} else {
selectedItems.forEach(function (item) {
var span = document.createElement('span');
span.setAttribute('class', 'selectedOptions-icon-cross');
span.setAttribute('data-value', item.value);
span.textContent = item.text + ' ';
span.addEventListener('click', function (event) {
event.stopPropagation(); // 阻止事件冒泡到外层元素
var itemValue = this.getAttribute('data-value');
options.forEach(function (option) {
if (option.getAttribute('data-value') == itemValue) {
option.classList.toggle('selected', false);
}
});
// 更新已选项显示
updateSelectedDisplay();
});
selectedOptions.appendChild(span);
});
}
}
});
// 获取选中项
function getSelectedItems() {
var selectedItems = [];
var selectedOptions = document.querySelectorAll('.custom-select .selected-options .selectedOptions-icon-cross');
selectedOptions.forEach(function (option) {
selectedItems.push({ value: option.getAttribute('data-value'), text: option.textContent.trim() });
});
return selectedItems;
}
</script>
<!-- 自定义下拉选择框 JS脚本 结束 -->
</body>
</html>
效果
效果展示:
我这里是将可选择项写固定的,在实际项目中可以改成输入关键词,异步方法去后台查询可供选项的列表,绑定到前端该控件,然后就是正常的在项目中动态地使用了。
请看下一篇: 带有多选和突出显示关键字的自定义下拉选择框(动态) >>