所以我一直试图围绕这个称为Parallax的整洁效果。基本上背景滚动比前景元素慢。
我发现这个新的“技巧”正在发挥作用。滚动时,更改top
属性以创建视差效果。
问题......
因此,为了提高性能并在元素不在用户视口内时解除CPU的压力,我创建了一个if
语句,用于检查top
位置是否超过300像素。如果是,它会覆盖所有内容并将top
属性设置回0,因此不会无缘无故地增加它。
现在,滚动一下。看看,当红色的div
越过白色的那个时,白色的那个断断续续?查看DOM检查器,我发现if
语句吓坏了,将top
属性设置为0px,即使它不超过300px。 HALP。
虽然我们正在努力,但我希望看到有关视差效果的更多建议。我已经看到了一些关于这种效果的答案,但它们似乎......对我来说过于复杂。我知道有更好的方法可以做到这一点,我知道有。
而且,如果没有jQuery答案,我将不胜感激。感谢。
var txtfirst = document.getElementById("txtfirst");
window.onscroll = function(){
var ypos = window.pageYOffset;
txtfirst.style.top = ypos * 0.4 + "px";
if(txtfirst.style.top > '300px'){
txtfirst.style.top = '0px';
}
}
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.text-first {
display: flex;
text-align: center;
justify-content: center;
align-items: center;
font-size: 32px;
font-family: Arial;
color: gray;
width: 100%;
height: 500px;
position: relative;
}
.foreground-red {
width: 100%;
height: 600px;
background-color: red;
display: flex;
justify-content: center;
align-items: center;
font-family: Arial;
color: gray;
font-size: 32px;
}
.spacer { /*for scrolling purposes*/
width: 100%;
height: 1000px;
}
<div class="text-first" id="txtfirst">THIS IS SOME TEXT</div>
<div class="foreground-red">THIS SHOULD GO ABOVE</div>
<div class="spacer"></div>
答案 0 :(得分:0)
您最有可能的应用程序(我假设您只提供了选定的代码段)至少因为您在比较数字时正在比较 text 你的优化尝试:
txtfirst.style.top > '300px'
上述情况不会像您期望的那样。 Element::style
属性的每个属性(例如您的txtfirst.style
)都是text string,而不是number。像"50px" < "300px"
这样的测试无法比较50是否小于300,它会比较文本值lexicographically。
如果您确实想要比较像素数量,可以使用parseInt
函数将50px
之类的值转换为数字50。您的测试将如下所示:
parseInt(txtfirst.style.top) < 300
现在,由于您对建议感兴趣,因此您解决此问题的方法和建议的解决方案存在许多问题。
内联样式在CSS中具有最高优先级,在用户拥有自己的样式表的情况下可能会出现问题,因为在这些样式中设置的属性将被忽略,而有利于内联设置的属性。
< / LI>读取内联样式的属性,假设它是实际使用的值,这是完全错误的。内联样式对象跟踪分配的值,而非计算或使用的值。另一方面,Window::getComputedStyle(element)
函数检索元素的计算样式。
解决方案?使用getComputedStyle
读取属性并将其直接写入首选(或空的,如果需要)样式表(document.styleSheets
,反映所有link rel=stylesheet
和style
元素):
function rule(selector) {
var sheet = document.styleSheets[0];
return Array.prototype.find.call(sheet.cssRules, rule => rule.selectorText == selector);
}
var txtfirst = document.getElementById("txtfirst");
window.onscroll = function() {
var ypos = window.pageYOffset;
var style = rule(".text-first").style;
style.top = ypos * 0.4 + "px";
if(parseInt(getComputedStyle(txtfirst).top) > 300) {
style.top = "0px";
}
}
上面的rule
函数返回CSS规则(一个包含设置的CSS属性),带有匹配的选择器(例如.text-first
或html, body
)来自第一个找到的样式表(你只有一个) )。规则的style
属性是指包含规则中设置的所有CSS属性的对象。它的行为与内联样式对象相同。请注意,您没有在上面的任何位置使用内联样式,您可以写入样式表对象(由文档的<style>...</style>
片段初始化)并回读计算值。
scroll
事件进行动画首先,您是否知道旧的iOS版本在滚动时未触发scroll
事件?这将阻止您的视差效果停滞不前,因为单 scroll
事件将在用户停止滚动后触发。这与浏览器页面滚动的方式有关 - 使用受约束的移动CPU资源实现平滑的页面滚动动画,运行JavaScript代码由scroll
事件处理程序提供,每秒60次被认为过于慷慨,而苹果公司却采用了有争议的解决方案,因为它们具有良好的用户体验。
无论如何,如果不使用scroll
事件该怎么办?您可以使用旧的setInterval
:
function rule(selector) {
var sheet = document.styleSheets[0];
return Array.prototype.find.call(sheet.cssRules, rule => rule.selectorText == selector);
}
var txtfirst = document.getElementById("txtfirst");
var old_window_pageYOffset = window.pageYOffset;
setTimeout(function() {
var ypos = window.pageYOffset;
if(ypos != old_window_pageYOffset) return;
old_window_pageYOffset = ypos;
var style = rule(".text-first").style;
style.top = ypos * 0.4 + "px";
if(parseInt(getComputedStyle(txtfirst).top) > 300) {
style.top = "0px";
}
}, 1000 / 60);
上面所做的是确保函数在页面的整个生命周期内每秒调用60次,但是如果自上次调用后窗口的滚动位置发生了更改,则检查每次调用,仅在调用旧代码时调用它有,否则什么都不做。这显然不会使用scroll
事件。所有这些都表示,较新的iOS版本已经恢复了行为,并且每次更改滚动位置时都会触发scroll
事件。这意味着您可能只想将其用作基线并依赖于事件而不是setInterval
。后者的一个免费好处是你可以控制视差效应的运行速度。
我还建议使用requestAnimationFrame
,这是更多&#34;智能&#34;而不是setInterval
,因为如果用户代理认为不需要动画,则用户代理不会调用您的代码,例如,如果整个页面选项卡目前不可见或与用户交互。请放心,您的动画将在需要时运行&#34;:
function rule(selector) {
var sheet = document.styleSheets[0];
return Array.prototype.find.call(sheet.cssRules, rule => rule.selectorText == selector);
}
var txtfirst = document.getElementById("txtfirst");
var old_window_pageYOffset = window.pageYOffset;
requestAnimationFrame(function() {
var ypos = window.pageYOffset;
if(ypos != old_window_pageYOffset) return;
old_window_pageYOffset = ypos;
var style = rule(".text-first").style;
style.top = ypos * 0.4 + "px";
if(parseInt(getComputedStyle(txtfirst).top) > 300) {
style.top = "0px";
}
});
上面的代码是对视差效果的好尝试,除了与单独的视差效果几乎没有关系的次要挑剔:
当我们on*name*
时,我不会使用addEventListener
系列函数。前者是每个处理程序的一个属性,并且不保证您的脚本是这些属性的唯一使用者 - 它们可能已经由浏览器扩展设置。我们可以争论网页作者是否拥有他们可以获得的所有属性的独家所有权和访问权限,但至少我已经解释了我的理由。我所知道的使用addEventListener("scroll", function() { ... })
并没有明显的缺点。
您不需要使用 类名称和元素ID来引用它。 document.querySelector(".text-field")
将返回第一个可用元素,其中包含&#34; text-field&#34;在其班级名单中。
我已经为最后一次保存了最好的 - Pure CSS Parallax Websites通过实现(虽然不是没有针对错误的浏览器的一些小黑客)所需的效果而没有任何JavaScript,依赖于CSS {{1}属性和其他一些。它还提到了我上面已经警告的一些事情,我试图规避和解释的事情。
如果你不想阅读(和理解)文档,我建议你使用一个方便的抽象 - 一个插件,一个框架,一个库或者其他东西,这将使你不必弄清楚这一点的复杂性。现代CSS和兼容的浏览器模型非常复杂,足以让这些解决方案得以存在并蓬勃发展。