<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#container {
width: 400px;
height: 600px;
border: 2px solid black;
margin: 0 auto;
overflow: hidden;
position: relative;
}
#container ul {
position: absolute;
left: 0;
top: 0;
width: 400px;
height: auto;
}
#container ul .box {
list-style: none;
width: 200px;
height: 200px;
background-color: pink;
margin: 10px auto;
border: 3px solid transparent;
}
#container ul .focus {
border: 3px solid red;
}
</style>
</head>
<body>
<div id="container">
<ul class="list">
<li class="box ac_in" id="item0"></li>
<li class="box ac_in" id="item1"></li>
<li class="box ac_in" id="item2"></li>
<li class="box ac_in" id="item3"></li>
<li class="box ac_in" id="item4"></li>
</ul>
</div>
<script src="./jquery.js-3.6-ynsw.js"></script>
<script>
var LEFT_KEY = 37;
var TOP_KEY = 38;
var RIGHT_KEY = 39;
var BOTTOM_KEY = 40;
var ENTER_KEY = 13;
var BACK_KEY = 8;
var LEFT_KEY_TV = 30;
var TOP_KEY_TV = 28;
var RIGHT_KEY_TV = 31;
var BOTTOM_KEY_TV = 29;
var ENTER_KEY_TV = 13;
var BACK_KEY_TV = 113;
var pageData = {
activeItem: 'item0',
list_top: 0,
itemArr: []
}
$(document).ready(function () {
getItemArr();
window.onkeydown = keyDown;
})
function getItemArr() {
pageData.itemArr = [];
$.each($('.ac_in'), function (index, item) {
pageData.itemArr.push($(item).attr('id'));
})
$('#' + pageData.activeItem).addClass('focus');
}
function scrollPage(el) {
var cHeight = parseInt($('#container').height());
var listHeight = parseInt($('.list').height()) - cHeight;
var elHeight = parseInt($('#' + el).height());
var elTop = parseInt($('#' + el).offset().top);
var value = elTop - parseInt((cHeight - elHeight) / 2);
if ($('.list').position().top - value >= 0) {
pageData.list_top = 0;
} else if ($('.list').position().top - value <= -listHeight) {
pageData.list_top = -listHeight
} else {
pageData.list_top = $('.list').position().top - value;
}
$('.list').animate({
'top': pageData.list_top,
}, 100)
}
function keyDown(e) {
var e = e || window.e || arguments.callee.caller.arguments[0];
e.preventDefault();
if (e.keyCode == LEFT_KEY || e.keyCode == TOP_KEY || e.keyCode == RIGHT_KEY || e.keyCode == BOTTOM_KEY || e
.keyCode == LEFT_KEY_TV || e.keyCode == TOP_KEY_TV || e.keyCode == RIGHT_KEY_TV || e.keyCode ==
BOTTOM_KEY_TV) {
pageData.activeItem = toClosest(pageData.activeItem, pageData.itemArr, e.keyCode);
}
if (e.keyCode == BACK_KEY || e.keyCode == BACK_KEY_TV) {
location.href = 'javascript:history.go(-1)'
}
}
// 使用规则
// 1.可获取焦点的元素要有ac_in类名且有固定id
function toClosest(el, elementsArr, keyCode) {
var elObjArr = [];
var mainObj = {};
var distanceArr = [];
var elDom = $('#' + el);
mainObj.left = parseInt(elDom.offset().left);
mainObj.right = parseInt(elDom.offset().left + elDom.width());
mainObj.top = parseInt(elDom.offset().top);
mainObj.bottom = parseInt(elDom.offset().top + elDom.height());
$.each(elementsArr, function (index, item) {
var elObj = {};
var elNode = $('#' + item);
elObj.left = parseInt(elNode.offset().left);
elObj.right = parseInt(elNode.offset().left + elNode.width());
elObj.top = parseInt(elNode.offset().top);
elObj.bottom = parseInt(elNode.offset().top + elNode.height());
elObj.index = index;
elObjArr.push(elObj);
})
if (keyCode == LEFT_KEY || keyCode == LEFT_KEY_TV) {
var mainLt = {
left: mainObj.left,
top: mainObj.top
}
var rtArr = []
$.each(elObjArr, function (index, item) {
rtArr.push({
right: item.right,
top: item.top,
index: item.index
})
})
$.each(rtArr, function (index, item) {
if (el != elementsArr[i] && mainLt.left > item.right) {
distanceArr.push([parseInt(Math.pow((mainLt.left - item.right), 2) + Math.pow((mainLt
.top - item.top), 2)), item.index]);
}
})
if (distanceArr.length > 0) {
var minDistance = distanceArr[0][0];
var minIndex = distanceArr[0][1];
for (var i = 1; i < distanceArr.length; i++) {
if (minDistance > distanceArr[i][0]) {
minDistance = distanceArr[i][0];
minIndex = distanceArr[i][1];
}
}
$('#' + elementsArr[minIndex]).addClass('focus').siblings().removeClass('focus');
return elementsArr[minIndex];
} else {
$('#' + el).addClass('focus');
return el;
}
}
if (keyCode == TOP_KEY || keyCode == TOP_KEY_TV) {
var mainLt = {
left: mainObj.left,
top: mainObj.top
}
var lbArr = [];
$.each(elObjArr, function (index, item) {
lbArr.push({
left: item.left,
bottom: item.bottom,
index: item.index
})
})
$.each(lbArr, function (index, item) {
if (el != elementsArr[i] && mainLt.top > item.bottom) {
distanceArr.push([parseInt(Math.pow((mainLt.top - item.bottom), 2) + Math.pow((mainLt
.left -
item.left), 2)), item.index]);
}
})
if (distanceArr.length > 0) {
var minDistance = distanceArr[0][0];
var minIndex = distanceArr[0][1];
for (var i = 1; i < distanceArr.length; i++) {
if (minDistance > distanceArr[i][0]) {
minDistance = distanceArr[i][0];
minIndex = distanceArr[i][1];
}
}
scrollPage(elementsArr[minIndex]);
$('#' + elementsArr[minIndex]).addClass('focus').siblings().removeClass('focus')
return elementsArr[minIndex];
} else {
$('#' + el).addClass('focus');
return el;
}
}
if (keyCode == RIGHT_KEY || keyCode == RIGHT_KEY_TV) {
var mainRt = {
right: mainObj.right,
top: mainObj.top
}
var ltArr = [];
$.each(elObjArr, function (index, item) {
ltArr.push({
left: item.left,
top: item.top,
index: item.index
})
})
$.each(ltArr, function (index, item) {
if (el != elementsArr[i] && mainRt.right < item.left) {
distanceArr.push([parseInt(Math.pow((mainRt.right - item.left), 2) + Math.pow((mainRt
.top -
item.top), 2)), item.index]);
}
})
if (distanceArr.length > 0) {
var minDistance = distanceArr[0][0];
var minIndex = distanceArr[0][1];
for (var i = 1; i < distanceArr.length; i++) {
if (minDistance > distanceArr[i][0]) {
minDistance = distanceArr[i][0];
minIndex = distanceArr[i][1];
}
}
$('#' + elementsArr[minIndex]).addClass('focus').siblings().removeClass('focus');
return elementsArr[minIndex];
} else {
$('#' + el).addClass('focus');
return el;
}
}
if (keyCode == BOTTOM_KEY || keyCode == BOTTOM_KEY_TV) {
var mainLb = {
left: mainObj.left,
bottom: mainObj.bottom
}
var ltArr = [];
$.each(elObjArr, function (index, item) {
ltArr.push({
left: item.left,
top: item.top,
index: item.index
})
})
$.each(ltArr, function (index, item) {
if (el != elementsArr[i] && mainLb.bottom < item.top) {
distanceArr.push([parseInt(Math.pow((mainLb.bottom - item.top), 2) + Math.pow((mainLb
.left -
item.left), 2)), item.index]);
}
})
if (distanceArr.length > 0) {
var minDistance = distanceArr[0][0];
var minIndex = distanceArr[0][1];
for (var i = 1; i < distanceArr.length; i++) {
if (minDistance > distanceArr[i][0]) {
minDistance = distanceArr[i][0];
minIndex = distanceArr[i][1];
}
}
scrollPage(elementsArr[minIndex]);
$('#' + elementsArr[minIndex]).addClass('focus').siblings().removeClass('focus');
return elementsArr[minIndex];
} else {
$('#' + el).addClass('focus');
return el;
}
}
}
</script>
</body>
</html>