帶有多選和突出顯示關鍵字的自定義下拉選擇框:
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>
效果
效果展示:
我這裡是將可選擇項寫固定的,在實際專案中可以改成輸入關鍵詞,非同步方法去後臺查詢可供選項的列表,繫結到前端該控制元件,然後就是正常的在專案中動態地使用了。