- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
目前我正在尝试在 React 中实现以下视差效果,其中我的图像垂直处于固定位置,但随着文本从左到右移动。
我使用 useEffect 来实现这一点,我获取总高度像素并相应地移动我的组件。这样做的问题是它在我的屏幕上看起来很完美,但是一旦我将其调整到更大或更小的屏幕,布局就会变得很乱。反正有没有同样的效果,但响应友好。随意编辑 CodeSandBox
CodeSandBox(全屏查看以获得更好的引用):https://codesandbox.io/s/stoic-rumple-s8cr6?file=/src/App.js
代码:
export default function App() {
const [index, setIndex] = useState(false);
const [display, setDisplay] = useState(false);
const [number, setNumber] = useState(false);
const [screen, setScreen] = useState(false);
useEffect(function onFirstMount() {
const changeBackground = () => {
let value = window.scrollY;
console.log(value);
let img = document.getElementById("moveLeft");
let text = document.getElementById("moveUp");
let text2 = document.getElementById("text2");
let text3 = document.getElementById("text3");
let text4 = document.getElementById("text4");
let imgWidth = 280;
text.style.marginTop = "-" + value * 0.5 + "px";
text2.style.transform = `translateX(${value * 1.3}px)`;
text3.style.transform = `translateX(-${value * 1.3}px)`;
text4.style.transform = `translateX(${value * 1.3}px)`;
if (value > 600) {
img.style.transform = `translateX(${value * 0.8 - 480 - imgWidth}px)`;
} else {
img.style.transform = `translateX(-${value * 0.5}px)`;
}
if (value > 1400) {
img.style.transform = `translateX(${
-1 * (value * 0.8 - 1120) + 80 + imgWidth
}px)`;
}
if (value > 1700) {
setNumber(true);
} else {
setNumber(false);
}
if (value > 1100) {
setIndex(true);
} else {
setIndex(false);
}
};
window.addEventListener("scroll", changeBackground);
return () => window.removeEventListener("scroll", changeBackground);
}, []);
return (
<>
<div className="App">
<div className="middletext" id="moveUp" style={{ zIndex: "9" }}>
Random Text
</div>
<div class="inflow">
<div class="positioner">
<div class="fixed" style={{ zIndex: "11" }}>
<div id="moveLeft">
<img
alt="passport"
src="https://cdn.britannica.com/87/122087-050-1C269E8D/Cover-passport.jpg"
/>
</div>
</div>
</div>
<div className="halfWindow" style={{ zIndex: "8" }}></div>
<div>
<div class="fixedText" style={{ zIndex: "7" }}>
<div id="text2" className="text2">
Random Text
</div>
</div>
</div>
<div className="secondhalfWindow" style={{ zIndex: index ? "10" : "6" }}></div>
<div>
<div
class="secondfixedText"
style={{
zIndex: index ? "9" : "5",
display: "block"
}}
>
<div id="text3" className="text3">
Random Text 2
</div>
</div>
</div>
<div className="thirdhalfWindow" style={{ zIndex: "4" }}></div>
<div>
<div
class="thirdfixedText"
style={{
zIndex: number ? "10" : "3"
}}
>
<div id="text4" className="text4">
Random Text 3
</div>
</div>
</div>
</div>
</div>
</>
使用 vw 而不是 px 应该可以,但计算非常复杂。
最佳答案
解决方案是重构您的代码。
function App() {
const [screen, setScreen] = React.useState(false);
const ref = React.useRef(null);
// Reduce value if want the image to be closer to the edges
// otherwise to the center
const setImageLimitMovement = 2;
const setTextLimitMovement = 4;
const opacityRange = 400;
// Speed text movement
const speed = 2; // .5
React.useEffect(() => {
window.addEventListener("resize", () => {
if (window.innerWidth !== 0) {
setScreen(window.innerWidth);
}
});
}, []);
React.useEffect(() => {
const app = [...ref.current.children];
const titles = app.filter((el) => el.matches(".titles") && el);
const blocks = app.filter((el) => el.matches(".blocks") && el);
const img = app.find((el) => el.matches("#passport") && el);
// Get the center point of blocks in an array
const centerPoints = blocks.map((blockEl, idx) => {
const blockindex = idx + 1;
const blockHeight = Math.floor(blockEl.getBoundingClientRect().height);
const blockHalf = blockHeight / 2;
return blockHeight * blockindex - blockHalf;
});
const leftMoveLimitImg = -centerPoints[0] / setImageLimitMovement;
const rightMoveLimitImg = centerPoints[0] / setImageLimitMovement;
const textLimit = centerPoints[0] / setTextLimitMovement;
const changeBackground = () => {
const value = window.scrollY;
titles[0].style.transform = `translateY(-${value * speed}px)`;
// IMAGE BOUNCE
// Move to <==
if (centerPoints[0] > value) {
img.style.transform = `translateX(-${
value * (1 / setImageLimitMovement)
}px)`;
titles[1].style.transform = `translateX( ${
0 + value / setTextLimitMovement
}px)`;
titles[1].style.opacity = value / opacityRange;
return;
}
// Move to ==>
if (centerPoints[1] > value) {
const moveTextToRight =
centerPoints[1] / setTextLimitMovement - textLimit;
const hideText = centerPoints[0] / opacityRange;
const checkDirection = Math.sign(
textLimit + (textLimit - value / setTextLimitMovement)
);
const moveImageToRight =
(value - centerPoints[0]) / setImageLimitMovement;
img.style.transform = `translateX(${
leftMoveLimitImg + moveImageToRight
}px)`;
if (checkDirection === -1) {
titles[1].style.opacity = 0;
titles[1].style.transform = `translateX(${0}px)`;
titles[2].style.opacity =
Math.abs(hideText - value / opacityRange) - 1;
titles[2].style.transform = `translateX(${
moveTextToRight - value / setTextLimitMovement
}px)`;
return;
}
if (checkDirection === 1) {
titles[1].style.opacity = 1 + (hideText - value / opacityRange);
titles[1].style.transform = `translateX(${
textLimit + (textLimit - value / setTextLimitMovement)
}px)`;
titles[2].style.opacity = 0;
titles[2].style.transform = `translateX(${0}px)`;
}
return;
}
// Move to <==
if (centerPoints[2] > value) {
const moveTextToLeft =
centerPoints[2] / setTextLimitMovement - textLimit;
const hideText = centerPoints[1] / opacityRange;
const checkDirection = Math.sign(
moveTextToLeft - value / setTextLimitMovement
);
const moveImageToLeft =
(-value + centerPoints[1]) / setImageLimitMovement;
img.style.transform = `translateX(${
rightMoveLimitImg + moveImageToLeft
}px)`;
if (checkDirection === -1) {
titles[2].style.opacity = 0;
titles[2].style.transform = `translateX(${0}px)`;
titles[3].style.opacity =
Math.abs(hideText - value / opacityRange) - 1;
titles[3].style.transform = `translateX(${Math.abs(
moveTextToLeft - value / setTextLimitMovement
)}px)`;
}
if (checkDirection === 1) {
titles[2].style.opacity = 1 + (hideText - value / opacityRange);
titles[2].style.transform = `translateX(-${
moveTextToLeft - value / setTextLimitMovement
}px)`;
titles[3].style.opacity = 0;
titles[3].style.transform = `translateX(${0}px)`;
}
return;
}
// Move to ==>
if (centerPoints[3] > value) {
const moveTextToRight =
centerPoints[3] / setTextLimitMovement - textLimit;
const hideText = centerPoints[2] / opacityRange;
const checkDirection = Math.sign(
moveTextToRight - value / setTextLimitMovement
);
const moveImageToRight =
(value - centerPoints[2]) / setImageLimitMovement;
img.style.transform = `translateX(${
leftMoveLimitImg + moveImageToRight
}px)`;
if (checkDirection === -1) {
titles[3].style.opacity = 0;
titles[3].style.transform = `translateX(${0}px)`;
}
if (checkDirection === 1) {
titles[3].style.opacity = 1 + (hideText - value / opacityRange);
titles[3].style.transform = `translateX(${
moveTextToRight - value / setTextLimitMovement
}px)`;
}
return;
}
window.requestAnimationFrame(changeBackground);
};
window.addEventListener("scroll", changeBackground);
return () => window.removeEventListener("scroll", changeBackground);
}, [screen]);
return (
<div className="App" ref={ref}>
<h1 id="title" className="titles">
Random Title
</h1>
<section id="block1" className="blocks">
<h4>Block 1</h4>
</section>
<figure id="passport">
<img
alt="passport"
src="https://cdn.britannica.com/87/122087-050-1C269E8D/Cover-passport.jpg"
/>
</figure>
<h2 id="text1" className="titles text1">
Random Text 1
</h2>
<section id="block2" className="blocks">
<h4>Block 2</h4>
</section>
<h2 id="text2" className="titles text2">
Random Text 2
</h2>
<section id="block3" className="blocks">
<h4>Block 3</h4>
</section>
<h2 id="text3" className="titles text3">
Random Text 3
</h2>
<section id="block4" className="blocks">
<h4>Block 4</h4>
</section>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render( <
App / > ,
rootElement
);
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.App {
font-family: sans-serif;
width: 100%;
background-color: hsl(220, 65%, 16%);
}
figure {
width: 280px;
height: max-content;
position: fixed;
inset: 0;
margin: auto;
z-index: 100;
}
img {
width: 100%;
}
.blocks {
height: 100vh;
display: flex;
position: relative;
grid-column: 1 / -1;
color: grey;
}
.titles {
width: max-content;
height: max-content;
position: fixed;
inset: 0;
margin: auto;
color: white;
z-index: 99;
}
h1 {
font-size: 3.5em;
}
h2 {
display: flex;
opacity: 0;
font-size: 2.5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>
关于javascript - 使用 useEffect 操作 DOM 事件在不同屏幕上不响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68920034/
我正在尝试检查 Entry 中是否存在重复项,并使用内联消息提醒用户该数字存在。 $(document).ready(function(){ $("#con1").blur(function(
我有一个基于类的 View 。我在引导模式上使用 Ajax。为了避免页面刷新,我想使用此类基于 View 返回 JSON 响应而不是 HTTP 响应,但我只看到了如何为基于函数的 View 返回 JS
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我有一个大型内部企业基于 Web 的应用程序在 IIS6 上运行 ASP.NET 3.5,生成 401 个“未经授权”响应,然后是 200 个“Ok”响应(如 Fiddler 所述)。我知道为什么会发
感谢您研究我的问题。 我有一个node/express服务器,配置了一个server.js文件,它调用urls.js,而urls.js又调用 Controller 来处理http请求,所有这些都配置相
当我使用以下命令时,我得到正确的 JSON 响应: $ curl --data "regno=&dob=&mobile=" https://vitacademics-rel.herokuapp.co
我有一个非常简单的 RESTful 服务,它通过 POST 接收一些表单数据,其目的是在云存储(Amazon S3、Azure Blob 存储等)中简单地保留文本主体(具有唯一 ID)作为一个文件..
UDP 不发送任何 ack,但它会发送任何响应吗? 我已经设置了客户端服务器UDP程序。如果我让客户端向不存在的服务器发送数据,那么客户端会收到任何响应吗? 我的假设是; 客户端 --> 广播服务器地
我有一个电梯项目,其中 有一个扩展 RestHelper 的类,看起来像这样 serve{ "api" / "mystuff" prefix { case a
我们正在寻求覆盖 Kong 错误响应结构并编写自定义消息(即用我们的自定义消息替换“超出 API 速率限制”、“无效的身份验证凭据”等)。 我们要找的错误响应结构(代码是自定义的内部错误代码,与HTT
我正在尝试监听 EKEventStoreChangedNotification 以检查当我的应用程序处于后台时日历是否已更改。 我在 View Controller 的 initWithNibMeth
我了解 javascript,并且正在学习 ASP.NET C# 我想要做什么(完成的是javascript): document.getElementById('divID-1'
是否可以过滤所有 har 对象并仅获取 POST 请求/响应?也许在初始化 BrowserMobProxyServer 期间是这样做的方法?我需要将 har 对象保存到文件中并上传到 har 查看器。
我正在尝试向 Oauth 的 API 发送响应。遗憾的是,Symfony2 文档在解释 $response->headers->set(...); 的所有不同部分方面做得很差。 这是我的 OauthC
我正在尝试测试用例来模拟 api 调用,并使用 python 响应来模拟 api 调用。 下面是我的模拟, with responses.RequestsMock() as rsps: url
在尝试在 Haskell 中进行一些领域驱动设计时,我发现自己遇到了这个问题: data FetchAccessories = FetchAccessories data AccessoriesRes
我正在与 ANT+ USB 棒连接,并用项目 react 器替换我自己天真的“MessageBus”,因为它看起来非常合适。 USB接口(interface)本质上是异步的(单独的输入/输出管道),我
我正在将项目迁移到AFNetworking 2.0。使用AFNetworking 1.0时,我编写了代码来记录控制台中的每个请求/响应。这是代码: -(AFHTTPRequestOperation *
我有以下代码段。 ajaxRequest.onreadystatechange = function(){ if(ajaxRequest.readyState == 4){
我有问题......我在 php 中有一个监听器脚本可以执行以下操作: if ($count != 1) {echo 'no';} else { echo "yes";} 因此它会回显"is"或“
我是一名优秀的程序员,十分优秀!