有没有办法让视觉元素位于某个元素的下方或上方?
元素是列表的一部分,我希望能够使用箭头键在列表中导航。左/右移动到上一个/下一个兄弟,但我不知道如何处理上/下。
$(document).on('keydown', function(e) {
console.log(e.which);
var current = $('li.selected');
switch (e.which) {
case 37:
current.prev().addClass('selected').siblings().removeClass('selected');
break;
case 39:
current.next().addClass('selected').siblings().removeClass('selected');
break;
default:
return true;
}
e.preventDefault();
});
$('li').on('click', function(e) {
$(this).addClass('selected').siblings().removeClass('selected');
});
ul {
display: flex;
flex-wrap: wrap;
list-style: none;
}
li {
width: 50px;
height: 50px;
margin: 5px;
border: 1px solid red;
}
li.selected {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="selected"></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
答案 0 :(得分:3)
我写了一个函数来搜索兄弟节点并检查它们在元素宽度范围内的左边位置。
function findDown(node) {
return findInSiblings(node, node.nextAll());
}
function findUp(node) {
return findInSiblings(node, node.prevAll());
}
function findInSiblings(node, siblings) {
var x = node.offset().left,
w = node.width() / 2;
for (var i = 0; i < siblings.length; i++) {
var sibling = $(siblings[i]);
if (sibling[0].nodeType === 1) {
var offset = sibling.offset().left;
if (offset - w < x && offset + w > x) {
return sibling;
}
}
}
return null;
}
$(document).on('keydown', function(e) {
var current = $('li.selected');
var node = getNode(current, e.which);
if (node == null) {
return true;
}
select(node);
e.preventDefault();
});
$('li').on('click', function(e) {
select($(this));
});
function select(node) {
node.addClass('selected').siblings().removeClass('selected');
}
function getNode(selected, direction) {
switch (direction) {
case 37: // Left
return selected.prev();
case 38: // Up
return findUp(selected);
case 39: // Right
return selected.next();
case 40: // Down
return findDown(selected);
}
return null;
}
function findDown(node) {
return findInSiblings(node, node.nextAll());
}
function findUp(node) {
return findInSiblings(node, node.prevAll());
}
function findInSiblings(node, siblings) {
var x = node.offset().left,
w = node.width() / 2;
for (var i = 0; i < siblings.length; i++) {
var sibling = $(siblings[i]);
if (sibling[0].nodeType === 1) {
var offset = sibling.offset().left;
if (offset - w < x && offset + w > x) {
return sibling;
}
}
}
return null;
}
ul {
display: flex;
flex-wrap: wrap;
list-style: none;
}
li {
width: 50px;
height: 50px;
margin: 5px;
border: 1px solid red;
}
li.selected {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="selected"></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
答案 1 :(得分:1)
答案 2 :(得分:1)
获取当前元素的offsetLeft
属性。
var currentLeft = current.prop("offsetLeft");
查看每个下一个或上一个元素,直到找到具有相同offsetLeft
属性的元素。
case 38:
var el = current.prev();
while (el.length && el.prop("offsetLeft") != currentLeft) {
el = el.prev();
}
if (el.length) {
current.removeClass("selected");
el.addClass("selected");
}
break;
$(document).on('keydown', function(e) {
console.log(e.which);
var current = $('li.selected');
var currentLeft = current.prop("offsetLeft");
switch (e.which) {
case 37:
current.prev().addClass('selected').siblings().removeClass('selected');
break;
case 39:
current.next().addClass('selected').siblings().removeClass('selected');
break;
case 38:
var el = current.prev();
while (el.length && el.prop("offsetLeft") != currentLeft) {
el = el.prev();
}
if (el.length) {
current.removeClass("selected");
el.addClass("selected");
}
break;
case 40:
var el = current.next();
while (el.length && el.prop("offsetLeft") != currentLeft) {
el = el.next();
}
if (el.length) {
current.removeClass("selected");
el.addClass("selected");
}
break;
default:
return true;
}
e.preventDefault();
});
$('li').on('click', function(e) {
$(this).addClass('selected').siblings().removeClass('selected');
});
&#13;
ul {
display: flex;
flex-wrap: wrap;
list-style: none;
}
li {
width: 50px;
height: 50px;
margin: 5px;
border: 1px solid red;
}
li.selected {
background: red;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="selected"></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
&#13;