로그인

이메일
비밀번호
왼쪽에 걸리적 거리는 거 숨기기
브라우저의 문서 영역의 크기를 구할때
현재 보여지는 부분의 크기(clientWidth, clientHeight)와
실제 존재하는 부분의 크기(scrollWidth, scrollHeight)를 사용하게 되는데,

이게, 브라우저마다 또 표준 DTD 인지 여부에 따라 구하는 방법이 모두 상이하다.
그래서 간단한 함수로 만들어봤다.

IE5, IE55, IE6, IE7, IE8, FF2, Safari3, Opera9 에서 테스트 됨 (Language : javascript)
  1. /**
  2. * 브라우저 document 영역의
  3. * clientWidth/clientHeight, scrollWidth/scrollHeight 구하기
  4. *
  5. * @author hooriza
  6. */
  7. function getClientSize() {
  8.  
  9.   var oDoc = document[document.compatMode == 'CSS1Compat' ? 'documentElement' : 'body'];
  10.   if (/Opera/.test(navigator.userAgent)) oDoc = document.body;
  11.  
  12.   return [
  13.     oDoc.clientWidth,
  14.     oDoc.clientHeight
  15.   ];
  16.  
  17. }
  18.  
  19. function getScrollSize() {
  20.  
  21.   var oDoc = document[document.compatMode == 'CSS1Compat' ? 'documentElement' : 'body'];
  22.   if (/Opera|Safari/.test(navigator.userAgent)) oDoc = document.body;
  23.  
  24.   // IE6 미만이면
  25.   if (/MSIE\s([0-9]+(\.[0-9]+)*)/.test(navigator.userAgent) && parseFloat(RegExp.$1) < 6) {
  26.    
  27.     var aOld = [ oDoc.scrollLeft, oDoc.scrollTop ];
  28.     var aClient = getClientSize();
  29.    
  30.     oDoc.scrollLeft = 999999;
  31.     oDoc.scrollTop = 999999;
  32.    
  33.     var aRet = [
  34.       oDoc.scrollLeft + aClient[0],
  35.       oDoc.scrollTop + aClient[1]
  36.     ];
  37.    
  38.     oDoc.scrollLeft = aOld[0];
  39.     oDoc.scrollTop = aOld[1];
  40.    
  41.     return aRet;
  42.    
  43.   }
  44.  
  45.   return [
  46.     oDoc.scrollWidth,
  47.     oDoc.scrollHeight
  48.   ];
  49.  
  50. }

IE5.5 이하의 경우는 당췌 scrollWidth, scrollHeight 가 제대로 얻어지질 않아서 꽁수를 사용했다;
영양가 있는 포스팅인가요
(총 4분이 투표해서 3.0점) 3.0점
2008/06/09 10:57 2008/06/09 10:57

주옥과 같은 자료
http://www.quirksmode.org/dom/events/index.html

존재조차 몰랐던 이벤트도 많이 있구나.
영양가 있는 포스팅인가요
(총 1분이 투표해서 2.0점) 2.0점
2008/05/16 22:15 2008/05/16 22:15

빠르게 클릭해도 문제가 생기지 않도록 만드는게 맞는 방향이긴 하지만,
여러가지 이유로 빠르게 클릭할 수 없게 만들고 싶은 경우 사용할 수 있는 스크립트이다.

몇 달 전에 만들었던 거.

(Language : javascript)
  1. function protectAbusing(oEl) {
  2.  
  3.   var key = oEl.getAttribute('_pabuse');
  4.   var bef = 0;
  5.  
  6.   if (!key) {
  7.  
  8.     key = 'U' + (new Date().getTime() * 1000000 + parseInt(Math.random() * 1000000));
  9.     oEl.setAttribute('_pabuse', key);
  10.    
  11.   } else {
  12.    
  13.     bef = arguments.callee._clickTimes[key];
  14.    
  15.   }
  16.  
  17.   var now = new Date().getTime();
  18.   arguments.callee._clickTimes[key] = now;
  19.  
  20.   // 마지막으로 클릭한지 1초가 넘었으면 true 리턴
  21.   return (now - bef) > 1000;
  22.  
  23. }
  24.  
  25. protectAbusing._clickTimes = {};

사용은 아래처럼 하면 된다.

(Language : html4strict)
  1. <a href="http://hooriza.com/" onclick="return protectAbusing(this);">

끝.
영양가 있는 포스팅인가요
(총 1분이 투표해서 5.0점) 5.0점
2008/05/14 15:13 2008/05/14 15:13

만드는 중간에 갈아엎은 것 까지 포함하면 대략 5번째 만드는 CSS 셀렉터 엔진.
맨 처음에 만들었던거는 아마 이거였던 것 같다.

매번 만들때마다 만들고 나서 아쉬움이 남았었는데,
이번에 완성한 셀렉터 엔진은 꽤나 만족스럽다.

속도도 꽤나 향상되서 다른 여타 프레임웍에 있는 셀렉터 엔진과 비견할 만큼의 퍼포먼스는 보이는 듯 하다.

아래는 내 노트북에서 Firefox2 로 속도를 비교해 본 결과. (셀렉터 5회 반복)
맨 오른쪽꺼가 이번에 만든거다.

사용자 삽입 이미지

사용자 환경이나 브라우저, 셀렉터 종류마다 차이는 있겠지만 Firefox 와 IE 에서는 다른 셀렉터 엔진이랑 비교했을때 가장 빠른 속도를 보여준다.

작년 겨울, Ajaxian 에서 DomQuery - A lightweight CSS Selector / Basic XPath implementation 포스팅을 보고 저 속도를 어찌나 동경해 왔던가.

그래서 Ext.DomQuery 랑도 1:1 로 비교해봤다. (Firefox2 - 셀렉터 50회 반복)

사용자 삽입 이미지

엎치락 뒤치락 하더니 마지막 nth-child 가상 클래스 부분에서 선전하면서 승리!
아 좋아~ (하지만 XPath 는 지원하지 않는다..)

이번에 사용상의 지원 범위로 신경 쓴건 :not 가상 클래스의 지원과 [type="val\"ue"] 형태나 :contains('I\'m a boy') 형태의 역슬래시 escape 를 사용한 표현의 지원.

추가적으로 특징적인 기능은 빈칸, >, +, ~ 연결자와 반대되는 기능의 연결자가 있다는거.
이를테면,

(Language : javascript)
  1. cssquery("input ! div"); // input 상위에 있는 div
  2. cssquery("span !> div"); // span 바로 위에 있는 div
  3. cssquery("ul !+ div"); // ul 의 바로 앞에 있는 div
  4. cssquery("p !~ div"); // p 의 앞 쪽에 있는 div

이런 식의 연결자를 (CSS 표준은 아니지만) 사용 할 수 있다.

소스 공개는 사내에서 좀 더 확인 과정을 거치고 할 듯.
영양가 있는 포스팅인가요
(총 3분이 투표해서 1.7점) 1.7점
2008/05/14 11:13 2008/05/14 11:13

자바스크립트로 개발할때도 여러가지 디버깅툴이 있지만
가장 간단하고 애용되는 디버깅툴(?)은 바로 alert 이다-_-

하지만 이 alert 을 사용해서 디버깅할때의 문제중 하나가
뭔가 루프를 잘못 돌아 무한 alert 이 뜨는 경우가 생길 수 있다는 것.

브라우저에서 무한 alert 이 떠버리면 브라우저 프로세스를 죽여버리지 않는 이상 벗어날수가 없다.

그런 상황마다 매번 브라우저 죽였다가 다시 띄우고 하는게 여간 성가신 작업이 아닌데...
그래서 만들어 봤다-_-

무한 얼럿 방지 스크립트 (Language : javascript)
  1. /**
  2. * @author http://hooriza.com/
  3. *
  4. * 무한 얼럿 방지 스크립트-_-
  5. */
  6. (function() {
  7.  
  8.   window._alert = window.alert;
  9.  
  10.   window.alert = function(s) {
  11.  
  12.     var f = arguments.callee;
  13.     if (f.ignore) return;
  14.  
  15.     f.count = (new Date().getTime() - f.last < 500) ? f.count + 1 : 0;
  16.  
  17.     if (f.count >= 10) {
  18.       if (confirm('앞으로 alert 무시?')) f.ignore = true;
  19.       f.count = 0;
  20.     }
  21.  
  22.     var r;
  23.     if (!f.ignore) r = window._alert(s);
  24.  
  25.     f.last = new Date().getTime();
  26.     return r;
  27.   };
  28.  
  29.   window.alert.count = 0;
  30.   window.alert.last = 0;
  31.  
  32. })();

사용방법은... 그냥 위의 코드만 넣어주면 된다.

0.5초 이내의 시간 간격으로 얼럿창이 10번 이상 뜨게되면 confirm 창이 하나 뜨게 되고 여기서 확인을 누르면 이후의 alert 은 모두 무시된다.

잘라고 불 끄고 누워있다가 갑자기 생각나서 일어나 만들었다.
제길;

이제 진짜로 자야지.

내용추가 :
간단하게 사용하고 싶으신 분은 아래 코드만 HTML 상단에 추가해서 쓰세요.

(Language : html4strict)
  1. <script src="http://hooriza.com/js/alert.js" type="text/javascript" language="javascript"></script>

영양가 있는 포스팅인가요
(총 2분이 투표해서 3.5점) 3.5점
2008/05/06 23:24 2008/05/06 23:24

아래 올린 타입검사 코드를 사용하여 오버로딩을 구현했다.
같은 함수명으로 여러가지 서로 다른 타입의 인자를 받아들이는 함수를 등록하면 호출 시 가장 적당한 함수를 찾아서 실행해주는 식이다.

(Language : javascript)
  1. /**
  2. * 함수 오버로딩
  3. *
  4. * @author hooriza
  5. */
  6. Function.prototype.overload = function(fpAddFunc) {
  7.  
  8.   var fpRet = this;
  9.  
  10.   // 이미 오버로드 된 함수인지
  11.   var bOverloaded = this._overloaded ? true : false;
  12.  
  13.   // 오버로드 안 되어 있으면
  14.   if (!bOverloaded) {
  15.  
  16.     fpRet = function() {
  17.  
  18.       var aLists = arguments.callee._overloaded;
  19.       var fpRaw = null;
  20.  
  21.       // 인자갯수까지 완벽히 일치하는걸로 실행
  22.       for (var i = 0, fpMethod; fpMethod = aLists[i]; i++) {
  23.  
  24.         if (fpMethod.typesMatch) {
  25.  
  26.           if (fpMethod.typesMatch(arguments, true))
  27.             return fpMethod.apply(this, arguments);
  28.  
  29.         } else if (!fpRaw) {
  30.  
  31.           fpRaw = fpMethod;
  32.  
  33.         }
  34.  
  35.       }
  36.  
  37.       // 대충 맞는 거라도 실행
  38.       for (var i = 0, fpMethod; fpMethod = aLists[i]; i++) {
  39.  
  40.         if (fpMethod.typesMatch && fpMethod.typesMatch(arguments, false))
  41.           return fpMethod.apply(this, arguments);
  42.  
  43.       }
  44.  
  45.       // 아예 types 안 정해진 함수 실행
  46.       if (fpRaw) return fpRaw.apply(this, arguments);
  47.  
  48.       // 실행 할 메쏘드 없음 예외 발생
  49.       throw new Error('Not found the matched method');
  50.      
  51.     };
  52.  
  53.     fpRet._overloaded = [ this ];
  54.  
  55.   }
  56.  
  57.   fpRet._overloaded.push(fpAddFunc);
  58.  
  59.   return fpRet;
  60.  
  61. };

사용은 아래처럼 한다.

(Language : javascript)
  1. var foo = function(nNumber) {
  2.   alert('숫자!');
  3. }.types(Number);
  4.  
  5. foo = foo.overload(function(sStr) {
  6.   alert('문자열!');
  7. }.types(String));
  8.  
  9. foo = foo.overload(function(nNumber, aArray) {
  10.   alert('숫자랑 배열!');
  11. }.types(Number, Array));
  12.  
  13. foo = foo.overload(function(oAnything) {
  14.   alert('아무거나');
  15. });
  16.  
  17. foo(10); // 결과 : 숫자!
  18. foo('hello'); // 결과 : 문자!
  19. foo(10, []); // 결과 : 숫자랑 배열!
  20. foo({}); // 결과 : 아무거나

이를 사용하면 클래스를 구현할때 메쏘드 오버로딩이 가능하도록 개발할 수 있다.
영양가 있는 포스팅인가요
(총 1분이 투표해서 0.0점) 0.0점
2008/04/08 16:20 2008/04/08 16:20

약타입 언어인 자바스크립트에서는
기본적으로 함수의 인자 타입의 검사를 하지 않는다.

하지만 함수가 아무 타입의 값을 받아들일 수 있다는 것이
아무 타입의 값을 넣어도 정상작동 한다는 의미는 아니기 때문에
간혹 타입 검사가 필요한 경우가 있다.

그 경우는 보통 아래처럼 짜기 나름.

(Language : javascript)
  1. function foo(nNumber) {
  2.   if (typeof nNumber != 'number') {
  3.     // throw new Error('숫자를 넣어주세요');
  4.     return;
  5.   }
  6.  
  7.   // ... 코드생략 ...
  8. }


이번에 짠 코드는 이런 코드타입 검사를 손쉽게 해주는 Function.prototype 의 확장기능이다.

(Language : javascript)
  1. /**
  2. * 함수 사용 타입 설정
  3. *
  4. * @author hooriza
  5. */
  6. Function.prototype.types = function() {
  7.  
  8.   var fpFunc = this;
  9.   var aTypes = arguments;
  10.  
  11.   var fpRet = function() {
  12.  
  13.     var r;
  14.  
  15.     if (!arguments.callee.typesMatch(arguments, false))
  16.       throw new Error('Illegal arguments');
  17.  
  18.     r = fpFunc.apply(this, arguments);
  19.     return r;
  20.  
  21.   };
  22.  
  23.   fpRet.typesMatch = function(aArgs, bStrict) {
  24.  
  25.     if (bStrict && aArgs.length != aTypes.length) return false;
  26.  
  27.     var oArg, oType;
  28.  
  29.     // 미리 정해진 타입의 갯수만큼 루프돌기
  30.     for (var i = 0, len = aTypes.length; i < len; i++) {
  31.  
  32.       oArg = aArgs[i];
  33.       oType = aTypes[i];
  34.  
  35.       // 정해진 타입에 따라 체크하는 방법이 다름
  36.       switch (oType) {
  37.       case String:
  38.         if (typeof oArg != 'string') return false;
  39.         break;
  40.  
  41.       case Number:
  42.         if (typeof oArg != 'number') return false;
  43.         break;
  44.  
  45.       case Object:
  46.         if (typeof oArg != 'object' && !(oArg instanceof Array)) return false;
  47.         break;
  48.  
  49.       default:
  50.         if (!(oArg instanceof oType)) return false;
  51.       }
  52.  
  53.     }
  54.  
  55.     return true;
  56.   };
  57.  
  58.   return fpRet;
  59.  
  60. };
  61.  

사용은 아래처럼 한다.

(Language : javascript)
  1. var foo = function(nNumber, sStr) {
  2.   // ...
  3. }.types(Number, String);
  4.  
  5. foo(100, 'hello'); // OK
  6. foo(100); // 예외발생
  7. foo('hello'); // 예외발생
  8. foo(100, 'hello', 'more'); // OK


뭐 이런 식.
이를 응용해서 메쏘드 오버로딩 기능을 만들 수 있다.
영양가 있는 포스팅인가요
(아무도 투표를 안 했어요) 0점
2008/04/08 16:12 2008/04/08 16:12