ES5 Javascript: 从 2 选择器和 add/update 获取唯一值到数组
ES5 Javascript: Get unique value from 2 selector and add/update to array
在我的网页上有 2 个选择器 - 一个是选项卡,另一个是下拉列表。基于用户点击选项卡和下拉菜单,我得到点击值并将其推送到一个数组。数组中最多有 2 个元素 - 两个元素都需要是分别映射到选项卡和下拉选择的唯一值:
Tag1 -> value from Tab selection
Tag2 -> value from drop down
把add/update数组放到特定位置,我用了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]。预期:[标签 2]
2) 如果用户首先选择一个下拉选项 (Tag2) 然后选择一个选项卡 (Tag1):Tags 数组首先具有 [Tag2],然后被 [Tag1] 替换。预期:[Tag2,Tag1]
3) 如果用户首先选择一个下拉选项 (Tag2),然后选择另一个下拉选项 (Tag2),最后选择下拉值 "All" (Tag2):Tags 数组首先有 [Tag2 , Tag2] 并选择 "All" 它变成 [Tag2,]。预期:第一个 [Tag2] 并选择 "All",[]
理想场景
1) 如果用户在选择下拉选项 (Tag2) 之前首先选择了一个选项卡 (Tag1):Tags 数组应为 [Tag1, Tag2]。
2) 如果用户选择了 "All",则清空同一标签(1 或 2)数组位置中的先前选择。例如,用户首先选择了一个选项卡 (Tag1),然后选择了选项卡 "All"。标签数组获取 []。如果用户首先选择了一个选项卡 (Tag1) 并选择了一个下拉选项 (Tag2),然后选择了下拉 "All" 值。标记数组应变为 [Tag1]
我希望标签数组是以下之一:
1) 数组中最多 2 个项目 -> [Tag1 , Tag2] 或 [Tag2 , Tag1]
2) 单个数组元素 [Tag1] 或 [Tag2]
但它不应该有 [Tag1, Tag1] 或 [Tag2, Tag2]
简而言之,数组应具有与选项卡选择和下拉选择相对应的唯一值。
由于您有时需要 [Tag 1, Tag 2] 的结果,有时需要 [Tag 2, Tag 1],最好记住您上次存储 Tag 1 选择的位置,以便您知道要替换两者中的哪一个。
我假设 last 所做的选择也将始终是数组中的 last 值。
所以我引入了变量 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>
在我的网页上有 2 个选择器 - 一个是选项卡,另一个是下拉列表。基于用户点击选项卡和下拉菜单,我得到点击值并将其推送到一个数组。数组中最多有 2 个元素 - 两个元素都需要是分别映射到选项卡和下拉选择的唯一值:
Tag1 -> value from Tab selection
Tag2 -> value from drop down
把add/update数组放到特定位置,我用了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]。预期:[标签 2]
2) 如果用户首先选择一个下拉选项 (Tag2) 然后选择一个选项卡 (Tag1):Tags 数组首先具有 [Tag2],然后被 [Tag1] 替换。预期:[Tag2,Tag1]
3) 如果用户首先选择一个下拉选项 (Tag2),然后选择另一个下拉选项 (Tag2),最后选择下拉值 "All" (Tag2):Tags 数组首先有 [Tag2 , Tag2] 并选择 "All" 它变成 [Tag2,]。预期:第一个 [Tag2] 并选择 "All",[]
理想场景
1) 如果用户在选择下拉选项 (Tag2) 之前首先选择了一个选项卡 (Tag1):Tags 数组应为 [Tag1, Tag2]。
2) 如果用户选择了 "All",则清空同一标签(1 或 2)数组位置中的先前选择。例如,用户首先选择了一个选项卡 (Tag1),然后选择了选项卡 "All"。标签数组获取 []。如果用户首先选择了一个选项卡 (Tag1) 并选择了一个下拉选项 (Tag2),然后选择了下拉 "All" 值。标记数组应变为 [Tag1]
我希望标签数组是以下之一:
1) 数组中最多 2 个项目 -> [Tag1 , Tag2] 或 [Tag2 , Tag1]
2) 单个数组元素 [Tag1] 或 [Tag2]
但它不应该有 [Tag1, Tag1] 或 [Tag2, Tag2]
简而言之,数组应具有与选项卡选择和下拉选择相对应的唯一值。
由于您有时需要 [Tag 1, Tag 2] 的结果,有时需要 [Tag 2, Tag 1],最好记住您上次存储 Tag 1 选择的位置,以便您知道要替换两者中的哪一个。
我假设 last 所做的选择也将始终是数组中的 last 值。
所以我引入了变量 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>