admin管理员组文章数量:1025465
Is there a way to get the element that is visually underneath or above a certain element?
The elements are part of a list, and I want to be able to navigate through the list using the arrow keys. Left/right moves to the previous/next sibling, but I have no idea what to do with up/down.
$(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=".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>
Is there a way to get the element that is visually underneath or above a certain element?
The elements are part of a list, and I want to be able to navigate through the list using the arrow keys. Left/right moves to the previous/next sibling, but I have no idea what to do with up/down.
$(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./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>
Share
Improve this question
edited Jan 16, 2015 at 1:38
Mr. Polywhirl
48.9k12 gold badges94 silver badges145 bronze badges
asked Jan 16, 2015 at 1:36
nice assnice ass
16.7k8 gold badges53 silver badges92 bronze badges
4
- you can read elements' positions and find the one to navigate to. – akonsu Commented Jan 16, 2015 at 1:41
- 1 I would remend using a <table> instead. Then you can navigate the rows and columns. – Ian Hazzard Commented Jan 16, 2015 at 1:41
- No, he means that if the div flows, can you detect a neighboring div. (Think line wrapping) – Mr. Polywhirl Commented Jan 16, 2015 at 1:41
- I want to avoid tables, because the number of columns is variable (as much as they can fit). But heights should be equal like in tables, that's why I chose flex... – nice ass Commented Jan 16, 2015 at 1:45
3 Answers
Reset to default 5I wrote a function to search sibling nodes and check their left position within the bounds of the element width.
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;
}
Demo
$(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./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>
A couple ideas:
1) You could always just calculate the number that are shown on each line since you can get the width of the page.
2) You could use document.elementFromPoint and test a point that is below your current element.
Get the offsetLeft
property of the current element.
var currentLeft = current.prop("offsetLeft");
Look at each next or previous element until you find the one with the same offsetLeft
property.
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');
});
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./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>
Is there a way to get the element that is visually underneath or above a certain element?
The elements are part of a list, and I want to be able to navigate through the list using the arrow keys. Left/right moves to the previous/next sibling, but I have no idea what to do with up/down.
$(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=".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>
Is there a way to get the element that is visually underneath or above a certain element?
The elements are part of a list, and I want to be able to navigate through the list using the arrow keys. Left/right moves to the previous/next sibling, but I have no idea what to do with up/down.
$(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./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>
Share
Improve this question
edited Jan 16, 2015 at 1:38
Mr. Polywhirl
48.9k12 gold badges94 silver badges145 bronze badges
asked Jan 16, 2015 at 1:36
nice assnice ass
16.7k8 gold badges53 silver badges92 bronze badges
4
- you can read elements' positions and find the one to navigate to. – akonsu Commented Jan 16, 2015 at 1:41
- 1 I would remend using a <table> instead. Then you can navigate the rows and columns. – Ian Hazzard Commented Jan 16, 2015 at 1:41
- No, he means that if the div flows, can you detect a neighboring div. (Think line wrapping) – Mr. Polywhirl Commented Jan 16, 2015 at 1:41
- I want to avoid tables, because the number of columns is variable (as much as they can fit). But heights should be equal like in tables, that's why I chose flex... – nice ass Commented Jan 16, 2015 at 1:45
3 Answers
Reset to default 5I wrote a function to search sibling nodes and check their left position within the bounds of the element width.
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;
}
Demo
$(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./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>
A couple ideas:
1) You could always just calculate the number that are shown on each line since you can get the width of the page.
2) You could use document.elementFromPoint and test a point that is below your current element.
Get the offsetLeft
property of the current element.
var currentLeft = current.prop("offsetLeft");
Look at each next or previous element until you find the one with the same offsetLeft
property.
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');
});
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./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>
本文标签: javascriptGet the element from above or belowStack Overflow
版权声明:本文标题:javascript - Get the element from above or below - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745623445a2159715.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论