使用 Pure Vanilla JavaScript 在视口上显示焦点 DIV 并在滚动时隐藏非焦点 DIV
Posted
技术标签:
【中文标题】使用 Pure Vanilla JavaScript 在视口上显示焦点 DIV 并在滚动时隐藏非焦点 DIV【英文标题】:Show Focused DIV on Viewport & Hide Unfocused DIVs on Scrolling using Pure Vanilla JavaScript 【发布时间】:2021-07-23 22:26:11 【问题描述】:我正在使用 Pure Vanilla javascript 创建 html 表单,其效果与在 SurveyMonkey 表单上的效果相同,例如 https://www.surveymonkey.com/r/Online-Product-Feedback-Survey-Template-new 上的示例
我想要实现的是让我的表单问题的不透明度变浅,并使一个屏幕上的问题不透明度:0;以便在向上和向下滚动时从用户那里获得焦点并使该表单的所有其他问题变暗与上例相同,从而完全可见。
为此,我在从不同资源获得不同提示后尝试了我的代码,并在此分享。查看我的工作的实时工作 JSFIDDLE 并在那里进行编辑。
HTML
<form>
<div class="questionDIV overlay">
<h3>Question # 1) Our purpose / vision / mission / values reflect delivering value for all stakeholders...</h3>
<p><label class="container">Yes<input type="radio" name="1" value="Yes"><span class="radiomark"></span></label></p>
<p><label class="container">No<input type="radio" name="1" value="No"><span class="radiomark"></span></label></p>
<p><label class="container">Partially<input type="radio" name="1" value="Partially"><span class="radiomark"></span></label></p>
</div>
<div class="questionDIV overlay">
<h3>Question # 1) Our purpose / vision / mission / values reflect delivering value for all stakeholders...</h3>
<p><label class="container">Yes<input type="radio" name="1" value="Yes"><span class="radiomark"></span></label></p>
<p><label class="container">No<input type="radio" name="1" value="No"><span class="radiomark"></span></label></p>
<p><label class="container">Partially<input type="radio" name="1" value="Partially"><span class="radiomark"></span></label></p>
</div>
<div class="questionDIV overlay">
<h3>Question # 1) Our purpose / vision / mission / values reflect delivering value for all stakeholders...</h3>
<p><label class="container">Yes<input type="radio" name="1" value="Yes"><span class="radiomark"></span></label></p>
<p><label class="container">No<input type="radio" name="1" value="No"><span class="radiomark"></span></label></p>
<p><label class="container">Partially<input type="radio" name="1" value="Partially"><span class="radiomark"></span></label></p>
</div>
<div class="questionDIV overlay">
<h3>Question # 1) Our purpose / vision / mission / values reflect delivering value for all stakeholders...</h3>
<p><label class="container">Yes<input type="checkbox" name="1" value="Yes"><span class="checkmark"></span></label></p>
<p><label class="container">No<input type="checkbox" name="1" value="No"><span class="checkmark"></span></label></p>
<p><label class="container">Partially<input type="checkbox" name="1" value="Partially"><span class="checkmark"></span></label></p>
</div>
<div class="questionDIV overlay">
<h3>Question # 1) Our purpose / vision / mission / values reflect delivering value for all stakeholders...</h3>
<p><label class="container">Yes<input type="checkbox" name="1" value="Yes"><span class="checkmark"></span></label></p>
<p><label class="container">No<input type="checkbox" name="1" value="No"><span class="checkmark"></span></label></p>
<p><label class="container">Partially<input type="checkbox" name="1" value="Partially"><span class="checkmark"></span></label></p>
</div>
<div class="questionDIV overlay">
<h3>Question # 1) Our purpose / vision / mission / values reflect delivering value for all stakeholders...</h3>
<p><label class="container">Yes<input type="checkbox" name="1" value="Yes"><span class="checkmark"></span></label></p>
<p><label class="container">No<input type="checkbox" name="1" value="No"><span class="checkmark"></span></label></p>
<p><label class="container">Partially<input type="checkbox" name="1" value="Partially"><span class="checkmark"></span></label></p>
</div>
</form>
CSS
.overlay opacity:0.2
JavaScript
//Example from https://www.javascripttutorial.net/sample/dom/event/visible-viewport/index.html
function isInViewport(el)
const rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
const box = document.querySelector('.questionDIV');
document.addEventListener('scroll', function ()
if (isInViewport(box) == true)
document.querySelector('.questionDIV').classList.remove("overlay");
else
document.querySelector('.questionDIV').classList.add("overlay");
,
passive: true
);
【问题讨论】:
【参考方案1】:主要问题在于您的“.questionDIV”选择器方法。
document.querySelector 只返回它找到的第一个出现。第一个块之后的所有块都不会被“isInViewport”评估。
您需要获取所有问题容器的列表并在滚动事件期间对其进行迭代。像这样:
const box = document.querySelectorAll('.questionDIV');
document.addEventListener('scroll', function ()
for(let i = 0; i < box.length;i++)
console.log(box[i]);
console.log(isInViewport(box[i]));
if (isInViewport(box[i]) == true)
box[i].classList.remove("overlay");
else
box[i].classList.add("overlay");
,
passive: true
);
之后,您只需微调代码以确保一次只有一个问题处于活动状态。编辑JSFIDDLEhere
【讨论】:
完美。非常感谢您指出我的错误并修复它。 - 你能像问题中提到的那样让它和我想要的一样吗意味着即使有 2-3 个 div 进入视口,也只有一个(中间的一个)应该是完全可见的。我怎样才能实现它? 您需要在“isInViewport”函数中定义偏移量,并将评估限制在屏幕的一小部分(我用静态偏移量示例编辑了我的小提琴,因此您可以检查出来)。 谢谢。现在我将尝试让它只显示一个中间的 DIV 其余部分全部隐藏。 只需更改下面的函数即可按照所问的问题实现 --- function isInViewport(el) const rect = el.getBoundingClientRect();返回 ( rect.top >= ((window.innerHeight/2)-(el.clientHeight)) && rect.left >= 0 && rect.bottom以上是关于使用 Pure Vanilla JavaScript 在视口上显示焦点 DIV 并在滚动时隐藏非焦点 DIV的主要内容,如果未能解决你的问题,请参考以下文章
javascript 使用vanilla JS观察对象属性更改
javascript 使用vanilla JavaScript爬上DOM树
css Vanilla CSS来自http://www.cssreset.com/scripts/vanilla-css-un-reset/,在CSS重置后使用,为所有人定义“默认”样式。