티스토리 뷰
이번에 고민해서 구현한 기능은 아래와 같습니다.
웹소켓으로 구현하면 좋겠지만 이번 프로젝트에 realtime database를 사용해서 조금 아쉽습니다.
그래도 상상한 기능은 비슷하게 구현된 것 같습니다.
이번에 배운 포인트는 총 세가지입니다~
1. 모든 참여자가 실시간으로 동일하게 받는 이벤트가 필요합니다. 즉, 한 명이 onBlur 이벤트가 발생한다고 해서 모두에게 onBlur가 발생하는 건 아닙니다. onBlur 이벤트에 css를 바꿔주면 나한테만 보입니다.
2. 무수히, 산발적으로 발생하는 이벤트 와중에 적절한 타겟을 골라와야 합니다.
3. setTimeout이 동시에 여러 개 돌아가야 합니다. 즉, 변수명이 동적으로 바뀌는 함수가 여러개 필요합니다.
처음에는 textarea의 onChange이벤트가 발생할 때마다 css만 바꿔주면 되겠지~라고 쉽게 생각했으나, 다른 사람에게 실시간적으로 보이지는 않았습니다. 당연히 제가 텍스트를 입력한다고 다른 사람의 브라우저에서 onChange가 발생하는 건 아니니까요!
그래서 모든 브라우저가 동일하게 수신하는 이벤트가 필요했습니다. 다행히 realtime DB에서 적절한 함수를 찾았습니다.
onChildChanged라는 함수인데요! 메모가 입력되는 객체의 부모에 ref를 걸어놓고 자식이 변화할 때마다 이벤트를 수신했습니다.
이제 텍스트가 편집될 때마다 다른 모든 브라우저에서 이벤트를 받을 수 있습니다.
일단 편집이 되는 teatarea의 key를 받아왔는데 이걸 어떻게 저장해놓고 써야 할지 막막했습니다. "안녕하세요"라고만 쳐도 이벤트가 12개라서 똑같은 key를 12개나 수신했기 때문입니다.
그래서 이 key를 차곡차곡 쌓아서 중복이 불가능한 배열을 만들고 index로 찾아가며 적절한 class를 주어 css를 변화시키기로 했습니다.
빈 배열에 key를 계속 쌓아가며 set객체를 이용해 중복이 없는 배열을 만들었습니다. 이제 uniqueArr에는 사용자가 편집하는 순서대로 key가 순서대로 들어가 있습니다. 그리고 key와 동일한 id를 가진 textarea element를 가져왔습니다. 색을 다르게 해주는 class를 추가했습니다. 이제 편집이 시작되는 순간 모든 브라우저에서 파란색으로 표현되기 시작합니다.
저는 이것을 1.5초만 유지하고 사용자가 1.5초간 추가적인 편집이 없으면 다시 원상 복귀하고 싶습니다. 그래서 setTimeout을 이용해서 1500밀리세컨드후에 class를 제거해주었습니다.
근데 만약 1초 간격으로 계속 이벤트가 발생하면, 두 번째 이벤트가 발생한 지 0.5초 만에 색깔이 원상 복귀되어 버립니다.
첫 번째 이벤트에서 실행했던 setTimeout시간이 완료되어 class를 제거했기 때문입니다.
그래서 이벤트가 새로 발생하면 기존에 진행 중이던 setTimeout을 제거해줘야 합니다. 그리고 다시 0초부터 시작해야 합니다.
이런 함수를 계속 반복해야 class가 중간에 제거되지 않고 편집이 지속되는 동안은 계속 다른 css를 유지할 수 있습니다.
이렇게 해놓고 테스트를 했는데,,, 다른 사람이 중간에 끼어들면 처음에 작업하던 teatarea에서 class가 영원히 제거되지 않습니다.
곰곰이 생각하다가 동기&비동기 발표자료 공부할 때가 떠올랐습니다. 싱글스레드인 자바스크립트에서 setTimeout이 비동기적으로 실행되는 이유는 브라우저가 제공하는 webAPIs를 활용할 수 있기 때문이라는 것이라는 생각이 났습니다.
중간에 다른 textarea에서 편집이 시작된다는 것은 브라우저가 처리하던 setTimeout함수가 미처 완료되지 못하고 중간에 스텍에서 넘어온 새로운 setTimeout으로 덮어 씌워지는 것 같다는 생각이 들었습니다. 그래서 class가 제거되는 함수가 마저 실행되지 못하고 중간에 증발해버리는 거죠.
그럼 setTimeout함수에 변수명을 다르게 주면 여러 개의 setTimeout이 동시에 실행되게 할 수 있지 않을까요?
그래서 위에 보는 timeout0이라는 급조한 티가 역력한 변수명이 있습니다.
과연 두 개의 setTimeout이 동시에 진행될 수 있을까..
첫 번째 textarea는 object.timeout0라는 함수가 실행되고, 두 번째 teaxarea는 object.timeout1 이라는 함수가 실행됩니다.
(아니죠 사실은 첫번째로 편집이 시작된 textarea에서 object.timeout0 함수가 실행되겠죠.. 편집이 시작된 순서가 중요하지, 누가 위에있는지는 관심이 없습니다.)
그리고 setTimeout이 두 개 실행됩니다! 이렇게 원하는 기능을 구현할 수 있었습니다.
이제 저 case가 10개나 되는 switch 문을 간단한 코드로 구현하는 일만 남았습니다.ㅎㅎㅎ 해결하게 되면 포스팅하겠습니다.
'항해99 개발일지' 카테고리의 다른 글
이미지 업로드 용량 줄이기 browser-image-compression (0) | 2022.05.27 |
---|---|
1차 베타테스트 오픈 (0) | 2022.05.24 |
DB문제 해결, 큰 문제의 원인은 아주 사소한 것 (0) | 2022.05.20 |
DB의 데이터가 갑자기 사라진다 (0) | 2022.05.20 |
JWT인증, Access, Refresh token에 대하여 (0) | 2022.05.15 |