Footer的基本原理
<html style="height:100%">
<head>
</head>
<body style="min-height: 100%;margin-top: 0;margin-bottom: 0; display: flex;flex-direction: column">
<div id="app" style="flex-grow: 1">
<p>Content</p>
</div>
<div style="display: flex;flex-direction: column;align-items: center;justify-content:flex-end;flex-grow: 1">
<footer id="footer">
<p style="">Designed by Fulton Shaw</p>
</footer>
</div>
</body>
</html>
实现效果:
几个关键点:
<html style="height:100%">
让HTML布满整个可视界面body
采用flex布局body
的两个子元素的flex-grow: 1
,让他们平分空间footer
的justify-content: flex-end
会尽量让元素下沉
基于骨架和replace(有问题)
当使用React时,我们面临的问题是如何使得布局参数生效。React渲染之后,元素并不是替代目标节点,而是作为目标节点的子元素,所以在React组件上的布局不生效。
一种可行的办法时,index.html
作为骨架,然后index.js
中手动渲染并替换元素:
<html style="height:100%">
<head>
</head>
<body style="min-height: 100%;margin-top: 0;margin-bottom: 0; display: flex;flex-direction: column">
<!-- to be replaced by the script-->
<div id="app"></div>
<div id="footer"></div>
</body>
</html>
Footer.js
function Footer(){
return (
<div style={{display: "flex",flexDirection: "column",alignItems: "center",justifyContent:"flex-end",flexGrow: 1}}>
<footer id="footer">
<p>Designed by Fulton Shaw</p>
</footer>
</div>
)
}
export default Footer
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import Footer from './Footer'
let app = document.createElement("div")
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>
,
app
)
// <div id="app" style="flex-grow: 1">
app.children[0].style["flex-grow"] = 1
let footer = document.createElement("div")
ReactDOM.render(
<React.StrictMode>
<Footer/>
</React.StrictMode>
,
footer
)
// replace root with the rendered
document.body.replaceChild(app.children[0],document.getElementById('app'))
document.body.replaceChild(footer.children[0],document.getElementById('footer'))
上面的代码中, 我们通过ReactDOM.render
将组件渲染到一个临时元素,然后获取临时元素的子组件来替换index.html
中的骨架节点。
虽然这种方式在视觉上能够工作,但其问题在于,替换之后的元素,onClick
等回调函数不生效。我猜这与创建元素时的上下文有关。
基于骨架和设置
因为替换会存在问题,所以我们不会更改React渲染的元素。我们基于上面的布局原理,还是构造骨架包含两个基本插入节点:
<html style="height:100%">
<head>
</head>
<body style="min-height: 100%;margin-top: 0;margin-bottom: 0; display: flex;flex-direction: column">
<div id="app" style="flex-grow: 1"></div>
<div id="footer" style="display: flex;flex-direction: column;align-items: center;justify-content:flex-end;flex-grow: 1"></div>
</body>
</html>
然后Footer.js
现在只需要包含一个footer
元素即可:
function Footer(){
return (
<footer id="footer">
<p>Designed by Fulton Shaw</p>
</footer>
)
}
export default Footer
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import Footer from './Footer'
ReactDOM.render(
(<React.StrictMode>
<App />
</React.StrictMode>
)
,
document.getElementById("app")
)
ReactDOM.render(
(<React.StrictMode>
<Footer/>
</React.StrictMode>
),
document.getElementById("footer")
)