如果完全在视图中(大于视口),则 intersectionObserver 获得比率 1
intersectionObserver get ratio 1 if fully in view (larger than viewport)
我有一个页面分为多个部分。现在滚动我试图显示进度(有多少部分在视图中),使用导航项底部边框的宽度。下面是我如何实现它的示例。
现在如您所见,如果一个部分高于视口,则 intersectionRatio 永远不会达到 1(这反过来也不会绘制全宽边框)。我可以使用任何选项或替代方法来实际实现全宽吗?
(function() {
var sections = [],
links = {},
thresholdSet = [[]],
observerOptions = {
root: null,
rootMargin: "0px",
threshold: _buildThresholdList()
};
function _init() {
if (!'IntersectionObserver' in window) {
return;
}
sections = document.getElementsByClassName('section');
for(var i = 0; i < sections.length; i++) {
var observer = new IntersectionObserver(_intersectionCallback, observerOptions),
section = sections[i],
link = document.getElementById('js-' + section.id);
links[section.id] = {
node: link,
initialWidth: link.offsetWidth
};
observer.observe(section);
}
}
function _buildThresholdList() {
for(var i = 0; i <= 1.0; i += 0.01) {
thresholdSet[0].push(i.toFixed(2));
}
console.table(thresholdSet[0]);
return thresholdSet[0];
}
function _intersectionCallback(entries) {
entries.forEach(function(entry) {
var section = entry.target;
var link = links[section.id];
var width = link.initialWidth * (entry.intersectionRatio || 0) + "px";
link.node.style.width = width;
console.log(section.id, entry.intersectionRatio);
});
}
_init();
}());
body {
display: flex;
}
.aside {
flex: 0 0 150px;
}
.nav {
position: sticky;
top: 0;
}
.nav li {
margin-bottom: 20px;
}
.nav li span {
display: inline-block;
padding-bottom: 10px;
border-bottom: 2px solid red;
}
.sections {
flex: 1;
}
#page1 {
height: 350px;
background-color: #cc8136;
}
#page2 {
height: 1500px;
background-color: #6538c4;
}
#page3 {
height: 1300px;
background-color: #9e7f9b;
}
#page4 {
height: 300px;
background-color: #568574;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="aside">
<ul class="nav">
<li><span id="js-page1">page1</span></li>
<li><span id="js-page2">page2</span></li>
<li><span id="js-page3">page3</span></li>
<li><span id="js-page4">page4</span></li>
</ul>
</div>
<div class="sections">
<div class="section" id="page1"></div>
<div class="section" id="page2"></div>
<div class="section" id="page3"></div>
<div class="section" id="page4"></div>
</div>
</body>
</html>
K 所以我没有使用 entry.intersectionRatio
,而是使用 entry.intersectionRect.height / viewportHeight
。
我有一个页面分为多个部分。现在滚动我试图显示进度(有多少部分在视图中),使用导航项底部边框的宽度。下面是我如何实现它的示例。
现在如您所见,如果一个部分高于视口,则 intersectionRatio 永远不会达到 1(这反过来也不会绘制全宽边框)。我可以使用任何选项或替代方法来实际实现全宽吗?
(function() {
var sections = [],
links = {},
thresholdSet = [[]],
observerOptions = {
root: null,
rootMargin: "0px",
threshold: _buildThresholdList()
};
function _init() {
if (!'IntersectionObserver' in window) {
return;
}
sections = document.getElementsByClassName('section');
for(var i = 0; i < sections.length; i++) {
var observer = new IntersectionObserver(_intersectionCallback, observerOptions),
section = sections[i],
link = document.getElementById('js-' + section.id);
links[section.id] = {
node: link,
initialWidth: link.offsetWidth
};
observer.observe(section);
}
}
function _buildThresholdList() {
for(var i = 0; i <= 1.0; i += 0.01) {
thresholdSet[0].push(i.toFixed(2));
}
console.table(thresholdSet[0]);
return thresholdSet[0];
}
function _intersectionCallback(entries) {
entries.forEach(function(entry) {
var section = entry.target;
var link = links[section.id];
var width = link.initialWidth * (entry.intersectionRatio || 0) + "px";
link.node.style.width = width;
console.log(section.id, entry.intersectionRatio);
});
}
_init();
}());
body {
display: flex;
}
.aside {
flex: 0 0 150px;
}
.nav {
position: sticky;
top: 0;
}
.nav li {
margin-bottom: 20px;
}
.nav li span {
display: inline-block;
padding-bottom: 10px;
border-bottom: 2px solid red;
}
.sections {
flex: 1;
}
#page1 {
height: 350px;
background-color: #cc8136;
}
#page2 {
height: 1500px;
background-color: #6538c4;
}
#page3 {
height: 1300px;
background-color: #9e7f9b;
}
#page4 {
height: 300px;
background-color: #568574;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="aside">
<ul class="nav">
<li><span id="js-page1">page1</span></li>
<li><span id="js-page2">page2</span></li>
<li><span id="js-page3">page3</span></li>
<li><span id="js-page4">page4</span></li>
</ul>
</div>
<div class="sections">
<div class="section" id="page1"></div>
<div class="section" id="page2"></div>
<div class="section" id="page3"></div>
<div class="section" id="page4"></div>
</div>
</body>
</html>
K 所以我没有使用 entry.intersectionRatio
,而是使用 entry.intersectionRect.height / viewportHeight
。