Tastetrykk i React



creative-internet-computer-display

Tastetrykk i React

av Ole Petter den 29. juli 2021

Sist oppdatert: 29 juli, 2021 kl 11:41

Dette innlegget er en fortsettelse av det forrige innlegget, https://progitek.no/2021/07/28/lag-en-lightbox-med-react/

Contents [hide]

Tastetrykk hook: useKeypress

Denne koden er hentet fra: https://usehooks.com/useKeyPress/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { useEffect, useState } from "react";
 
export function useKeyPress(targetKey) {
    // State for keeping track of whether key is pressed
    const [keyPressed, setKeyPressed] = useState(false);
    // If pressed key is our target key then set to true
    function downHandler({ key }) {
      if (key === targetKey) {
        setKeyPressed(true);
      }
    }
    // If released key is our target key then set to false
    const upHandler = ({ key }) => {
      if (key === targetKey) {
        setKeyPressed(false);
      }
    };
    // Add event listeners
    useEffect(() => {
      window.addEventListener("keydown", downHandler);
      window.addEventListener("keyup", upHandler);
      // Remove event listeners on cleanup
      return () => {
        window.removeEventListener("keydown", downHandler);
        window.removeEventListener("keyup", upHandler);
      };
    }, []); // Empty array ensures that effect is only run on mount and unmount
    return keyPressed;
  }

Bruk useKeypress i Modal.js

useKeypress håndterer tastetrykkene, det eneste man trenger å sende inn, er hvilken knapp man vil lytte til. I dette tilfellet er venstre pil, høyre pil og Escape knappen brukt for å navigere med tastaturet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { useKeyPress } from "../../hooks/useKeypress";
...
    
const right = useKeyPress("ArrowRight");
const left = useKeyPress("ArrowLeft");
const exit = useKeyPress("Escape")
 
    useEffect(() => {
        if (left) {
            previousImage()
        }
        if (right) {
            nextImage()
        }
        if (exit) {
            setSelectedIndex(-1);
        }
    }, [left, right, exit])

Filer

Modal.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import React, { useEffect } from "react";
 
import { motion } from "framer-motion";
import { useKeyPress } from "../../hooks/useKeypress";
 
const Modal = ({ selectedImg, selectedIndex, setSelectedIndex, images }) => {
    const right = useKeyPress("ArrowRight");
    const left = useKeyPress("ArrowLeft");
    const exit = useKeyPress("Escape")
    const clickHandler = (e) => {
        if (e.target.classList.contains("backdrop")) {
            setSelectedIndex(-1);
        }
    };
 
    useEffect(() => {
        if (left) {
            previousImage()
        }
        if (right) {
            nextImage()
        }
        if (exit) {
            setSelectedIndex(-1);
        }
    }, [left, right, exit])
 
    function nextImage() {
        let imageIndex = selectedIndex
        if (imageIndex >= images.length - 1) {
          imageIndex = 0
        } else {
          imageIndex = selectedIndex + 1
        }
        setSelectedIndex(imageIndex)
      }
     
      function previousImage() {
        let imageIndex = selectedIndex
        if (imageIndex > 0) {
          imageIndex = selectedIndex - 1
        } else {
          imageIndex = images.length - 1
        }
        setSelectedIndex(imageIndex)
      }
 
    return (
        <motion.div
            className="modal show backdrop bg-transparent-dark"
            style={{display: "block"}}
            onClick={clickHandler}
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
        >
            <div className="modal-dialog modal-dialog-centered modal-xl">
                <div className="modal-content" style={{ border: "none", backgroundColor: "black" }}>
                    <motion.img
                        src={selectedImg ? selectedImg : "https://smorasstats.com/v4/wp-content/uploads/2020/06/71951528_2527097874023921_5910925260533792768_o.jpg"}
                        alt="Modal"
                        initial={{ width: "110%" }}
                        animate={{ width: "100%" }}
                    />
                     
                </div>
            </div>
            <div className="imageCount text-white">
                {selectedIndex + 1} / {images?.length}
            </div>
            <div className="closeButton">
                <button
                    onClick={() => setSelectedIndex(-1)}
                    type="button"
                    class="close"
                    style={{ color: "white" }}
                >
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div className="lightbox-navigation">
                <div  onClick={previousImage} className="arrow-left">
                    <i className="fas fa-chevron-left"></i>
                </div>
                <div onClick={nextImage} className="arrow-right">
                    <i className="fas fa-chevron-right"></i>
                </div>
            </div>
        </motion.div>
    );
};
export default Modal;
Legg igjen en kommentar