Menu素子
15249 ワード
import React, { useEffect, useRef } from 'react';
import { useMediaQuery } from 'react-responsive';
import './Menu.css';
import { Link } from 'react-router-dom';
import styled from "styled-components";
const StyledLink = styled(Link)`
text-decoration: none;
color: white;
`
function Menu() {
let isMb = useMediaQuery({
query: "(max-width:414px)"
})
let ManipulatedObj = {
listObj: useRef(),
button: useRef(),
}
let sw = 0;
const fadein = fadeIn.bind(ManipulatedObj);
const fadeout = fadeOut.bind(ManipulatedObj);
function fadeIn() {
this.listObj.current.style.visibility = 'visible';
for (let i = 0; i < this.listObj.current.children.length; i++) {
this.listObj.current.children[i].style.opacity = 1;
}
}
function fadeOut() {
this.listObj.current.style.visibility = 'hidden';
for (let i = 0; i < this.listObj.current.children.length; i++) {
this.listObj.current.children[i].style.opacity = 0;
}
}
function ButtonPointerEnter() {
fadein();
}
function ButtonMouseLeave(event) {
if (event.relatedTarget === window || event.relatedTarget === null) {
fadeout();
}
else if (!event.relatedTarget.closest('.list')) {
fadeout();
}
}
function ListMouseLeave(event) {
if (event.relatedTarget === window || event.relatedTarget === null) {
fadeout();
}
else if (event.relatedTarget === this.button.current) {
}
else if (!event.relatedTarget.closest('.list')) {
fadeout();
}
}
function ButtonOnClick() {
if (!sw) {
this.listObj.current.style.visibility = 'visible';
fadein();
sw = !sw;
}
else {
this.listObj.current.style.visibility = 'hidden';
fadeout();
sw = !sw;
}
}
useEffect(() => {
if (!isMb) {
ManipulatedObj.button.current.onpointerenter = ButtonPointerEnter.bind(ManipulatedObj);
ManipulatedObj.button.current.onmouseleave = ButtonMouseLeave.bind(ManipulatedObj);
ManipulatedObj.listObj.current.onmouseleave = ListMouseLeave.bind(ManipulatedObj);
ManipulatedObj.button.current.onclick = undefined;
}
else {
ManipulatedObj.button.current.onpointerenter = undefined;
ManipulatedObj.button.current.onmouseleave = undefined;
ManipulatedObj.listObj.current.onmouseleave = undefined;
ManipulatedObj.button.current.onclick = ButtonOnClick.bind(ManipulatedObj);
}
}, [isMb]);
return (
<div className="container">
<button className="button" ref={ManipulatedObj.button}>MENU</button>
<ul className="list" ref={ManipulatedObj.listObj}>
<li><StyledLink to='/'>HOME</StyledLink></li>
<li><StyledLink to='/music'>MUSIC</StyledLink></li>
<li><StyledLink to='/contact'>CONTACT</StyledLink></li>
</ul>
</div>
);
}
export default Menu;
styled componentsを使用してstyledメソッドを通過飾ります重要な点は、useMediaQuery hookを使用して画面サイズを追跡し、useEffect hookコンポーネントのライフサイクルの更新を実現することです.PCで設定されているイベントと移動中に設定されているイベントは、更新のたびに異なるため、初期化と再設定が必要な部分があります.
css
.container {
display: flex;
flex-direction: column;
align-items: flex-end;
margin: 0;
padding: 0;
}
.list {
padding: 0;
margin: 0;
font-size: 3rem;
list-style: none;
display: table-cell;
visibility: hidden;
cursor: pointer;
z-index: 1;
-webkit-tap-highlight-color: black;
}
.button {
font-size: 4rem;
padding: 0;
margin: 0;
background-color: black;
color: white;
border: none;
cursor: pointer;
z-index: 1;
}
.list li:hover {
background-color: gray;
}
.list li:nth-child(1){
opacity: 0;
transition: opacity 0.2s;
}
.list li:nth-child(2){
opacity: 0;
transition: opacity 0.6s;
}
.list li:nth-child(3){
opacity: 0;
transition: opacity 1s;
}
.button {
-webkit-tap-highlight-color: black;
}
@media screen and (max-width: 414px) {
.button {
font-size: 3rem;
padding: 0;
margin: 0;
background-color: black;
color: white;
border: none;
cursor: pointer;
}
.list {
font-size: 1.8rem;
-webkit-tap-highlight-color: transparent;
}
.list li:hover {
background-color: black;
}
.button {
-webkit-tap-highlight-color: transparent;
}
}
ボタンの全部分を囲む親コンテナのdisplayはflex、directionはcolumn、align-items部分はdirectionの反対部分なので、flex-endを使用して上部右端に位置決めできます.リストでは、マウスのサスペンションに適用する部分は文字に密着し、スペースを残さないようにするため、display:table-cell構造を採用します.
:nth-child(n)のように、コレクタに対応するグループからn順に抽出して適用できる医師類である.
Reference
この問題について(Menu素子), 我々は、より多くの情報をここで見つけました https://velog.io/@hqillz/Menu-컴포넌트テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol