quiz
quiz copied to clipboard
DOM基础测试40
本期关于常见的列表操作,以及简单的快捷键访问支持。
积分:3+4
大家提交回答的时候,注意缩进距离,起始位置从左边缘开始;另外,github自带代码高亮,所以请使用下面示意的格式(缩进和代码高亮1积分)。
```js // 你的JS代码写在这里 ```
**心怀瑞雪,自己作答,不要参考别人回答**
其他 本周因为要去北京参加活动,因此直播时间改为下周六和CSS小测一起,直播地址:https://live.bilibili.com/21193211
每位答题者会有至少2积分参与分,本次小测满分9积分,1分隐藏奖励分。
首位答题者将会获得100%被翻牌的技能。
{
let now = -1;
let oInput = document.querySelector("input");
let aLi = document.querySelectorAll("#list li");
aLi.forEach((item, index) => {
item.addEventListener("click", () => {
if (now != index) {
aLi[now] && aLi[now].classList.remove("selected");
oInput.value = item.innerHTML;
item.classList.add("selected");
now = index;
}
})
});
let move = (dir) => {
aLi[now] && aLi[now].classList.remove("selected");
dir === "up" ? now-- : now++;
if (now < 0) {
now = aLi.length - 1;
}
if(now > aLi.length - 1){
now = 0;
}
oInput.value = aLi[now].innerHTML;
aLi[now].classList.add("selected");
};
document.addEventListener("keyup", ({keyCode}) => {
switch (keyCode) {
case 38: //up
move("up");
break;
case 40: //down
move("down");
break;
}
})
}
var input = document.querySelector("#input");
var list = document.querySelector("#list");
list.addEventListener("click",function(e){
var target = e.target;
var selected = list.querySelector(".selected");
selected&&selected.classList.remove("selected");
target.classList.add('selected');
input.value = target.innerHTML;
})
var lis = list.querySelectorAll('li');
window.addEventListener("keyup",function(e){
var selected = list.querySelector(".selected"),
target;
switch(e.keyCode){
case 40:
if(!selected||selected===list.lastElementChild){
target = list.firstElementChild;
}else{
target = selected.nextElementSibling;
};
break;
case 38:
if(!selected||selected===list.firstElementChild){
target = list.lastElementChild;
}else{
target = selected.previousElementSibling;
};
break;
}
if([38,40].includes(e.keyCode)){
selected&&selected.classList.remove("selected");
target.classList.add('selected');
input.value = target.innerHTML;
}
})
https://jsbin.com/tunino/edit?html,css,output
var list = document.getElementById('list');
var input = document.getElementById('input');
function selected(target) {
// 在列表中选择 有 selected 的元素 不取消不在列表中的selected元素
var items = list.querySelectorAll('.selected');
var txt = target.innerText.replace(/$\s+/).replace(/\s+^/);
input.value = txt;
items && items.length > 0 && items.forEach(item => {item.classList.remove('selected')});
target.classList.add('selected');
}
// 点击
list.addEventListener('click', (e) => {
var target = e.target;
selected(target);
});
function move(e) {
var keyCode = e.keyCode;
if(keyCode !== 38 && keyCode !== 40){
return;
}
var items = list.children;
var index = Array.prototype.reduce.call(items,(init,item, i) => {
return item.classList.contains('selected') ? i : init;
},-1)
if(keyCode === 40) {
//向下
index = index === -1 ? 0 : (index + 1) % items.length;
}
else{
// 向上
index = index === -1 ? items.length - 1 : (index + items.length - 1) % items.length;
}
selected(items[index]);
}
// 按键
window.addEventListener('keyup',(e) => {
move(e);
})
//zxx: 有bug,会同时出现两个红色
let input = document.querySelector('#input')
let list = document.querySelectorAll('#list li')
let originTarget
list.forEach((item) => {
item.addEventListener('click', e => {
if (originTarget) {
originTarget.classList.remove('selected')
}
console.log(e.target.classList)
originTarget = e.target
input.value = e.target.innerText
e.target.classList.toggle('selected')
})
})
// 2
function selectedIndex(arr) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].classList.contains('selected')) return i
}
return -1
}
function sync(current, prev, input) {
if (current) {
console.log(current)
current.classList.add('selected')
input.value = current.innerText
}
prev ? prev.classList.remove('selected') : ''
}
document.addEventListener('keydown', e => {
let si = selectedIndex(list)
let current
let prev
if (e.keyCode == 40) {
if (si == list.length - 1) {
prev = list[si]
current = list[0]
} else if (si >= 0) {
prev = list[si]
current = list[si + 1]
} else {
current = list[0]
}
sync(current, prev, input)
} else if (e.keyCode == 38) {
if (si > 0) {
prev = list[si]
current = list[si - 1 % list.length]
} else if (si == 0) {
prev = list[si]
current = list[list.length - 1]
} else {
current = list[list.length - 1]
}
sync(current, prev, input)
}
})
const input = document.getElementById("input");
const list = document.getElementById("list");
const func = (nextEle, prevEle) => {
if (prevEle) {
prevEle.classList.remove("selected");
}
input.value = nextEle.innerText;
nextEle.classList.add("selected");
};
// 点击li列表元素赋值
list.addEventListener("click", function(e) {
const element = e.target;
const name = element.nodeName;
if (name === "LI") {
const oldSelectedLi = list.getElementsByClassName("selected")[0];
func(element, oldSelectedLi);
}
});
// 监听键盘上下方向,按键后列表高亮并同时赋值
document.addEventListener("keyup", function(e) {
const keyCode = e.keyCode;
if (keyCode === 38) {
const oldSelectedLi = list.getElementsByClassName("selected")[0];
if (oldSelectedLi) {
const prevEle = oldSelectedLi.previousElementSibling;
if (prevEle) {
func(prevEle, oldSelectedLi);
return;
}
}
const lastEle = list.lastElementChild;
func(lastEle, oldSelectedLi);
}
if (keyCode === 40) {
const oldSelectedLi = list.getElementsByClassName("selected")[0];
if (oldSelectedLi) {
const nextEle = oldSelectedLi.nextElementSibling;
if (nextEle) {
func(nextEle, oldSelectedLi);
return;
}
}
const firstEle = list.firstElementChild;
func(firstEle, oldSelectedLi);
}
});
var input = document.getElementById('input');
var oul = document.getElementById('list');
var list = oul.querySelectorAll('li');
var vlist = oul.querySelectorAll('li:not([hidden])');
var index = -1;
function setIndex(i){
var max = vlist.length - 1;
if(i<0){
i = max;
}
if(i>max){
i = 0;
}
vlist[index] && vlist[index].classList.remove('select');
vlist[i].classList.add('select');
input.value = vlist[i].innerText;
index = i;
}
oul.addEventListener('click',function(ev){
var target = ev.target;
if(target.tagName==='LI'){
setIndex([].slice.call(vlist).indexOf(target));
input.focus();
}
})
input.addEventListener('keydown',function(ev){
switch (ev.keyCode) {
case 40:
ev.preventDefault();
setIndex(index+1);
break;
case 38:
ev.preventDefault();
setIndex(index-1);
break;
default:
break;
}
})
input.addEventListener('input',function(ev){
var value = ev.target.value;
list.forEach(function(el,i){
if(el.innerText.includes(value)){
el.removeAttribute('hidden');
}else{
el.setAttribute('hidden','');
}
});
vlist[index] && vlist[index].classList.remove('select');
vlist = oul.querySelectorAll('li:not([hidden])');
if(value){
index = 0;
vlist[0].classList.add('select');
}else{
index = -1;
}
})
const input = document.getElementById('input')
const list = document.getElementById('list')
const log = document.getElementById('log');
function selectList(e) {
const selectedLi = list.children
let index = Array.prototype.findIndex.call(selectedLi, elm => elm.classList.contains('selected'))
let selectIndex = index
if (e.keyCode === 40) {
if (index === -1) {
selectIndex = 0
} else {
selectIndex = ++selectIndex % list.childElementCount
}
} else if (e.keyCode === 38) {
if (index === -1) {
selectIndex = list.childElementCount - 1
} else {
selectIndex = selectIndex === 0 ? list.childElementCount - 1 : selectIndex - 1
}
} else {
return
}
index !== -1 && list.children[index].classList.remove('selected')
list.children[selectIndex].classList.add('selected')
input.value = list.children[selectIndex].textContent
}
list.querySelectorAll(':root li').forEach(elm => {
elm.addEventListener('click', e => {
input.value = elm.textContent
removeSelected()
e.currentTarget.classList.add('selected')
})
})
input.addEventListener('keydown', selectList)
function removeSelected() {
const selected = document.querySelector('.selected')
if (selected) {
selected.classList.remove('selected')
}
}
let eleList = document.getElementById("list");
let eleInput = document.getElementById("input");
let dataList = new Proxy({},{
get(target, name) {
switch (name) {
case "next": return target.act && target.act.nextElementSibling || eleList.firstElementChild;
case "prev": return target.act && target.act.previousElementSibling || eleList.lastElementChild;
default : return target[name];
}},
set(obj, prop, value) {
switch (prop) {
case "act" :
if (!value) {return}
obj.act && obj.act.classList.remove("selected");
value && value.classList.add("selected");
eleInput.value = value.textContent;
eleInput.select();//自动选中
default :
obj[prop] = value;
}}
});
eleList.addEventListener("mousedown", e => e.preventDefault());//防止outline闪烁
eleList.addEventListener("click", e => {dataList.act = e.target});
document.addEventListener("keydown", e => {
e.keyCode === 38||e.keyCode === 40?e.preventDefault():void 0;//防止光标闪烁
dataList.act =
e.keyCode === 38? dataList.prev
: e.keyCode === 40? dataList.next
: null;
});
代码示例:https://codepen.io/iceytea/pen/oNNVxeK
注:仅在 Chrome 78.0.3904.97(正式版本)下测试通过,代码中未作出对其他浏览器兼容性的处理
var SELECTED_MARK = "selected";
var KEYCODE_UP = 38,
KEYCODE_DOWN = 40;
var input = document.getElementById("input"),
ul = document.getElementById("list"),
li_group = ul.children,
first_li = ul.firstElementChild,
last_li = ul.lastElementChild;
var last_selected_li; // 上次选中的 li
/* 处理选中事件 selected_li 当前选中的 li*/
function handleSelect(selected_li) {
if (last_selected_li) {
last_selected_li.classList.remove(SELECTED_MARK);
}
selected_li.classList.add(SELECTED_MARK);
input.value = selected_li.textContent;
}
// 设置上次选中的 li
function setLastSelectedLi() {
// 注:同一时刻只有一个被选中的 li
last_selected_li = ul.getElementsByClassName(SELECTED_MARK).item(0);
}
// 点击事件
ul.addEventListener("click", function(e) {
var selected_li = e.target;
setLastSelectedLi();
if (selected_li.parentElement === ul && selected_li !== last_selected_li) {
handleSelect(selected_li);
}
});
// 键盘按下事件
document.addEventListener("keydown", function(e) {
var keyCode = e.keyCode;
setLastSelectedLi();
if (keyCode === KEYCODE_DOWN) {
if (!last_selected_li || !last_selected_li.nextElementSibling) {
handleSelect(first_li);
} else {
handleSelect(last_selected_li.nextElementSibling);
}
}
if (keyCode === KEYCODE_UP) {
if (!last_selected_li || !last_selected_li.previousElementSibling) {
handleSelect(last_li);
} else {
handleSelect(last_selected_li.previousElementSibling);
}
}
});
var SELECT = 'selected';
var input = document.getElementById('input');
var list = document.getElementById('list');
var liArr = list.querySelectorAll('li');
var liLength = liArr.length;
var selectIndex = -1;
var selectLi;
list.addEventListener('click', function(event) {
var target = event.target;
if (target.tagName === 'LI') {
if (selectLi) {
selectLi.classList.remove(SELECT);
selectLi.removeAttribute('aria-selected');
}
selectLi = target;
selectLi.classList.add(SELECT);
selectLi.setAttribute('aria-selected', 'true');
selectIndex = Array.from(liArr).indexOf(selectLi);
input.value = selectLi.textContent;
}
});
list.addEventListener('focus', function() {
if (!selectLi) {
var event = new Event('keydown');
event.key = 'Home';
document.dispatchEvent(event);
}
});
// 2
document.addEventListener('keydown', function(event) {
switch (event.key) {
case 'ArrowUp':
selectIndex = selectIndex === -1 ? 0 : selectIndex;
_selectByIndex(-1);
break;
case 'ArrowDown':
_selectByIndex(1);
break;
case 'Home':
selectIndex = 0;
_selectByIndex(0);
break;
case 'End':
selectIndex = liArr.length - 1;
_selectByIndex(0);
break;
default:
break;
}
});
function _selectByIndex(step) {
selectIndex = (selectIndex + liLength + step) % liLength;
if (selectLi) {
selectLi.classList.remove(SELECT);
selectLi.removeAttribute('aria-selected');
}
selectLi = liArr[selectIndex];
selectLi.classList.add(SELECT);
selectLi.setAttribute('aria-selected', 'true');
input.value = selectLi.textContent;
list.focus();
}
li.selected {
color: red;
}
<input id="input">
<ul id="list">
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
</ul>
let list = document.getElementById('list')
let items = list.querySelectorAll('li')
let inputItem = document.getElementById('input')
let cur = -1 // 当前选中li元素索引
let total = items.length // li元素总数
// 选中指定索引的li元素
function selectItem (idx) {
if (cur !== -1) {
items[cur].classList.remove('selected')
}
items[idx].classList.add('selected')
inputItem.value = items[idx].innerText
cur = idx
}
for (let i = 0; i < total; i++) {
items[i].addEventListener('click', () => {
selectItem(i)
})
}
window.addEventListener('keydown', e => {
if (e.key === 'ArrowDown') {
selectItem(cur !== -1 ? (cur + 1) % total : 0)
} else if (e.key === 'ArrowUp') {
selectItem(cur !== -1 ? (cur - 1 + total) % total : total - 1)
}
})
llet lis = document.querySelectorAll('#list li')
let input = document.getElementById('input')
lis.forEach(li => {
li.addEventListener('click', event => {
console.log(event)
let text = event.target.innerText
input.value = text
lis.forEach(li => {
li.classList.remove('selected')
})
event.target.classList.add('selected')
})
})
function selectPrev() {
let selectedLi = document.querySelector('#list .selected')
if (selectedLi) {
selectedLi.classList.remove('selected')
if (selectedLi.previousElementSibling) {
selectedLi.previousElementSibling.classList.add('selected')
input.value = selectedLi.previousElementSibling.innerText
} else {
lis[lis.length - 1].classList.add('selected')
input.value = lis[lis.length - 1].innerText
}
}
}
function selectNext() {
let selectedLi = document.querySelector('#list .selected')
if (selectedLi) {
selectedLi.classList.remove('selected')
if (selectedLi.nextElementSibling) {
selectedLi.nextElementSibling.classList.add('selected')
input.value = selectedLi.nextElementSibling.innerText
} else {
lis[0].classList.add('selected')
input.value = lis[0].innerText
}
} else {
lis[0].classList.add('selected')
input.value = lis[0].innerText
}
}
document.addEventListener('keydown', event => {
let { keyCode } = event
switch (keyCode) {
case 38:
selectPrev()
break;
case 40:
selectNext()
default:
break;
}
})
题目1
var input = document.getElementById('input');
var listWrap = document.getElementById('list');
var listItems = listWrap.getElementsByTagName('li');
var curIndex = -1;
function clickHandle (e) {
console.log(listItems.length);
var target = e.target;
if (target.tagName === 'LI') {
if(listItems[curIndex] === target) return input.focus();
if (curIndex > -1) {
listItems[curIndex].classList.remove('selected');
}
for (var i = 0, len = listItems.length; i < len; i ++) {
if(target === listItems[i]){
curIndex = i;
break;
}
}
target.classList.add('selected');
input.value = target.textContent;
input.focus();
}
}
listWrap.addEventListener('click', clickHandle, false);
题目2
var changeCur = {
'38': function () {
curIndex = (--curIndex > -1) ? curIndex : (listItems.length - 1);
},
'40': function () {
curIndex = (curIndex + 1) % listItems.length;
}
}
function keyDownHandle(e) {
var keyCode = e.keyCode;
if (keyCode === 38 || keyCode === 40) {
e.preventDefault();
if (curIndex > - 1) {
listItems[curIndex].classList.remove('selected');
}
changeCur[keyCode]();
listItems[curIndex].classList.add('selected');
input.value = listItems[curIndex].textContent;
input.focus();
}
}
document.addEventListener('keydown', keyDownHandle, false);
let list = document.getElementById('list')
let aLi = Array.from(list.children)
// 存储当前DOM索引
let current_highlight = null
list.addEventListener('click', (e) => {
if (e.target.nodeName === 'LI') {
handleInputAndLi(e.target)
}
})
document.addEventListener('keydown', (e) => {
let keyCode = e.keyCode
if (keyCode !== 38 && keyCode !== 40) return
let index
let maxIndex = aLi.length - 1
if (current_highlight) {
let _currenIndex = current_highlight - 1
index = keyCode === 38 ? (_currenIndex === 0 ? maxIndex : _currenIndex - 1) : (_currenIndex === maxIndex ? 0 : _currenIndex + 1)
} else {
index = keyCode === 38 ? 0 : maxIndex
}
handleInputAndLi(aLi[index])
})
function handleInputAndLi (el) {
let val = el.innerHTML
input.value = val
aLi.forEach((item, index) => {
if (item.classList.contains('selected')) {
item.classList.remove('selected')
}
if (item === el) {
current_highlight = index + 1
}
})
el.classList.add('selected')
}
let ul = document.querySelector("#list");
let input = document.querySelector("#input");
let list = document.querySelectorAll("li");
ul.addEventListener("click", function(e) {
for (var i = 0; i < list.length; i++) {
if (list[i].classList.contains("selected")) {
list[i].classList.remove("selected");
}
}
let currentItem = e.target;
input.value = currentItem.innerText;
currentItem.classList.add("selected");
});
window.addEventListener("keyup", function(e) {
var selected = ul.querySelector(".selected");
let index;
switch (e.keyCode) {
case 38:
e.preventDefault();
if (!selected) {
index = list.length - 1;
input.value = list[index].innerText;
list[index].classList.add("selected");
} else {
index = Array.from(list).indexOf(selected);
if (index == 0) {
index = list.length;
}
selected.classList.remove("selected");
list[index - 1].classList.add("selected");
input.value = list[index - 1].innerText;
}
break;
case 40:
e.preventDefault();
if (!selected) {
index = 0;
input.value = list[index].innerText;
list[index].classList.add("selected");
} else {
index = Array.from(list).indexOf(selected);
if (index == list.length - 1) {
index = -1;
}
selected.classList.remove("selected");
list[index + 1].classList.add("selected");
input.value = list[index + 1].innerText;
}
break;
}
});
demo JS
var tag = -1
var list = document.querySelectorAll('#list li')
var length = list.length - 1
var inputEle = document.querySelector('#input')
/**
* 样式改变
* @param {Array} [arr = []] 列表数组
* @param {String} [style] 要移除的样式
*/
function styleAlert(arr = [], style) {
arr.forEach((item, index) => { item.classList.remove(style) }) // 移除全部selectde样式
arr.forEach((item, index) => {
if (index === tag) {
item.classList.add(style)
inputEle.value = item.innerHTML
}
})
}
list.forEach((item, index) => {
item.addEventListener('click', function () {
tag = index
styleAlert(list, 'selectde')
})
})
window.onkeyup = function (event) {
if (event.keyCode === 38 && event.code === "ArrowUp") {
tag > 0 ? --tag : tag = length
styleAlert(list, 'selectde')
}
if (event.keyCode === 40 && event.code === "ArrowDown") {
tag < 2 ? ++tag : tag = 0
styleAlert(list, 'selectde')
}
}
HTML
<input type="text" id="input">
<ul id="list">
<li class="pervent-more-click">列表1</li>
<li class="pervent-more-click">列表2</li>
<li class="pervent-more-click">列表3</li>
</ul>
CSS
input {
border: 1px solid #ccc;
border-radius: 3px;
padding: 5px 10px;
}
.pervent-more-click {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
outline: 0;
}
ul {
padding: 0px;
/* display: inline-block; */
list-style-type: none;
}
li {
width: 200px;
cursor: pointer;
}
li.selectde {
color: red;
}
var oLi = document.querySelectorAll('li')
var input = document.querySelector('input')
oLi.forEach(item => {
item.addEventListener('click',function(){
let self = this;
self.className = self.className.indexOf('selected') === -1 ? self.className += 'selected' : self.className;
input.value = self.innerText;
let aLi = self.parentNode.children
for (let i = 0, len = aLi.length; i < len; i++) {
if (self !== aLi[i]) {
aLi[i].className = aLi[i].className.replace(/selected/g, '')
}
}
},false)
})
document.addEventListener('keydown', function(event){
if (event.keyCode === 38) {
move('up')
}
if (event.keyCode === 40) {
move('down')
}
},false)
function move (type) {
let now, next;
let current = document.querySelector('.selected')
let currentUl = [...document.querySelectorAll('li')]
if (current === null) {
if (type === 'up') {
next = oLi.length -1
} else {
next = 0
}
} else {
now = currentUl.indexOf(current)
if (type === 'up') {
next = (now - 1) >= 0 ? now -1 : oLi.length -1;
}
if (type === 'down') {
next = now + 1 >= oLi.length ? 0 : now + 1;
}
oLi[now].className = oLi[now].className.replace(/selected/g, '')
}
oLi[next].className = 'selected'
input.value = oLi[next].innerText
}
const viewList = {
init() {
this.input = document.getElementById('input');
this.list = document.getElementById('list');
this.listItems = this.list.querySelectorAll('li');
this.selectedIdx = -1;
this.clickHandle();
this.keyingHandle();
},
clickHandle() {
this.listItems.forEach((li, index) => {
li.addEventListener('click', () => this.doSelect(index));
});
},
keyingHandle() {
document.addEventListener('keydown', ({ keyCode }) => {
const maxIndex = this.listItems.length - 1;
let index = this.selectedIdx;
if (keyCode === 38) { // ↑
index--
} else if (keyCode === 40) { // ↓
index++
}
index = index < 0 ? maxIndex : index;
index = index > maxIndex ? 0 : index;
this.doSelect(index);
});
},
doSelect(index) {
const curLi = this.listItems[index];
const selectedIdx = this.selectedIdx < 0 ? 0 : this.selectedIdx;
this.listItems[selectedIdx].classList.remove('selected');
curLi.classList.add('selected');
this.input.value = curLi.innerText;
this.selectedIdx = index;
}
};
viewList.init();
JSBIN:点我
//zxx: 为什么键盘事件在列表DOM上,autocomplete冲突可以阻止默认行为,或者设置属性值为off
@zhangxinxu 我可能理解错题意了,因为第一题是点击一个列表然后在输入框中显示文案,第二题我理解为直接在这个列表选中状态下进行上下键操作😂
<style>
li.selected {
background-color: red;
}
</style>
<input id="input">
<ul tabindex="0" id="list">
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
<li>
<div>列表41</div>
<div>
<span>列表42</span>
</div>
</li>
</ul>
<script>
var domInput = document.getElementById("input");
var domList = document.getElementById("list");
var fnSelectThisItem = function (item) {
// 移除 domList 所有 selected
var domSelected = domList.querySelectorAll('.selected');
var selectedLen = domSelected.length;
for (var i = 0; i < selectedLen; i++) {
domSelected[i].classList.remove('selected');
}
// 高亮
item.classList.add('selected');
// 赋值
domInput.value = item.innerText;
};
domList.addEventListener('click', function (e) {
var domTarget = e.target;
// 找到对应子元素
while (domTarget !== domList && domTarget.tagName.toLowerCase() !== 'li') {
domTarget = domTarget.parentNode;
}
if (domTarget !== domList && !domTarget.classList.contains('selected')) {
fnSelectThisItem(domTarget);
}
});
// 输入框按下让列表获取焦点
// 但是这个功能感觉不应该有和 autoComplete 有点冲突
// 有点拿捏不准
// domInput.addEventListener('keydown', function (e) {
// (e.keyCode === 40) && domList.focus();
// });
domList.addEventListener('keydown', function (e) {
var isUp = e.keyCode === 38;
var isDown = e.keyCode === 40;
if (!isUp && !isDown) {
return;
}
var domSelected = domList.querySelector('.selected');
var kids = domList.children;
var kidLen = kids.length;
// 一个选中的都没有
if (!domSelected) {
var goIndex = isUp ? kidLen - 1 : 0;
fnSelectThisItem(kids[goIndex]);
return;
}
for (var i = 0; i < kidLen; i++) {
var kid = kids[i];
// 遍历找到当前选中的元素
if (kid === domSelected) {
var goIndex = 0;
if (isUp) {
goIndex = (i - 1) < 0 ? kidLen - 1 : i - 1;
} else if (isDown) {
goIndex = (i + 1) < kidLen ? i + 1 : 0;
}
fnSelectThisItem(kids[goIndex]);
break;
}
}
});
</script>
var list = document.getElementById('list')
var input = document.getElementById('input')
var li = document.querySelectorAll('#list>li')
li = [...li]
list.addEventListener('click', (e) => {
var self = e.target
if (self.tagName === 'LI') {
var selected = li.find(item => item.classList.contains('selected'))
if (selected) {
selected.classList.remove('selected')
}
self.classList.add('selected')
input.value = self.innerText
}
})
window.addEventListener('keydown', (e) => {
var code = e.keyCode
if (code === 38 || code === 40) {
var i = li.findIndex(item => item.classList.contains('selected'))
var len = li.length
var nextIndex
if (i >= 0) {
li[i].classList.remove('selected')
nextIndex = code === 40 ? (i + 1) % len : (i - 1 + len) % len
} else {
nextIndex = code === 40 ? 0 : len - 1
}
var next = li[nextIndex]
next.classList.add('selected')
input.value = next.innerText
}
})
var input = document.querySelector("#input");
var li = document.querySelectorAll("li");
var index = -1;
[].slice.call(li).forEach(function (el,i) {
el.addEventListener("click",function () {
var selected = document.querySelector(".selected");
selected && selected.classList.remove("selected");
this.classList.add("selected");
input.value = this.textContent;
index = i;
});
});
document.addEventListener("keyup",function (e) {
if(e.keyCode === 40){
movePos("down");
}else if(e.keyCode === 38){
movePos("up");
}
});
function movePos(type){
index !== -1 && li[index].classList.remove("selected");
if(type === "down"){
index++;
if(index > li.length - 1){
index = 0;
}
}else{
index--;
if(index < 0){
index = li.length - 1;
}
}
li[index].classList.add("selected");
input.value = li[index].textContent;
}
let inputDom = document.getElementById('input'),
list = document.getElementById('list'),
lis = list.children,
listLength = lis.length,
dom = null
list.addEventListener('click', e => {
if (dom instanceof HTMLElement) {
dom.classList.remove('selected')
}
dom = e.target
e.target.classList.add('selected')
inputDom.value = e.target.innerText
})
document.onkeydown = e => {
if (e.keyCode === 38 || e.keyCode === 40) {
let clickIndex = 0
if (dom instanceof HTMLElement) {
clickIndex = [].indexOf.call(lis, dom)
if (e.keyCode === 38) {
clickIndex--
} else {
clickIndex++
}
} else {
if (e.keyCode === 38) {
clickIndex = listLength - 1
}
}
clickIndex = clickIndex < 0 ? listLength - 1 : clickIndex === listLength ? 0 : clickIndex
lis[clickIndex].click()
}
}
var selectItem = function(item) {
item.classList.add('selected');
document.querySelector('#input').value = item.innerText;
};
//第一题
document.querySelector('#list').onclick = function (e) {
selectItem(e.target);
Array.from(e.target.parentNode.children).forEach(child => {
if (child !== e.target) {
child.classList.remove('selected');
}
});
};
//第二题
var listTrigger = (function() {
var list = document.querySelector('#list').children;
var getIndex = function() {
return Array.from(list).findIndex(v => v.classList.contains('selected'));
};
return {
prev: function() {
var index = getIndex();
if (index !== -1) {
list[index].classList.remove('selected');
index--;
if (index < 0) {
index += list.length;
}
} else {
index = 0;
}
selectItem(list[index]);
},
next: function() {
var index = getIndex();
if (index !== -1) {
list[index].classList.remove('selected');
}
index = (index + 1) % list.length;
selectItem(list[index]);
}
}
})();
document.onkeydown = function (e) {
if (e.code === 'ArrowUp') {
listTrigger.prev();
}
if (e.code === 'ArrowDown') {
listTrigger.next();
}
}
var input = document.querySelector('#input')
var ul = document.querySelector('#list')
var list = ul.querySelectorAll('li')
// 1
list.forEach(li => {
li.addEventListener('click', () => {
input.value = li.innerText
var selected = ul.querySelector('.selected')
selected && selected.classList.remove('selected')
li.classList.add('selected')
})
})
// 2
document.addEventListener('keydown', e => {
if (e.keyCode !== 38 && e.keyCode !== 40) {
return
}
var selected = ul.querySelector('.selected')
if (e.keyCode === 38) {
if (!selected || selected === ul.firstElementChild) {
selected && selected.classList.remove('selected')
ul.lastElementChild.classList.add('selected')
input.value = ul.lastElementChild.innerText
} else {
selected && selected.classList.remove('selected')
selected.previousElementSibling.classList.add('selected')
input.value = selected.previousElementSibling.innerText
}
}
if (e.keyCode === 40) {
if (!selected || selected === ul.lastElementChild) {
selected && selected.classList.remove('selected')
ul.firstElementChild.classList.add('selected')
input.value = ul.firstElementChild.innerText
} else {
selected && selected.classList.remove('selected')
selected.nextElementSibling.classList.add('selected')
input.value = selected.nextElementSibling.innerText
}
}
})
demo js部分
let ipt = document.getElementById('input'),
listBox = document.getElementById('list'),
list = document.querySelectorAll('#list li');
let aClick = []; //记录上个点击的是谁
//第一题 点击切换 selected
list.forEach(function(item){
item.onclick = function(){
//前面有操作 对上一个操作处理
if(aClick.length > 0) aClick[0].classList.remove('selected');
// 现在要处理的操作
this.classList.add("selected");
ipt.value = this.innerText;
aClick[0] = this;
};
})
//第二题
let items = list[list.length-1];
let first = list[0];
function addCur(el,flag){
let els = flag === 'first' ? list[0]: flag === 'last' ? items :el ;
els.classList.add('selected');
aClick[0] = el;
ipt.value = el.innerText;
}
document.onkeydown = function(e){
//向上
if(e.keyCode == 38){
//零界点处理
if(aClick.length == 0) return addCur(items,'last');
let prev = aClick[0].previousElementSibling;
aClick[0].classList.remove('selected');
addCur(!prev ? items:prev);
}
//向下
if(e.keyCode==40){
//零界点处理
if(aClick.length == 0) return addCur(first,'first');
let next = aClick[0].nextElementSibling;
aClick[0].classList.remove('selected');
addCur(!next ? first:next);
}
};
window.onload = function() {
// 第一题
let selectedIndex = -1;
const lis = document.querySelectorAll('li');
const input = document.querySelector('#input');
[...lis].forEach((li,index) => {
li.addEventListener('click',(e) => {
selectedIndex = index;
[...lis].forEach((li) =>{ li.classList.remove('selected')});
e.target.classList.add('selected');
const text = e.target.innerText;
input.value = text;
}, false)
});
// 第二题
document.onkeyup = function(event) {
if (event.keyCode === 40) {
selectedIndex ++;
}
if (event.keyCode === 38) {
selectedIndex --;
}
if (selectedIndex === 3) selectedIndex = 0;
if (selectedIndex === -1) selectedIndex = 2;
[...lis].forEach((li) =>{ li.classList.remove('selected')})
const e = lis[selectedIndex];
e.classList.add('selected');
const text = e.innerText;
input.value = text;
}
}
let inputObject = document.querySelector("#input");
let listObject = document.querySelectorAll("#list li");
var seletedItem = -1;
- 第一题
listObject.forEach((item, index) => {
item.addEventListener("click", () => {
if (seletedItem != index) {
if (listObject[seletedItem]) {
listObject[seletedItem].classList.remove("selected");
}
inputObject.value = item.innerHTML;
item.classList.add("selected");
seletedItem = index;
}
});
});
- 第二题
document.addEventListener("keyup", ({ keyCode }) => {
if (keyCode == 38) {
//UP
action(false);
} else if (keyCode == 40) {
//Down
action(true);
}
});
function action(key) {
if (seletedItem >= 0) {
// seletedItem已赋值情况
if (listObject[seletedItem]) {
listObject[seletedItem].classList.remove("selected");
}
if (key) {
seletedItem += 1;
} else {
if (seletedItem == 0) {
seletedItem = listObject.length - 1;
} else {
seletedItem -= 1;
}
}
seletedItem = seletedItem % listObject.length;
var resultObject = listObject[seletedItem];
inputObject.value = resultObject.innerHTML;
resultObject.classList.add("selected");
} else {
//seletedItem未赋值情况
if (key) {
seletedItem = 0;
var resultObject = listObject[seletedItem];
inputObject.value = resultObject.innerHTML;
resultObject.classList.add("selected");
} else {
seletedItem = listObject.length - 1;
var resultObject = listObject[seletedItem];
inputObject.value = resultObject.innerHTML;
resultObject.classList.add("selected");
}
}
}
https://codepen.io/emmayxy/pen/poomZjp
//zxx: 点击事件丢了,上面链接地址也不对
let list = document.getElementsByTagName('li');
let index = 0, hasSelected = false;
let input = document.querySelector('#input');
function keyUp(e) {
if (e.keyCode === 38) {
index --
} else if (e.keyCode === 40 && hasSelected) {
index ++
} else if (e.keyCode === 40 && !hasSelected){
hasSelected = true
index = 0
} else {
index = null
}
if (index < 0) {
index = 2
} else if (index > 2) {
index = 0
}
if (typeof index !== "object") {
input.value = list[index].innerHTML
Array.prototype.forEach.call(list, item => {
item.classList.remove('selected')
})
list[index].classList.add('selected')
}
}
document.addEventListener('keyup', keyUp)
// 第一题
document.querySelector('#list').addEventListener('click', function(e) {
if (e.target.tagName === 'LI') {
[].slice.apply(document.querySelectorAll('#list li')).forEach(function(item) {
item.classList.remove('selected');
})
document.querySelector('#input').value = e.target.innerText;
e.target.classList.add('selected');
}
});
// 第二题
document.addEventListener('keydown', function(e) {
var li = [].slice.apply(document.querySelectorAll('#list li'));
var selectedIndex = 0;
li.forEach(function(item, index) {
if ([].slice.apply(item.classList).indexOf('selected') !== -1) {
item.classList.remove('selected');
selectedIndex = index + 1;
}
})
if (e && e.keyCode === 38) {
const index = (selectedIndex - 1) % (li.length + 1);
let realIndex = index;
if (index === -1 || index === 0) {
realIndex = li.length;
}
document.querySelector('#list li:nth-child('+ realIndex + ')').click();
}
if (e && e.keyCode === 40) {
console.log(selectedIndex);
const index = (selectedIndex + 1) % (li.length + 1);
const realIndex = index === 0 ? 1 : index;
document.querySelector('#list li:nth-child('+ realIndex + ')').click();
}
});
//演示地址 http://49.233.165.74:801/
function Select(obj) { this.el = obj.el; this.class = obj.activeClass; //高亮的类名 this.isHas = false; //是否已经高亮 this.init(); }
Select.prototype = { //初始化 init: function () { this.addEvent(); }, //选择元素 $: function (el) { return document.querySelector(el); }, //初始化状态 pointState: function () { let childrens = this.$(this.el).children; for (let i = 0; i < childrens.length; i++) { childrens[i].classList.remove(this.class); }//初始化 return childrens; }, //元素添加高亮 isActive: function () { let childrens = this.$(this.el).children; let tabIndex = -1; for (let i = 0; i < childrens.length; i++) { if (childrens[i].classList.contains(this.class)) { tabIndex = i; break; } } return tabIndex; }, //高亮切换 changeEl: function (tempIndex, keyCode) { let codeArr = [13, 38, 40]; if (!codeArr.includes(keyCode)) { return } let childrens = this.pointState(); switch (keyCode) { case 13: if (this.isHas) { childrens[tempIndex].classList.add(this.class);//当前元素添加类名 } break; case 38: tempIndex--; if (tempIndex < 0) { tempIndex = childrens.length - 1; } childrens[tempIndex].classList.add(this.class);//当前元素添加类名 this.isHas = true; break; case 40: tempIndex++; if (tempIndex > childrens.length - 1) { tempIndex = 0; } this.isHas = true; childrens[tempIndex].classList.add(this.class);//当前元素添加类名 break; } console.log(childrens[tempIndex].innerHTML); ////输出当前选择的元素 }, //添加事件 addEvent: function () { let that = this; //添加点击事件 let childrens = this.$(this.el).children; for (let i = 0; i < childrens.length; i++) { childrens[i].addEventListener('click', function () { let tempChildren = that.pointState(); tempChildren[i].classList.add(that.class); console.log(tempChildren[i].innerHTML); ////输出当前选择的元素 }); }//初始化 //键盘事件 that.$('body').addEventListener('keyup', function (e) { let keyCode = e.keyCode; that.changeEl(that.isActive(), keyCode); // }) };