arrays - ES5 Javascript:从 2 个选择器中获取唯一值并添加/更新到数组
问题描述
在我的网页上有 2 个选择器 - 一个是选项卡,另一个是下拉菜单。根据用户对选项卡和下拉菜单的点击,我得到点击值并将其推送到数组中。数组中最多有 2 个元素 - 两个元素都需要分别是映射到选项卡和下拉选择的唯一值:
Tag1 -> value from Tab selection
Tag2 -> value from drop down
要将数组添加/更新到特定位置,我使用了Array.prototype.splice()
我设法从选项卡和数组中的下拉列表中推送选择值。但是,我遇到了一些问题场景,如下所述。
请看下面的测试代码:
// Get all tabs
var tabs = document.querySelectorAll('.tab')
// Get select element
var select = document.querySelector('select')
// Create tag array
var tags = []
var tagText = document.querySelector('#tags')
// Register click event listeners for tabs
if (tabs.length > 0) {
tabs.forEach(function (tab) {
tab.addEventListener('click', handleTabClick, true)
})
}
// Register click event listener for select element
if (select) {
select.addEventListener('change', handleSelectChange, true)
}
// Handle tab click
function handleTabClick(e) {
var currentElement = e.target
// Remove all active modifiers
tabs.forEach(function (tab) {
tab.classList.remove('active')
})
// Apply the active modifer to the current element
currentElement.classList.add('active')
// Update the UI showing the correct pane by ID
var id = currentElement.dataset.targetPane
if (id != 'tab-all') {
// Add selected id to array
tags.splice(0, 1, id)
} else {
tags.splice(0, 1, '')
}
tagText.innerHTML = tags
}
// Handle select change
function handleSelectChange(e) {
var id = e.target.value
if (id != 'all') {
// Add selected id to array
tags.splice(1, 1, id)
} else {
tags.splice(1, 1, '')
}
tagText.innerHTML = tags
}
.tabs {
padding-left: 0;
list-style-type: none;
display: flex;
}
.tab {
flex: 1;
text-align: center;
padding: 10px;
cursor: pointer;
color: #000000;
border: 1px solid #d1d1d1;
}
.active {
border-bottom: 3px solid red;
}
Tab options (1st in tags array): Tag 1
<ul class="tabs">
<li class="tab active" data-target-pane="tab-all">All
</li>
<li class="tab" data-target-pane="finance">
Finance
</li>
<li class="tab" data-target-pane="energy">
Energy
</li>
</ul>
Dropdown options (2nd in tags array): Tag 2
<label class="select">
<select>
<option value="all" selected="">All</option>
<option value="whitepaper">Whitepaper</option>
<option value="articles">Articles</option>
<option value="video">Video</option>
</select>
</label>
<p>Return tags array: <b><span id="tags"></span></b></p>
<p>Tag 1 -> value from Tab<br>
Tag 2 -> value from dropdown<br><br>Expect the tags array output to always be [Tag 1 , Tag 2].<br>Max 2 item in array. If user selected "All", empty the previous selection within the same Tag (1 or 2) array location.</p>
问题场景(不良结果)
1) 如果用户首先选择一个下拉选项 (Tag2),然后选择另一个下拉选项 (Tag2):Tags 数组则有 [Tag2, Tag2]。预期:[Tag2]
2) 如果用户首先选择一个下拉选项 (Tag2),然后选择一个选项卡 (Tag1):Tags 数组首先具有 [Tag2],然后被 [Tag1] 替换。预期:[Tag2,Tag1]
3)如果用户首先选择了一个下拉选项(Tag2),然后选择了另一个下拉选项(Tag2),最后选择了下拉值“All”(Tag2):Tags数组首先有[Tag2,Tag2]和“All " 选择它变成 [Tag2,]。预期:第一个 [Tag2] 并选择“全部”,[]
理想场景
1) 如果用户在选择下拉选项 (Tag2) 之前首先选择了一个选项卡 (Tag1):标签数组应该得到 [Tag1, Tag2]。
2) 如果用户选择“全部”,则清空同一标签(1 或 2)数组位置中的先前选择。例如,用户首先选择了一个选项卡 (Tag1),然后选择选项卡“全部”。标签数组获取 []。如果用户首先选择了一个选项卡 (Tag1) 并选择了一个下拉选项 (Tag2),然后选择了下拉“全部”值。标签数组应该变成 [Tag1]
我希望标签数组是以下之一:
1) 数组中最多 2 项 -> [Tag1 , Tag2] 或 [Tag2 , Tag1]
2) 单个数组元素 [Tag1] 或 [Tag2]
但它不应该有 [Tag1, Tag1] 或 [Tag2, Tag2]
简而言之,数组应该具有对应于选项卡选择和下拉选择的唯一值。
解决方案
由于您有时需要 [Tag 1, Tag 2] 和其他时候 [Tag 2, Tag 1] 的结果,因此最好记住您上次将 Tag 1 选择存储在哪个插槽中,这样您就知道两者中的哪一个取代。
我将假设最后做出的选择也将始终是数组中的最后一个值。
所以我引入了tabIndex
0 或 1 的变量。另外,我已经修改了代码,以便它首先从数组中删除当前值(从可以派生自的索引tabIndex
),然后将所选值推送到末尾数组,tabIndex
同时更新。
// Get all tabs
var tabs = document.querySelectorAll('.tab')
// Get select element
var select = document.querySelector('select')
// Create tag array
var tags = []
var tagText = document.querySelector('#tags')
var tabIndex = 0;
// Register click event listeners for tabs
tabs.forEach(function (tab) {
tab.addEventListener('click', handleTabClick, true)
})
// Register click event listener for select element
if (select) {
select.addEventListener('change', handleSelectChange, true)
}
// Handle tab click
function handleTabClick(e) {
var currentElement = e.target
// Remove all active modifiers
tabs.forEach(function (tab) {
tab.classList.remove('active')
})
// Apply the active modifer to the current element
currentElement.classList.add('active')
// Update the UI showing the correct pane by ID
var id = currentElement.dataset.targetPane
tags.splice(tabIndex, 1)
if (id != 'tab-all') {
// Add selected id to array
tabIndex = tags.length
tags.push(id)
}
tagText.textContent = JSON.stringify(tags)
}
// Handle select change
function handleSelectChange(e) {
var id = e.target.value
tags.splice(1-tabIndex, 1)
if (id != 'all') {
// Add selected id to array
tabIndex = 1 - tags.length;
tags.push(id)
}
tagText.textContent = JSON.stringify(tags)
}
.tabs {
padding-left: 0;
list-style-type: none;
display: flex;
}
.tab {
flex: 1;
text-align: center;
padding: 10px;
cursor: pointer;
color: #000000;
border: 1px solid #d1d1d1;
}
.active {
border-bottom: 3px solid red;
}
Tab options (1st in tags array): Tag 1
<ul class="tabs">
<li class="tab active" data-target-pane="tab-all">All</li>
<li class="tab" data-target-pane="finance">Finance</li>
<li class="tab" data-target-pane="energy">Energy</li>
</ul>
Dropdown options (2nd in tags array): Tag 2
<label class="select">
<select>
<option value="all" selected="">All</option>
<option value="whitepaper">Whitepaper</option>
<option value="articles">Articles</option>
<option value="video">Video</option>
</select>
</label>
<p>Return tags array: <b><span id="tags"></span></b></p>
<p>Tag 1 -> value from Tab<br>
Tag 2 -> value from dropdown<br><br>Expect the tags array output to always be [Tag 1 , Tag 2].<br>Max 2 item in array. If user selected "All", empty the previous selection within the same Tag (1 or 2) array location.</p>
推荐阅读
- python - mysql.connector.errors.InternalError:使用“DELETE”时发现未读结果错误
- python - Kivy 弹出窗口显示与主屏幕相同的按钮
- regex - 如何在 PowerShell 中使用正则表达式将动态字符串格式化为数组?
- c# - FluentValidation 不适用于不同的库
- c# - Unity:无法让游戏对象生成
- google-apps-script - 将列值从一个电子表格复制到另一个电子表格,仅添加必要的行
- docker - 可以将 docker 注册表从一台机器复制到另一台机器吗?
- javascript - fileReader.onload 不会第二次运行,即使选择了不同的文件
- alexa-skills-kit - 上传清单文件失败
- java - 如果元素在 java 中不存在,则添加该元素