레이블이 javascript인 게시물을 표시합니다. 모든 게시물 표시
레이블이 javascript인 게시물을 표시합니다. 모든 게시물 표시

2010년 7월 11일 일요일

자바 스크립트에서 trim()에 대한 단상

자바 스크립트는 trim() 함수를 지원하지 않는다.

그래서 정규식을 활용해서 구현해서 사용하는 것이 일반적이다.

 

주어진 문자열의 앞뒤를 동시에 트림하는 함수를 구현한 가장 일반적인 함수는 아래의 형태이다.

 

function trimboth1(str) {
  return str.replace(/^\s+|\s+$/g,'');
}

그런데, 인터넷을 뒤지다가 Faster Javascript Trim이라는 글을 찾았다.

글의 요지는 간단하다. 정규식을 이용하는 것이 가장 빠른 것이 아니라는 것.

 

코드의 길이가 좀 길어지더라도 더 빠른 함수가 필요하다면 아래와 같은 형태가 좋은 것 같다.

 

function trimboth2(str) {
  var space = '\s';
  var left=str.length, right=-1, i;
  for (i=0; i<str.length; i++) {
    if (space.indexOf(str.charAt(i)) == -1) {
      left = i;
      break;
    }
  }
  for (i=str.length-1; i>=left; i--) {
    if (space.indexOf(str.charAt(i)) == -1) {
      right = i;
      break;
    }
  }
  if (left>right) return '';
else return str.substring(left, right+1);
}

2009년 6월 12일 금요일

javascript에서 js 파일 자체의 파일명을 알애내는 방법

BBCode for TiStory 3.1을 개발하는 과정에서 js 파일이 저장된 폴더를 알아내야 했다.

지금까지는 각 이미지의 절대주소를 코드 안에 넣어뒀는데, 이제는 그럴 수 없게 되었기 때문이다.
그 전까진 내 전용 코드에만 추가적인 이미지를 사용했는데, 이제 이모티콘이 추가됨으로써 그런 주먹구구는 버려야 했기 때문.

그래서, 일단, js 파일 자체의 이름을 알아내는 방법을 찾아봤다.
우선 찾은 방법은 아래와 같은 코드이다.

getCurrentPath: function()
{
    var GetCurPath = (function(){
        var RandID = "SID" + Math.round(100000*Math.random());
        document.write("<script id='"+RandID+"'></script>");
        return document.getElementById(RandID).previousSibling.getAttribute("src");
    })()
    return GetCurPath;
}

이 코드를 js 파일에 추가한 뒤에 getCurrentPath() 함수를 호출하면 js 파일 자체의 이름이 리턴된다.

이 함수는 깔끔하고 명확하기는 하지만, 약간의 부담스러운 점이 있다.
내용이 텅 비긴 했지만, SID로 시작하는 임의의 스크립트를 하나 만든다는 것이다.

아무것도 추가하지 않는 방법을 찾아보니 아래와 같은 방법을 찾을 수 있었다.

getCurrentPath: function()
{
    var scr=document.getElementsByTagName('script');
    return(scr[scr.length-1].getAttribute("src"));
}

약간 복잡하기는 하지만, 이 함수는 IE8, FF3, Chrome2 에서 정상동작하는 것을 확인했다.
(물론 앞의 함수 역시 각 브라우저들에서 잘 동작한다)
이 코드 역시 js 파일에 추가한 뒤에 getCurrentPath() 함수를 호출하면 js 파일 자체의 이름이 리턴된다.

이렇게 js 파일 자체의 파일명을 얻었으면, 다음은 간단하다.
아래와 같이 getCurrentPath() 뒤에 간단한 정규식 함수 하나만 달아주면 된다.

alert(getCurrentPath().match(/^(.*)\/([^\/]*)$/i)[1]+'/');

덧. 이 함수는 html 파일 내에 위치하면 안된다.
두 getCurrentPath() 모두 html 내에서는 null을 리턴하기 때문이다.


2008년 10월 3일 금요일

JavaScript 코드 압축기 비교사이트 소개

블로그를 관리하다보면 자바스크립트 코드의 크기가 신경쓰입니다.
트래픽을 일일이 고민해야 하는 설치형 블로그는 물론이고, 트래픽의 제한이 없는 가입형 블로그에서도 스크립트 소스가 커지는 것이 그닥 좋지는 않습니다.

그러다보니 압축기를 사용하게 되는데, 찾아보니 여러 압축기를 돌려서 결과를 한칼에 비교해주는 사이트가 있더군요.

압축하고 비교하는데 시간은 다소 걸리지만, 좀 더 작은 크기의 코드를 선호할 때엔 훌륭한 선택이 아닐까 합니다.

링크: CompressorRator



2008년 4월 22일 화요일

티스토리용 BBCode v1.1a (역시 전문가 여러분의 도움이 필요합니다)

사용자 삽입 이미지

드디어 여러줄에 걸친 다중태그를 정확하게 해석합니다!


티스토리용 BBCode v1.0을 통해 공개한 티스토리용 BBCode를 하루동안 사용해보니 2개의 문제가 발견되었습니다.

1. 여러줄에 걸친 태그는 전혀 해석을 못함
2. 중첩된 태그를 전혀 해석 못함 (특히 [quote])

두 문제 모두 제가 정규식을 정확하게 이해하지 못해서 발생한 문제들입니다.
이 문제들을 해결한 BBCode.js 파일을 아래에 첨부합니다.


이제 버전 1.1a이라는 타이틀을 달고 올리기는 했지만, 많은 한계가 보입니다.
티스토리에서 BBCode를 정식으로 지원할 때까지는 빡세게 계속 달려보겠습니다.

덧1, [qoute]를 해석할 때는 <blockquote>로 변환하는 것이 정석입니다.
하지만, 우리의 IE6/7에 내장된 자바스크립트 엔진의 insertBefore 함수는 <blockquote>를 씹어먹어버리더군요.
그래서 울며 겨자먹기로 <table>로 변환했습니다.

덧2, 아주 자그마한 부분을 변경했습니다. ([quote] 태그 주변에 약간의 여백을 둠)
너무 사소한 변경이라 별도로 포스팅하지 않고, 내용만 약간 수정했습니다.


티스토리는 BBCode를 지원하라! 지원하라!



 

2008년 4월 19일 토요일

티스토리용 BBCode v1.0 공개 (전문가 여러분의 손길을 기다립니다)

사용자 삽입 이미지

BBCode가 제대로 지원되려면 아직 멀었습니다…


티스토리용 BBCode v1.1a로 업데이트했습니다. 설치법 및 구조에 관한 부분은 현재의 글을 읽으시면 됩니다.


티스토리용 BBCode 구현. 그러나…에서 포스팅했던 티스토리용 BBCode의 Working version 1.0을 공개합니다.
시스템 자체에서 지원해주는 것처럼 깔끔하지는 않겠지만, 아쉬운대로 쓸만은 한 수준입니다.

혹시 관심있으신 분들은 적용해보시기 바랍니다.
그리고, (혹시 더 관심이 있으신 분들은) 코드를 보시고 개선방안을 가르쳐주시면 고맙겠습니다.



1. 설치방법

a. bbcode.js 업로드

위 파일을 다운받은 후 압축을 풀면 bbcode.js와 bbcode2.js의 두 개의 파일이 나옵니다.
bbcode.js가 원본 파일이고, bbcode2.js는 Creativyst의 JavaScript Compression으로 bbcode.js를 압축한 파일입니다.
(당연한 얘기지만, 둘의 동작은 완벽하게 동일합니다)
이 두 파일 중 하나를 선택해서 스킨→직접올리기 메뉴를 통해 업로드합니다.


b. skin.html 수정 #1

스킨→HTML/CSS 편집 메뉴를 통해서 skin.html을 수정합니다.

우선, 헤더의 마지막을 표시하는 </head> 앞에서 위의 a.에서 업로드한 bbcode.js를 읽도록 지정합니다.
<script language="javascript" src="./images/bbcode.js"></script>
</head> <!-- 이 줄은 추가할 필요 없음. 위치 표시용 -->
다음, 스킨 맨 아래쪽에 있는 </body> 앞에 아래의 코드를 추가합니다.
<script language="javascript">
BBDecode.UpdateBBCodeNow();
</script>
</body> <!-- 역시 추가할 필요 없음 -->


c. skin.html 수정 #2

본문의 치환자들 중에 rp_onclick_submit, rp_rep_onclick_delete, rp_rep_onclick_reply, guest_onclick_submit, guest_rep_onclick_delete, guest_rep_onclick_reply를 찾아 치환자 앞에 모두 BBDecode.ResetTimer(); 를 추가합니다.
(어렵죠? 아래 코드를 보시면 쉽습니다)

원래의 코드가
<a href="#" onclick="[#\#_guest_rep_onclick_delete_#\#]" class="modify">
라면 아래와 같이 BBDecode.ResetTimer();를 추가하면 됩니다.
<a href="#" onclick="BBDecode.ResetTimer(); [#\#_guest_rep_onclick_delete_#\#]" class="modify">
각 치환자는 모두 1번씩 나오는데, *_onclick_delete는 2번 나옵니다.
즉, BBDecode.ResetTimer();를 8군데 추가하면 됩니다.


d. skin.html 수정 #3

본문의 치환자들 중에 rp_rep_desc, guest_rep_desc를 찾아 치환자 앞뒤에 각각  <textarea name="bbcode"> 와 </textarea> 를 추가합니다.
(역시 아래 코드를 보시면 쉽습니다)

원래의 코드는
<p>[#\#_rp_rep_desc_#\#]</p>
<p>[#\#_guest_rep_desc_#\#]</p>
의 형식인데, 태그를 앞뒤에 추가하면 아래와 같이 됩니다.
<p><textarea name="bbcode">[#\#_rp_rep_desc_#\#]</textarea></p>
<p><textarea name="bbcode">[#\#_guest_rep_desc_#\#]</textarea></p>
각 치환자는 모두 2번씩 나오므로 , <textarea name="bbcode">와 </textarea>를 4군데 추가하면 됩니다.


2. 사용법

사용은 댓글을 달면서 적절하게 BBCode를 적어주는 것으로 충분합니다.
그리고, 현재 지원 가능한 BBCode는 총 7가지입니다.

[i]이탤릭[/i] : 이탤릭
[b]볼드[/b] : 볼드
[u]밑줄[/u] : 밑줄
[quote]인용문[/quote] : 인용문 (예제 생략)
[img]이미지 URL[/img] : 이미지 (예제 생략)
[url=http://qaos.com]QAOS[/url] : QAOS (링크)
[color=red]색깔[/color] : 색깔

그리고, 댓글에 치환자를 적을 수 있도록 \#을 입력하면 #으로 변환해주는 기능과 태그를 적을 수 있도록 <[공백]태그 를 입력하면 공백을 없애주는 기능을 포함했습다.
즉, [#\#치환자#\#]를 입력하면 사이에 있는 \는 사라지고, < color>를 입력하면 공백이 사라져 <color>만 남습니다.

※ 태그 입력 기능은 BBCode 변환과 스마일리 기능 등이 겹쳐 어쩔 수 없이 포함시킨 기능입니다.





3. 구현 개념 및 개선필요사항 (전문가 분들의 도움이 필요한 부분)

a. 구현 개념

전체 페이지를 다시 읽는 경우 페이지 마지막에 BBDecode.DecodeAll()함수를 호출하고, 이 함수는 웹페이지에서 <textarea name="bbcode">~</textarea>를 찾아 이 부분에 display='none' 속성을 추가하고, 내부에 있는 BBCode를 HTML로 변환해서 <textarea> 앞에 추가합니다.

댓글을 달거나 지우는 등의 댓글 일부를 수정하는 작업이 발생할 때는 작업 전에 BBDecode.ResetTimer()함수를 호출하고, 이 함수는 최초에 0.5초, 다음에 3초, 그 다음에 5초 간격(이후 계속 5초 간격)으로 BBCode를 HTML로 계속 변환을 시도하며, 변환이 1번 이루어지면 바로 종료됩니다.

이렇게 복잡하게 구성된 이유는 댓글의 갱신이 완료되었을 때 발생하는 이벤트를 모르기 때문입니다.
(그런데, 그런 이벤트가 있기는 한가요?)


b. 개선필요 사항

앞에도 적었듯이, 댓글이 갱신되었을 때 발생하는 이벤트를 알 수 있으면 타이머 부분을 제거하고, 더 단순하고 깔끔하게 수정할 수 있습니다.

또, 변환하는 코드도 짜깁기의 흔적이 역력하여 다소 지저분한 구석이 있고, (저도 왜 만들었는지 모르는) 빈 함수 몇 개가 굴러다닙니다. 불필요한 함수를 없애는 방법이 없을까요?
(자바스크립트도 의외로 어렵군요)





며칠간 티스토리에서 BBCode를 구현해보겠다는 일념으로 여기에만 매달렸더니 정신이 없습니다.
조금 쉬었다가 더 공부해서 완벽한 BBCode를 구현해보겠습니다. 아자자자잣!


 

2008년 4월 18일 금요일

티스토리용 BBCode 구현. 그러나…

사용자 삽입 이미지

티스토리 최초의 BBCode 구현. 그러나…

텍스트큐브(태터툴즈)를 비롯한 많은 블로그 환경에서는 간단한 텍스트 효과를 위해서 BBCode를 지원합니다.
(BBCode에 대한 상세한 설명은 QAOS - BBCode의 사용법을 참고)

하지만, 태터툴즈를 기반으로 하는 티스토리에서는 아직 BBCode를 지원하지 않습니다.
스마일리 플러그인을 지원하는 것으로 보아 구현이 어려운 것 같지도 않은데요…

QAOS나 Sleepy Tiger님의 블로그를 보면서 댓글에 BBCode를 적용해서 많은 효과를 줄 수 있다는 점이 부러웠습니다.

목마른 놈이 우물 판다고 하죠. 네, 그래서 직접 구현해봤습니다.

일단, 저는 자바스크립트 맹이기 때문에 (직접 다 만들지는 못하고) 그 유명한 구글코드의 Code Highlighter를 뜯어고쳐 적용하기로 했습니다.

그리고, 정규식을 잘 모르기때문에, QAOS에서 무려 12년 전에 강의하신 정규식 강의를 통해 정규식을 공부했습니다.

다 구현해놓고 보니 현재의 티스토리는 BBCode가 매끄럽게 구현되기 힘든 환경이더군요.

사용자 삽입 이미지

최초 입력할 때는 BBCode가 그냥 보이고, 갱신해야 변환된다는 거…

구현의 개념은 댓글 상자를 <textbox> 태그로 묶은 뒤 마지막에 변환해주는 코드를 실행시키는 것입니다.
그런데, 티스토리는 글을 처음 입력한 뒤에 Save a comment 버튼을 클릭하면 페이지 전체를 다시 부르는 것이 아니라 댓글 부분만 갱신해줍니다. (속도를 위한 최적의 선택입니다)

따라서, 글을 입력하거나 삭제하면 바로 위의 화면처럼 홀딱 벗은(?) BBCode가 그대로 등장했다가 화면을 갱신해야 HTML로 변신해서 표시됩니다. ㅠ.ㅠ

이 문제는 티스토리 자체적으로 BBCode를 지원해줄 때까지는 답이 없을 것 같습니다.

티스토리는 BBCode를 지원하라! 지원하라!