갬쿠
개미 개발
갬쿠
전체 방문자
오늘
어제
  • ALL (137)
    • React (20)
    • JS & CSS & HTML (29)
    • Algorithm (62)
    • 웹 보안 (11)
    • 달리는 까까: 쿠키런 팬게임 (10)
    • Python (0)
    • 기타 (5)
    • 비공개 플젝 (0)

블로그 메뉴

  • GitHub
  • 방명록
  • 관리자 메뉴

공지사항

인기 글

태그

  • Best of the Best
  • Programmers
  • 쿠키런 모작
  • 백준
  • node.js
  • useReducer
  • SQL Injection
  • 크롬 공룡게임
  • Python
  • BEAKJOON
  • 모의 해킹
  • 크롬 공룡 게임
  • 달리는 까까
  • HTML
  • 객체
  • 쿠키런
  • useState
  • js
  • 쿠키런 팬게임
  • Baekjoon
  • 게임 개발
  • CSS
  • Object
  • useEffect
  • 게임
  • REACT
  • 리액트
  • EventListener
  • JavaScript
  • transform

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갬쿠

개미 개발

contentEditable로 수정 기능 구현하기
JS & CSS & HTML

contentEditable로 수정 기능 구현하기

2023. 7. 17. 18:19

스크립트에서 수정 기호를 선택한 채로 어떤 단어를 클릭하면 수정 가능하도록 하는 기능을 구현해야 했다. 클릭 이벤트를 감지해서 input text를 단어 위에 띄우고 고생하고 있었는데(input을 띄우면 기존 기능들이 적용이 안 됐다) contentEditable이라는 옵션이 있다는 걸 알게 되었다.

https://developer.mozilla.org/ko/docs/Web/HTML/Global_attributes/contenteditable

 

contenteditable - HTML: Hypertext Markup Language | MDN

contenteditable 전역 특성은 사용자가 요소를 편집할 수 있는지 나타내는 열거형 특성입니다.

developer.mozilla.org

 

<span contenteditable="true">
	수정 가능한 텍스트
</span>

위와 같이 옵션을 주면 사용자가 클릭했을 때 바로 수정이 가능하다(우와).

 

나는 아래와 같이 사용했다.

<Text
    onKeyDown={(e) => {
      if (e.key === "Enter") {
        e.preventDefault(); // 줄바꿈 방지
      }
    }}
    onInput={(e) => {
      console.log("수정 후: ", e.target.innerText);
      edited[i] = e.target.innerText; // 수정 후 단어를 edited에 저장
      setEdited([...edited]);
    }}
    contentEditable={cursor === edit} // 현재 커서가 수정펜일 때만 수정 모드
    spellCheck={false}
    suppressContentEditableWarning={true} // warning 무시..
>

우선 onKeyDown() 이벤트에서 엔터 키를 눌렀을 때 줄바꿈이 되지 않도록 했다(서비스 기능 상 필요).

그리고 onInput()으로 텍스트가 바뀔 때마다 업데이트 했는데, onChange()는 input, textarea, select 같은 엘리먼트에서만 작동하기 때문이다.

conteneEditable 옵션은 내가 원하는 상황에서만 켜지도록 설정하고 spellCheck를 false로 설정해 사용자의 입력에 대한 맞춤법 검사는 하지 않았다.

이렇게 리액트 컴포넌트 안에 contentEditable 옵션을 넣으면 "A component is contentEditable and contains children managed by React"이라는 콘솔 워닝이 뜨는데, 뭐 컴포넌트 안의 내용이 변할 수 있고 그 책임은 너한테 있다는 내용이다. 내가 원하는 기능이 컴포넌트 안의 내용 변화기 때문에, suppressContentEditableWarning을 설정해 워닝을 무시했다.

 

++ 저렇게 했더니 텍스트가 변할 때마다 edited state가 다시 렌더링 되면서 delete가 제대로 동작하지 않길래 다음과 같이 수정했다.

onBlur={(e) => {
  console.log("수정 후: ", e.target.innerText);
  edited[i] = e.target.innerText; // 수정 후 단어를 edited에 저장
  setEdited([...edited]);
}}

onBlur() 이벤트는 사용자가 input field를 벗어났을 때 작동한다. 편집이 끝나고 다른 곳으로 포커스를 이동하게 되면 수정된 최종 단어를 저장하도록 수정했다.

 

수정 전 단어를 보여주기 위해서는 툴팁을 제작했다.

const OriginalText = styled.span`
  visibility: hidden;
  // 디자인 및 위치

  ${Text}:hover & {
    visibility: visible;
  }

  // 아래 화살표 디자인
  &::after {
    content: " ";
    position: absolute;
    top: 100%;
    left: 50%;
    margin-left: -5px;
    border-width: 5px;
    border-style: solid;
    border-color: grey transparent transparent transparent;
  }
`;

툴팁까지 예쁘게 만들어 주고 나면 수정 기능 완성!

 

728x90

'JS & CSS & HTML' 카테고리의 다른 글

JS e.target vs e.currentTarget (미스터리 해결기...)  (1) 2023.07.20
JS sort (문자열 배열 정렬 & 숫자 배열 정렬)  (0) 2022.06.26
JS Image preloading  (0) 2022.05.31
CSS transform: translate vs. absolute positioning  (0) 2022.05.31
CSS line-height  (0) 2022.05.03
    'JS & CSS & HTML' 카테고리의 다른 글
    • JS e.target vs e.currentTarget (미스터리 해결기...)
    • JS sort (문자열 배열 정렬 & 숫자 배열 정렬)
    • JS Image preloading
    • CSS transform: translate vs. absolute positioning
    갬쿠
    갬쿠
    보안&소프트웨어 전공 프론트엔드 개발자

    티스토리툴바