Post

웹 페이지에서 번역된 콘텐츠와 원문 간의 전환 구현하기

comment, reply 만 따로 번역하기 기능


원래 처음 번역 서비스를 개발했을때는 전체 페이지 번역만 기능 개발을 했었다. 따라서 원문 보기는 뒤로가기 를 page replace 로 하여 번역 전을 볼 수가 있었다! 하지만 페이지를 한참 내리다가 번역하고 싶은 댓글을 보는 경우가 사용하다보니 많았고 현재로써는 그 댓글 하나를 번역 하기 위해 제일 페이지 상단에 올라가야 한다. 사용자 입장에서 불편하다!

따라서 댓글 그리고 답변들만 번역 할 수 있는 버튼도 따로 제작을 했다. 그랬더니 구현하기가 조금 까다로웠던 것은 원문보기였다. 기존에는 뒤로가기로 아주 간단하게 해결했는데 이제는 하나 하나를 번역하고 하나하나를 원문으로 돌릴수 있어야 했다.

어떤 방법으로 할까?


우선 머리속에 떠오르는 방법은 3가지 정도가 있었다.

  1. 번역을 할때 해당 번역 아래에 hide 를 class 로 준 다음 span 으로 어디 숨겨놓는다! 그리고 원문 보기를 하면 번역했던 결과는 삭제해버리고 hide를 없애버린다.
  2. 번역을 할때 번역하는 element 의 html 값을 저장해 두었다가 원문 보기를 하면 그걸로 바꿔친다.
  3. 현재 페이지를 js 에서 다시 불러온 다음 현재 위치를 찾아 바꿔친다.

1번 방법은 디버깅을 할때나 개발자도구로 html을 확인할때 너무 복잡할 것 같았다. 번역 버튼을 누르면 element가 두배가 되니 말이다!

3번 방법은 전체 페이지를 불러와야 한다는 것이 쓸모 없는 부분이었다. 부분 부분 불러올수 있도록 api 를 하나 뚫는 다고 해도 client 에서 해당 글의 id, comment 의 id 를 알아야하기에 너무 쓸모 없는 정보를 다 표현해야 할 것 같았다.

따라서 2번으로 진행하기로 했다!

originalHtmlList 를 하나 만들어 놓고 번역 하는 순서대로 차곡 차곡 innerHtml 을 push 한다. 그리고 해당 index 에 맞게 번역을 진행한 element 에는 translated-{index} 라는 class 를 넣어버린다. 원문 보기를 누르면 index 를 확인하고 예전의 html을 넣어준다!

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
let originalHtmlList = [];

function getTranslatedIndex(classList) {
	// translated-{index} 를 찾아보고 있으면 index return
	// 없다면 -1 return
}

function revertTranslatedElement(translatedTargetElementList) {
	if (!translatedTargetElementList || translatedTargetElementList.length === 0) return;
	translatedTargetElementList[0].innerHtml = originalHtmlList[getTranslatedIndex(translatedTargetElementList[0].classList)]
}

function translateSpecifiedElement(target, translatedTargetElementList) {
	if(!translatedTargetElementList || translatedTargetElementList.length === 0) return;
	if (getTranslatedIndex(translatedTargetElementList[0].classList) < 0 ) {
		// 이미 번역이 되어있었으면 패쓰!
		translatedTargetElementList[0].classList.add("translated-" + originalHtmlList.length);
		originalHtmlList.push(translatedTargetElementList[0].innerHtml);
		// originalHtmlList 에 원래 html 을 넣어버린다!
	}
	translateByNode(translatedTargetElementList[0], target)
}

$(document).on("click", ".original-reply"), function(event) {
	event.preventDefault();
	originalButton.addClass("hide"); // 원문보기, 번역하기 토글
	translateButton.removeClss("hide");
	revertTranslatedElement($(event.target).parent().find("reply-border"))
});

$(document).on("click", "reply-translate-button", function(event) {
	event.preventDefault();
	translateButton.addClass("hide"); // 원문보기, 번역하기 토글
	originalButton.removeClass("hide");
	translateSpecifiedElement("en", $(event.target).parent().find("reply-border"))
})

translated 를 해놓아서 두번 중복으로 원문이 저장되는 일도 없도록 하여 아무리 많이 번역해봤자 실제 페이지 하나보다는 용량이 작도록 했다!

후기


속도도 상당히 빠르고 브라우저 메모리도 많이 차지하지 않고 안정적이다! 다만 하나 걱정되는 것은 어떤 유저가 번역 버튼 여러개를 막 동시에 누르려고하거나 하면 race condition 이 발생 할 것 같다.

아무래도 Object 로 수정하는 작업을 추가로 진행해야 겠다!

This post is licensed under CC BY 4.0 by the author.

© 병욱. Some rights reserved.