이 글은 필요 없는 부분이 일부 있습니다. 코드를 원하시면, '함수' 항목으로 이동하세요.
1. 계기
Share Links는 반응형 바둑판 레이아웃(항목의 가로길이는 고정, 세로길이는 유동적)를 사용합니다. 한마디로 말해서 핀터레스트(Pinterest)의 레이아웃입니다.
flex
나grid
로 하려했으나 실패해 결국에는 자바스크립트의 힘을 빌렸습니다. 처음에 핀터레스트는 어떻게 구현한건지 살펴보니 일일이top
과left
를 때려박아서(...) 만들어져있었습니다.
여하튼 한번 만들어놓고 잘 썼었습니다만, 태그 목록이 길어지면 overflow:auto
시켜서 가로스크롤로 표현하는 대신, 세로를 height:auto
로 설정해 스크롤 없이 표현하는 것으로 레이아웃을 변경하려고 했습니다. 또한 제목이 길어지면 역시 태그처럼 스크롤을 생성하지 않게 레이아웃을 변경하려했습니다. 이제 auto로 늘어난 만큼을 계산해서 전체 카드의 height
를 구하는 것이 관건이었습니다.
자바스크립트에서 .length
는 한글이나 영어나 한글자로 취급해 반환합니다. 하지만 렌더링상으로는 전각과 반각문자이기 때문에, 차지하는 넓이는 다릅니다.
저는 "와 문자열이다!".getLength()
의 길이가 14
로 취급되는 것을 원했기 때문에, 바이트값으로 문자열의 길이를 측정할 방법이 필요하다고 생겼습니다.
물론 모노(Mono)글꼴을 사용하지 않으면 글자들이 각기 다른 넓이를 갖고 있지만 한글/한자 = 2, 반각문자 = 1, 정도로 계산해도 충분하기 때문에 넘어 갈 수 있습니다.
원본 코드는 https://programmingsummaries.tistory.com/239 에 소개되어있는 코드 중 '개선된 FOR문'의 코드입니다.
아래의 코드는 해당 코드를 map과 reduce를 대신하여 사용한 것입니다. 또한 바이트 수를 구하는 부분은 해당 글에 달려 있는 댓글 중 '노예'라는 분이 써주신 EUC-KR용(2바이트) 코드를 사용했습니다. 만약에 한글을 3바이트로 계산하는 코드가 필요하다면 아래에서 일부 코드를 '개선된 FOR문' 코드에서 따와서 고치면 됩니다.
원리는 아래와 같습니다.
먼저, map과 reduce를 쓰기 위해 문자열을 배열로 쪼갭니다.
그 다음으로, map으로 각 문자의 문자 코드 배열을 만듭니다. 이 과정을 생략하려면 charCodeAt(0)을 reduce 부분에 2번 해주어야합니다.
이제 계산식을 사용해서 reduce로 값을 구해주면 됩니다.
function getByte(str) {
return str
.split('')
.map(s => s.charCodeAt(0))
.reduce((prev, c) => (prev + ((c === 10) ? 2 : ((c >> 7) ? 2 : 1))), 0); // 계산식에 관한 설명은 위 블로그에 있습니다.
}
여담으로, 이 글은 https://jaeheon.kr/123 에도 올라와있습니다. 하지만, 분명이 블로그 글이 원본임에도 불구하고 velog에 작성하면서 싹 고친것 + velog의 깔끔한 UI덕분에 velog가 훨씬 더 좋습니다. 물론 여기에 쓰면서 개선된 부분을 블로그에 다시 옮겨 붙이긴 했습니다.
잘 참고하였습니다 : )