【发布时间】:2013-05-31 03:18:56
【问题描述】:
有没有办法通过媒体查询检测垂直滚动距离?
似乎媒体查询是围绕检测媒体而设计的(令人震惊的是:P),因此诸如浏览器高度之类的东西是可测试的,但不具体是页面向下滚动了多远。
如果不可能,但您知道 JS(不是 jQuery)中的一种方式,请随时发布!
【问题讨论】:
标签: css media-queries
有没有办法通过媒体查询检测垂直滚动距离?
似乎媒体查询是围绕检测媒体而设计的(令人震惊的是:P),因此诸如浏览器高度之类的东西是可测试的,但不具体是页面向下滚动了多远。
如果不可能,但您知道 JS(不是 jQuery)中的一种方式,请随时发布!
【问题讨论】:
标签: css media-queries
我不相信 CSS 媒体查询可以做到这一点,但我知道滚动高度可以在 JavaScript 中使用 window.pageYOffset 找到。如果您想在用户每次在页面上向上或向下滚动时通过函数运行此值,您可以执行类似的操作
window.onscroll = function() {
scrollFunctionHere(window.pageYOffset);
};
或者只是:
window.onscroll = scrollFunctionHere;
如果函数本身检查了window.pageYOffset 的值。
有关如何在 JavaScript 中高效使用 window.onscroll 的更多建议,请参阅 mynameistechno's answer。
关于效率的重要说明:如果在回调中执行任何非平凡的操作,则每次发出滚动事件时运行一个函数可能会破坏 CPU 周期。相反,最好只允许回调每秒运行这么多次。这被称为“去抖动”。
下面的简单去抖动滚动事件处理程序代码。注意文本是如何每 250 毫秒在“HELLO”和“WORLD”之间切换的,而不是每帧:
var outputTo = document.querySelector(".output");
var timeout_debounce;
window.addEventListener("scroll", debounce);
function debounce(event) {
if(timeout_debounce) {
return;
}
timeout_debounce = setTimeout(clearDebounce, 250);
// Pass the event to the actual callback.
actualCallback(event);
}
function clearDebounce() {
timeout_debounce = null;
}
function actualCallback(event) {
// Perform your logic here with no CPU hogging.
outputTo.innerText = outputTo.innerText === "HELLO"
? "WORLD"
: "HELLO";
}
p {
padding: 40vh;
margin: 20vh;
background: blue;
color: white;
}
<p class="output">Test!</p>
【讨论】:
window.onscroll 的更多信息。只是为了记录,我选择不在我的答案中添加更多信息,因为我假设想要使用 JavaScript 技术的开发人员会在 window.onscroll 上进行自己的研究。 @mynameistechno
首先,接受的答案不起作用。
正确的名字是
window.onscroll
而不是
window.onScroll
https://developer.mozilla.org/en-US/docs/Web/API/window.onscroll
其次,这是非常低效的,因为该函数的调用方式超出了它的需要,并且可能使页面在滚动时变得迟缓。来自 John Resig:
http://ejohn.org/blog/learning-from-twitter/
最好使用每 150 毫秒左右运行一次的计时器 - 类似于:
var scrolled = false;
window.onscroll = function() {
scrolled = true;
}
setInterval(function(){
if (scrolled) {
scrolled = false;
// scrollFunction()
}
}, 150);
【讨论】:
.onscroll 被设计 被覆盖,在滚动上更改一个简单的 CSS 属性根本不会滞后
onscroll 是否被设计 覆盖,它都是一个事件处理程序,并且滚动已知 会触发很多事件,因此在处理程序中做很多事情是一个坏主意(而不是因为覆盖的优点)。在相关的说明中,例如,iOS 不会触发 scroll 事件,直到用户 完成 滚动。如果我没记错的话,直到最近的版本。
onscroll 来触发许多事件。解决这些“太多事件”的方法是检查自上次执行 onscroll 函数以来经过了多少毫秒,并且仅当该毫秒值大于某个特定间隔值时才再次执行。
在 Jquery 中你有方法 .scrollTop()
http://api.jquery.com/scrolltop/
这个例子用窗口滚动来做一个 div 滚动。
$(window).scroll(function(){
$("div").css("margin-top", $(window).scrollTop())
});
【讨论】:
这是解决方案的一种方法。f https://jsfiddle.net/oravckzx/1/
$(window).scroll(function(){
$('.post-sidebar').each(function(){
var ScrollTopVar = $(window).scrollTop();
var OffsetTopVar = $(this).offset().top;
var OuterHeightVar = $(this).outerHeight();
var PositionVar = OffsetTopVar-(OuterHeightVar*1.1);
if (ScrollTopVar >= PositionVar) {
$('.hide') .css('background','green').css('font-size','12px')
$('.post-sidebar') .css('background','orange').css('font-size','12px')
$('.hide') .css('background','green').css('font-size','12px')
$('.post-sidebar') .css('background','gray').css('font-size','12px')
document.getElementById("demo3").innerHTML = ScrollTopVar;
document.getElementById("demo2").innerHTML = PositionVar;
}else {
$('.hide') .css('background','yellow').css('background','yellow')
$('.hide') .css('background','yellow')
$('.hide') .css('background','yellow')
document.getElementById("demo").innerHTML = ScrollTopVar;
document.getElementById("demo12").innerHTML = ScrollTopVar;
document.getElementById("demo13").innerHTML = ScrollTopVar;
document.getElementById("demo14").innerHTML = ScrollTopVar;
document.getElementById("demo2").innerHTML = PositionVar;
}
});
});
.red {height:100px;
background:red;margin-bottom:20px;}
.hide {height:50px;background:blue;margin-bottom:20px;}
.post-sidebar {
height:50px;
background:yellow;
margin-bottom:20px;
box-sizing: border-box;
display: block;
font: normal 700 34px Lato, sans-serif;
padding-right: 20px;
width: 452px;
}
.p {
font: normal 700 14px Lato, sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="red"><p id="demo"></div>
<div class="red"></div><p id="demo12">ok
<div class="red"><p id="demo13">ok</div>
<div class="post-sidebar"><p id="demo2"></p><p>lizard</p></div>
<div class="hide"><p id="demo2">If reaches to chosen class in html, saves value of ScrollTopVar (as distance from top) to separate variable as eventually PositionVar (which is the distance from top to the chosen class in html, - and that specific distance depends of device which is doing it), and then does certain action if ScrollTopVar value matches or exceeds PositionVar value. Else sets it back if needed, if not including Else it remains as it once met the value. <p id="demo3"></div>
<div class="red"><p id="demo14">ok</div>
<div class="red"><p id="demo"></div>
<div class="red"><p id="demo"></div>
【讨论】: