[英]How can i manipulate DOM inside the onScroll event in ReactJS?
我正在嘗試創建一個向上箭頭按鈕,如果我在頁面頂部,它將設置為display: "none"
,當我進一步向下滾動時,我想將其設置為顯示:“塊”。 我怎樣才能做到這一點? 我試圖在我的 handleScroll 函數中操作 DOM,但它不起作用。
我的 TopButton.js 組件
import React from "react";
import "../assets/arrow-up.png";
class TopButton extends React.Component {
constructor(props) {
super(props);
this.handleScroll = this.handleScroll.bind(this);
}
componentDidMount = () => {
window.addEventListener("scroll", this.handleScroll, true);
};
handleClick = () => {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
};
handleScroll = () => {
console.log("scroll");
let x = document.getElementsByClassName("topbutton_button");
var x = document.getElementsByClassName("topbutton_button");
// x.style.display = "none";
// console.log(event.target.className);
// if (
// document.body.scrollTop > 40 ||
// document.documentElement.scrollTop > 40
// ) {
// style.display = "block";
// } else {
// display = "none";
// }
};
render() {
return (
<div className="topbutton_container">
<button
style={{ display: "block" }}
onClick={this.handleClick}
onScroll={this.handleScroll}
className="topbutton_button"
>
<img src={require("../assets/arrow-up.png")} />
</button>
</div>
);
}
}
export default TopButton;
它不起作用至少有兩個原因:
查看此問題的答案; 基本上, getElementsByClassName
返回一個HTMLCollection
,而不是單個元素,但是您注釋掉的代碼將其視為單個元素。
如果您的組件曾經被重新渲染,它將以默認狀態呈現,而不是您通過 DOM 更改的更新狀態
但這不是你用 React 做的事情。 相反,你會:
將按鈕狀態(無論是否應為塊狀態)作為組件中的狀態保存;
在渲染topbutton_button
時使用該狀態,相應地設置其樣式或類; 和
在handleScroll
處理程序中更新該狀態
其他一些注意事項:
您還需要在卸載組件時刪除處理程序
您不應該將箭頭函數用於組件生命周期函數
您不需要在箭頭函數(例如handleScroll
)上使用bind
。 要么使它成為箭頭函數,要么在構造函數中使用bind
來綁定它。
沿着這些路線,請參閱***
評論
import React from "react";
import "../assets/arrow-up.png";
// *** Reusable function to decide whether we're "at the top" or not
function bodyIsAtTop() {
return (
document.body.scrollTop <= 40 &&
document.documentElement.scrollTop <= 40
);
}
class TopButton extends React.Component {
constructor(props) {
super(props);
// *** Initial state
this.state = {
atTop: bodyIsAtTop()
};
// *** No need for the following if you use an arrow function
// this.handleScroll = this.handleScroll.bind(this);
}
// *** Don't make this an arrow, make it a method
componentDidMount() {
window.addEventListener("scroll", this.handleScroll, true);
};
// *** Need to unbind when unmounted
componentWillUnmount = () => {
window.removeEventListener("scroll", this.handleScroll, true);
};
handleClick = () => {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
};
handleScroll = () => {
// *** Update state (possibly; if the flag isn't different, this doesn't do anything)
this.setState({atTop: bodyIsAtTop()});
};
render() {
// *** Get the flag from state, use it below in style
const {atTop} = this.state;
return (
<div className="topbutton_container">
<button
style={{ display: atTop ? "none" : "block" }}
onClick={this.handleClick}
onScroll={this.handleScroll}
className="topbutton_button"
>
<img src={require("../assets/arrow-up.png")} />
</button>
</div>
);
}
}
export default TopButton;
我在那里保留了handleScroll
和handleClick
的箭頭功能。 有一種說法是讓它們成為方法並在構造函數中使用bind
,但這主要是一種風格。 (好吧......樣式並且模擬原型方法進行測試更容易,這是使用原型方法和bind
的非樣式原因。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.