如果父div
可以垂直滚动并且可能嵌套了元素,那么如何获得当前占据父div顶端的(最里面的)元素?
例如,假设我将父div作为下图中的浅蓝色区域,并且其中有对象,其中有蓝色或红色,其中一些部分位于父div之外(实际应该是隐藏)。我想让对象用红色着色。
我可以通过将子元素的offsetTop
与父元素的coo_matrix
进行比较来实现,并递归进入。
答案 0 :(得分:2)
运行下面的代码段以查看一个解决方案。滚动窗口以相对于窗口移动div,然后单击按钮以查看窗口顶部最里面的div的id。该解决方案假设所有div都是“通常”嵌套的,即没有通过花式css工作重新排列div垂直放置,没有固定位置等。
下面有两个版本:第一个使用jQuery,第二个不使用。
$("button#check").click(function() {
var topElem = $("body")[0]; // start at the outermost, i.e. the body
var checkChildDivs = function() { // define the recursive checking function
var children = $(topElem).children("div").not("div#info"); // get all child divs
if (children.length > 0) { // if there are any child divs
$(children).each(function(index, elem) { // check each of them
var posns = getPosns($(elem)); // get their top and bottom posns
// relative to the top of the screen
if ((posns.top <= 0) && (posns.bottom >= 0)) { // if the div overlaps the screen top
topElem = elem; // make this the new innermost div
checkChildDivs(); // check any deeper child divs
return false; // no need to check any lower sibling divs
}
});
}
};
checkChildDivs(); // initiate the checking recursion
$("div#info").text($(topElem).attr("id") || "none, i.e. body"); // report the innermost top div id
});
function getPosns($elem) {
var top = $elem.offset().top; // get the top of the div relative to the document
var hgt = $elem.outerHeight(); // get the height of the element
var wst = $(window).scrollTop(); // get the height of window hidden above the top of the screen
return { // return the top and bottom distances of the element
top: (top - wst), // relative to the top of the screen
bottom: (top - wst + hgt)
};
}
body {
background-color: blue;
}
div {
border: solid black 2px;
padding: 1em;
margin: 1em;
background-color: magenta;
}
div > div {
background-color: red;
}
div > div > div {
background-color: orange;
}
div >div > div > div {
background-color: yellow;
}
button#check {
position: fixed;
height: 2em;
}
div#info {
position: fixed;
background-color: white;
border-width: 1px;
opacity: 0.7;
top: 3em;
left: -0.2em;
height: 1.5em;
width: 15em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="check">Determine Id of Innermost Div at Screen Top</button>
<div id="info"></div>
<div id="a">a
<div id="aa">aa
<div id="aaa">aaa</div>
<div id="aab">aab
<div id="aaba">aaba</div>
<div id="aabb">aabb</div>
<div id="aabc">aabc</div>
</div>
<div id="aac">aac</div>
</div>
<div id="ab">ab
<div id="aba">aba</div>
<div id="abb">abb</div>
<div id="abc">abc</div>
</div>
<div id="ac">ac
<div id="aca">aca</div>
<div id="acb">acb</div>
<div id="acc">acc</div>
</div>
</div>
<div id="b">b
<div id="ba">ba
<div id="baa">baa</div>
<div id="bab">bab</div>
<div id="bac">bac</div>
</div>
<div id="bb">bb
<div id="bba">bba</div>
<div id="bbb">bbb</div>
<div id="bbc">bbc</div>
</div>
<div id="bc">bc
<div id="bca">bca</div>
<div id="bcb">bcb</div>
<div id="bcc">bcc</div>
</div>
</div>
<div id="c">c
<div id="ca">ca
<div id="caa">caa</div>
<div id="cab">cab</div>
<div id="cac">cac</div>
</div>
<div id="cb">cb
<div id="cba">cba</div>
<div id="cbb">cbb</div>
<div id="cbc">cbc</div>
</div>
<div id="cc">cc
<div id="cca">cca</div>
<div id="ccb">ccb</div>
<div id="ccc">ccc</div>
</div>
</div>
这是同一件事的非jQuery版本:
var doc = document;
doc.getElementById("check").onclick = function() {
var topElem = doc.getElementsByTagName("body")[0]; // start at the outermost, i.e. the body
var checkChildDivs = function() { // define the recursive checking function
var children = topElem.childNodes; // get all child nodes
if (children.length > 0) { // if there are any child nodes
[].forEach.call(children, function(elem, index, arr) { // check each of them
if (elem.toString() === "[object HTMLDivElement]" && elem.id !== "info") {
// only use divs that do not have id "info"
var posns = getPosns(elem); // get their top and bottom posns
// relative to the top of the screen
if ((posns.top <= 0) && (posns.bottom >= 0)) { // if the div overlaps the screen top
topElem = elem; // make this the new innermost div
checkChildDivs(); // check any deeper child divs
return false; // no need to check any lower sibling divs
}
}
});
}
};
checkChildDivs(); // initiate the checking recursion
doc.getElementById("info").innerHTML = (topElem.id || "none, i.e. body");
// report the innermost top div id
};
function getPosns(elem) {
var top = elem.getBoundingClientRect().top + window.pageYOffset - doc.documentElement.clientTop;
// get the top of the div relative to the document
var hgt = elem.offsetHeight; // get the height of the element
var wst = window.scrollY; // get the height of window hidden above the top of the screen
return { // return the top and bottom distances of the element
top: (top - wst), // relative to the top of the screen
bottom: (top - wst + hgt)
};
}
body {
background-color: blue;
}
div {
border: solid black 2px;
padding: 1em;
margin: 1em;
background-color: magenta;
}
div > div {
background-color: red;
}
div > div > div {
background-color: orange;
}
div >div > div > div {
background-color: yellow;
}
button#check {
position: fixed;
height: 2em;
}
div#info {
position: fixed;
background-color: white;
border-width: 1px;
opacity: 0.7;
top: 3em;
left: -0.2em;
height: 1.5em;
width: 15em;
}
<button id="check">Determine Id of Innermost Div at Screen Top</button>
<div id="info"></div>
<div id="a">a
<div id="aa">aa
<div id="aaa">aaa</div>
<div id="aab">aab
<div id="aaba">aaba</div>
<div id="aabb">aabb</div>
<div id="aabc">aabc</div>
</div>
<div id="aac">aac</div>
</div>
<div id="ab">ab
<div id="aba">aba</div>
<div id="abb">abb</div>
<div id="abc">abc</div>
</div>
<div id="ac">ac
<div id="aca">aca</div>
<div id="acb">acb</div>
<div id="acc">acc</div>
</div>
</div>
<div id="b">b
<div id="ba">ba
<div id="baa">baa</div>
<div id="bab">bab</div>
<div id="bac">bac</div>
</div>
<div id="bb">bb
<div id="bba">bba</div>
<div id="bbb">bbb</div>
<div id="bbc">bbc</div>
</div>
<div id="bc">bc
<div id="bca">bca</div>
<div id="bcb">bcb</div>
<div id="bcc">bcc</div>
</div>
</div>
<div id="c">c
<div id="ca">ca
<div id="caa">caa</div>
<div id="cab">cab</div>
<div id="cac">cac</div>
</div>
<div id="cb">cb
<div id="cba">cba</div>
<div id="cbb">cbb</div>
<div id="cbc">cbc</div>
</div>
<div id="cc">cc
<div id="cca">cca</div>
<div id="ccb">ccb</div>
<div id="ccc">ccc</div>
</div>
</div>
答案 1 :(得分:1)
您可以使用此库:https://github.com/customd/jquery-visible。 查看我的代码片段以获取演示
$(function() {
$(window).on('scroll', function() {
$visible = null;
$('section > div').each(function() {
if (!$visible && $(this).visible(true)) {
$visible = $(this);
$(this).addClass('active');
} else {
$(this).removeClass('active');
}
});
$('#answer').html('' + $visible.text());
});
});
#main1,
#main2,
#main3,
#main4 {
display: block;
padding: 10px;
}
body {
background: blue;
}
section > div {
display: block;
width: 100%;
background: lightblue;
margin-bottom: 10px;
}
section > div.active {
background: red;
}
#answer {
display: block;
position: fixed;
bottom: 0;
height: 30px;
width: 300px;
background: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://opensource.teamdf.com/visible/jquery.visible.js"></script>
<section id="main1">
<div style="height:100px;">child 1</div>
</section>
<section id="main2">
<div style="height:100px;">child 2</div>
</section>
<section id="main3">
<div style="height:100px;">child 3</div>
</section>
<section id="main4">
<div style="height:300px;">child 4</div>
<div style="height:400px;">child 5</div>
</section>
<div id="answer"></div>