IE에서만 발생하는 javascript 오류, 잘못된 인수입니다.

IE에서만 발생하는 javascript 오류입니다. 여러가지가 있는데, 그 오류들을 하나씩 정리 하겟습니다.

오류 : 잘못된 인수입니다.   코드를 보시면 아시겠지만, height는 음수값이 들어갈수 없기때문에 발생한 버그입니다. 하지만 IE에서만 이를 문제로 삼으며, 다른 브라우저 (FF,safary,chrome)에서는 음수값을 넣은 라인을 무시하여, 오류를 발생시키지는 않습니다.

이 문제는 오히려 IE가 javascript를 옳바르게 해석하는것 같네요. 라인을 무시하고 erorr를 뱉지 않으면 라인이 무시되었는지 알수가 없지요.

javascript replaceall의 방법에 따른 처리 속도 비교

필자가 아는 replaceall(string to string) 할 수 있는 방법은 아래 3가자로 추려 볼 수 있다. 아래 방법중 가장 빠른 처리 속도를 내는 방법은 무었을까? 브라우저 별로 조사해 보았다.

방법 1 ) split&join을 이용하는 방법

방법 2 ) 정규식을 이용한 방법

방법 3 ) 루프문을 이용한 방법


비교 방법은 5,655,000 개의 문자열을 두개의 다른 문자로 치환하는 방법으로 했다. 3가지 방법 모두를 IE6, Safari, FF3, Chrome 에서 조사 했다.

비교 결과 (단위,Millisecond)

비교 결과 (단위,Millisecond)


결과를 보면,

방법 3의 while 문을 이용한 방법은 모든 부라우저에서 테스트 할수 없었다. 모두 다운 되버렸다. FF의 firebug에서는 out of memory라는 오류 메시지를 뿌려주었다. 그러므로 쓰면 안되는 방법인것이다.

방법2의 정규식을 이용한 방법은 특이하게 IE에서만 좋은 성능을 발휘했다. IE외에 브라우저 특히 Safari 에서는 성능이 확연하게 떨어졌다. 파이어폭스만 그나마 나은 성능을 보여주고 있다.

방법1은 IE를 제외한 브라우저에서 모두 최고의 성능을 발휘했다. 특히 Chrome 의 경우는 다른 브라우저들에 비해 최고의 빠른 속도를 보여줬다. 

필자의 결론, 

위 각 브라우저의 성능을 테스트해본 결과 방법 1의 split&join을 이용하는 방법이 정규식을 이용한 치환방법보다 좋으나, IE의 서비스 점유율을 볼때 IE에서 최적의 성능을 보이는 방법 2의 정규식을 이용한 방법을 무시 할수는 없다.

그러므로, 개발자가 할수 있는 가장 좋은 방법은 IE때만 정규식을 치환하는 방법을 사용하고 나머지는 모두 split&join을 이용하는 방법으로 구현하는것이 최선의 방법이 아닐까 한다.
저작자 표시

url 파라메터를 javascript로 받기

url prameter 를 javascript 의 json (object)형태로 리턴한다. 간혹 url의 ?로 표시된 prameter를 파싱해서 사용해야할때가 있는데, 이경우 이 function을 이용하면된다. 아래 코드를 살펴보면 알겠지만, url파싱은 처음 호출시에만 하며 이후는 파싱된 object 만을 리턴한다. 이는 개발시 개발되어 테스트된 버전은 아니고, 그냥 생각나서 만들어 본 것으로 이후 버그 발견시 수정될수 있다.


사용방법은 아래와 같다. 존재하지 않는 파라메터를 콜 할경우엔 당연히 undifined를 리턴한다. 적절히 붙여 사용하면 유용하겠다.


Download

간단한 javascript 페이징 처리

아래와 같은 간단한 페이징 처리를 위한 소스다. ul 태그의 li 태그를 모두 display:none; 시킨 다음에 해당 페이지의 li 태그만 노출시키는 구조이다. 일단 마크없을 다 뿌리기때문에 10페이지 내의 간단한 페이징 처리에 용이하다.

사용자 삽입 이미지
소스코드


파일 다운로드

롤링 스크립트

대게 실시간 검색어를 표시하는 용도로 쓰이는 롤링 스크립트이다.
DIV 블럭으로 쌓은 UL 태그로 마크업을 작성한 후에 script 를 호출하면, 한줄로 롤링되는 전광판 형태로 구현이 가능하다.

자 일단 demo 페이지를 열어보자. (ctrl + 링크클릭)

Demo

사용방법

javascript 로 구현한 한글 자소 분리

java 로 짜여진 한글 자소 분리 소스를 발췌해서 javascript 로 바꾸었다. (찾아보니 javascript로된 소스는 없었다.)


사용 방법은 아래와 같다.
array 형태로 리턴되며, string 으로 변환하고 싶으면 join() 메서드를 이용하여 변환하면 된다.
hangulToJaso("한글자소분리");

위 코드 실행시, 리턴값은 아래와 같다.

ㅎ,ㅏ,ㄴ,ㄱ,ㅡ,ㄹ,ㅈ,ㅏ,ㅅ,ㅗ,ㅂ,ㅜ,ㄴ,ㄹ,ㅣ

소스 다운 받기



크로스 브라우징을 위한 function 코드 작성시 팁

예를 들자면, 현재 element의 상위 element를 호출한다고 한다면, ff의 경우는 parentNode 메서드를 이용해야하고 ie의 경우엔 parentElement 를 이용해야 한다. 이 경우 보통 코드를 아래와 같이 작성할것이다.


그러나 이 이코드의 단점은 해당 function 을 호출할때 마다 매번 if문을 거처야 한다는 것이다. 그래서 아래와 같이 바꾸면 해결할 수 있다.


위 코드는 처음 한번만 if문을 거친후에 자기 자신을 오버라이딩해서 그에 맞는 메서드를 리턴하도록 되어 있다.

javascript의 relaceAll 을 대체할만한 split 와 join

javascript 의 relaceAll 메서드는 정규식을 이용한 치환밖에 되지 않는다. 보통 문자 치환은 String대 String 으로 하는데, 정규식을 이용해야하는 relaseAll 메서드를 이용할수 없다. 그래서 여러 개발자들은 해당 문자가 있는지 여부를 조사하는 indexOf메서드를 사용해 루프문을 돌아 relace시키는 function 을 만들어 사용한다.

하지만, replaceAll을 대체할만한 아래 아주 기발한 아이디어 하나가 있다. 별다른 펑션을 만들지 않고도 아래 한줄이면 간단히 구현된다.

spilt이라는 메서드는 "OLDSTRING"이라는 구분자로 구분해 Array변수로 변환한다. 그리고 다시 join이라는 메서드로 "NEWSTRING"이라는 구분자를 생성해 하나의 String으로 변환한다.

참재미있지 아니한가~ :)

javascript로 브라우저 중앙에 레이어 뛰우기

아래는 브라우저 중앙에 div 구조로된 레이어를 뛰울때, 좌표값을 구하는 방법이다.


document.documentElement.clientWidth : 현재 브라우저의 document 넓이를 반환.

300 : 뛰울 레이어의 가로 사이즈.

document.documentElement.scrollLeft : 브라우저의 document의 스크롤이 이동한 넓이.


※ 전체 크기에서 레이어 사이즈를 뺀것을 반으로 나누고, 스크롤 한 길이만큼을 더해준것이다.

document.body 대신에 document.documentElement 를 사용한 이유는 DTD 타입을 선언한 페이지에서는 document.body 의 값을 내뱉지 못한다. body에서 얻지 못한값은  documentElement 로 얻을수 있다.

자바스크립트로 구현한 튤팁(Tooltip)

tag속성중에 title 속성을 그대로 javascript로 구현했다. 이유는 title 속성은 레이어가 뜨는데 약간의 델리이 타임이 있다. 그 딜레이 타임을 없애 달라는 요구에서다. 당연히 css나 속성값으로 딜레이타임을 조정할수 없어서 javascript로 구현했다.

/* 튤팁 박스
   by junsung park */
var bTooltip =
{
 tip_id : "btooltip",
 makeLayer : function (str)
 {  
  var tip_obj = document.getElementById(this.tip_id);
  if (tip_obj==undefined)
  {
   var tip = document.createElement("div");
   tip.id = this.tip_id;
   tip.style.backgroundColor= "#FFFFE1";
   tip.style.fontFamily= "돋움";
   tip.style.fontSize= "12px";
   tip.style.padding= "2px";
   tip.style.color= "#000";
   tip.style.border= "1px solid #000";
   tip.style.position= "absolute";
   tip.style.zIndex= "99999";
   tip.style.display= "none";
 
   document.body.appendChild(tip);
   tip.appendChild(document.createTextNode(str));
  }
 },
 moveLayer : function (e)
 {
  var xp = 0, yp = 0;
  if (document.all) 
  {
   xp = event.clientX + document.documentElement.scrollLeft;
   yp = event.clientY + document.documentElement.scrollTop;
  }else
  {
   xp = e.pageX;
   yp = e.pageY;
  }
  xp += 10;
  yp += 10;
  var tip_obj = document.getElementById(this.tip_id);
  if (tip_obj!=undefined)
  {
   tip_obj.style.top = yp + "px";
   tip_obj.style.left = xp + "px";
   tip_obj.style.display= "block";
  }
 },
 hiddenLyaer : function (e)
 {
  var to = e?e.relatedTarget:event.toElement;
  var to_id = null;  
  try
  {
   to_id = to.id;
  }
  catch (e)
  {
   to_id = null;
  }
  if (this.tip_id==to_id)
  return;
  if (document.all)
  {
   try
   {
    document.getElementById(this.tip_id).removeNode(true);
   }
   catch (e){}  
  }else
  {
   try
   {
    document.body.removeChild(document.getElementById(this.tip_id));
   }
   catch (e){}
  }
 },
 on : function (tg)
 {
  var str = tg.title;
  tg.title= "";
  bTooltip.makeLayer(str);
  tg.onmouseover = new Function("bTooltip.makeLayer('" + str + "')");
  tg.onmousemove = new Function("bTooltip.moveLayer(arguments[0])");
  tg.onmouseout = new Function("bTooltip.hiddenLyaer(arguments[0])");
 }
}

아래처럼 최대한 사용하기 편하게 되어 있다. 예외처리도 다 했다. 다만, 튤팁에 들어갈 내용에 따옴표가 들어간다면 서블릿단에서 이미 처리되어 뿌려줘야 겠다. 이부분은 어쩔수 없는 부분 같다.

사용법

<img src="http://cfs.flvs.daum.net/files/15/57/65/50/6122988/thumb.jpg" onmouseover="bTooltip.on(this)", title="어쩌고">
<a href="" onmouseover="bTooltip.on(this)" title="어쩌고">에이링크</a>

Ajax 호출시 JSON 으로 리턴 받기

Ajax 호출시 리턴 형태는 xml과 text가 있다. Data를 text로 받는데, 그 text 가 javascript object 배열(JSON)인 것이다. 이 JSON이라고 하는것이 배열 표현 방법의 하나인것이다.

Ajax가 호출하는 페이지의 결과값을 아래처럼 JSON형태로 출력하게 한다. 이때 주의 할점은 배열의 Object 명을 명시 하지 않는다.

{
 list :
 [
   {  
    img_url : ".../20070806_164500_ban_superstar.gif" ,
    link_url : "/superstar/Top.htm" ,
    link_target : "_self"
   },  
   {  
    img_url : ".../20070806_164500_ban_superstar.gif" ,
    link_url : "/superstar/Top.htm" ,
    link_target : "_self"
   }
 ]
}

responseText 로 리턴 받은 text값을 이제 javascript 의 object 배열로 변경 시켜주면된다. 변경시켜주는 방법에는 여러가지가 있는데, 필자는 아래와 같은 방법을 선호한다. 가장 간단한 방법인 듯 하다.

  var logobanner = null;  
  try {
   logobanner= eval('(' + obj + ')'); 
  }catch(e){}

responseText 로 리턴 받은 text 값의 parameter명이 obj라고 할때, 이 obj를  eval함수로 괄호와 함께 묶어주면 logobanner 이라는 이름으로 object배열이 선언 된다. try cath문으로 묶은 이유는 이 obj가 배열 object형태로 리턴되지 않는 예외경우를 대처하기 위한 구문이다.

실제 사용해보니 xml보다 간편했다. 장단점이 있지만, 굳이 xml을 사용하지 않아도 된다면 JSON형태로의 개발을 추천한다.

java냐 javascript이냐?

2000년 대학교 시절에 교수님이 이런말을 했었다.

"자바스크립트가 자바보다 더 발전할 수 있다."
나는 그때 당시 이 말을 그냥 흘려 들었다. 사실 난 자바스크립트는 쉽고, 자바는 어렵다 정도 그정도 지식에 머물러 있었기 때문이다. 하지만, 지금에서야 그말이 선겸지명이 있는 말이었고, 그 의미를 알 것 같다.

1. 개인의 PC 사양은 날이 갈수록 높아지고 있다. 그래서 PC에서 처리 할 수 있는 데이터의 양이 증가해도 문제가 없다는 것이다. 그것은 사업자가 서비스 프로그램의 데이터 처리를 PC에서 처리하면 효율적이다 라는 것과 같다. 그만큼 서버의 부담을 덜을 수 있지 않겠는가?

2. 예전에는 웹서비스의 중요한 기술적인 목표가, 속도나 안전성이었다고 한다면, 요즘은 UI(user interface)다. 디자인이 훌륭해야하고 사용성이 편리 해야 한다는것이다. 그것은 웹서비스뿐만이 아니라 IT전체적인 트렌드가 아닐까 한다.

3. 웹 기술에서  '동기식 통신' 방식의 페이지 리로드는 리소스 낭비다. 불필요한 페이지나 이미지가 리로드가 되지 않는 Ajax나, Flex등 진보한 클라이언트 기반 기술들이 쏟아지고 있다. 이런, UI를 해치지 않고 백단에서 Data처리를 하는 '비동기식 통신'방식은 요즘 웹기술의 트렌드라 할수 있다.

위의 근거로, 앞으로의 서비스 기술들은, javascript 와 flex 또는 실버라이트 같은 클라이언트 기술들의 싸움이 될것이다. 그에 따라 이 기술을 보유한 개발자가 곽광 받을것이다.

물론, java를 모르고 javascript를 잘 개발할 수 있다고 생각하지 않는다. javascript 기술을 보유한 개발자도 java 를 해야하지만, java개발자도  java만 하도록 그 트렌드가 내버려 두지 않을것 이다.

'Web > Client' 카테고리의 다른 글

자바스크립트로 구현한 튤팁(Tooltip)  (0) 2007/08/20
Ajax 호출시 JSON 으로 리턴 받기  (0) 2007/08/06
java냐 javascript이냐?  (0) 2007/07/31
javascript include 클래스  (0) 2007/02/23
iframe 과 같은 object 태그  (0) 2007/02/08
javascript 오류 보고에 대한 발상?  (0) 2007/02/06

javascript include 클래스

여러개의 클래스을 각각의 *.js 파일로 만들어 놓고, 사용되는 클래스들만 import하여 쓸수 있게 하는 class를 만들었다. (회사 지인의 아이디어이고 코드만 만들어봤다.)

/**
Include class blog.byuli.com
2007 03 23
*/
var Byuli= {
 default_path: null,
 setPath: function(url){
  this.default_path= url;
 },
 include: function()
 {
  var jsList= this.include.arguments;
  for ( var i=0; i<jsList.length; i++ )
  {
   var tag= "<script languge=\"javascript\"";
   tag+= "src=\"" + this.default_path + jsList[i] + ".js?ver=1.1\"></script>";
   document.write(tag);
  }
 }
}

보면 알겠지만, document.write로  코드를 써준다. 아래처럼 javascript로 element를 생성할수도 있지만 head가 onload된 상태에서만 동작하기때문에 쓸수가 없다.

   var el = document.createElement('script');
   el.src = url;
   document.getElementsByTagName('head')[0].appendChild(el);

위 클래스를 쓰는 방법은 아래와 같다. 먼저 javascript 파일이 존재하는 절대 경로를 입력하고 아래에 각 js파일을 인자로 넘기면 된다.

Byuli.setPath("/script/");
Byuli.include(
 "/byuli/util.js",
 "/byuli/ajax.js",
 "/byuli/string.js"
);

어려운 코드가 아니나, java처럼 class 단위로 분리한 javascript 파일을 효율적으로 import 할수 있는 방법으로써 좋은 아이디어라고 생각된다.

'Web > Client' 카테고리의 다른 글

자바스크립트로 구현한 튤팁(Tooltip)  (0) 2007/08/20
Ajax 호출시 JSON 으로 리턴 받기  (0) 2007/08/06
java냐 javascript이냐?  (0) 2007/07/31
javascript include 클래스  (0) 2007/02/23
iframe 과 같은 object 태그  (0) 2007/02/08
javascript 오류 보고에 대한 발상?  (0) 2007/02/06

javascript 오류 보고에 대한 발상?

서비스 되는 페이지에 javascript가 정상적으로 작동되고 있는지 알고 싶다. 그러기 위해서는 오류가 발생 했을때 서버쪽으로 request를 날려주는 방법밖에는 없다.

아래 코드는 오류가 발생 했을때 error로그를 변수에 담고, onload이벤트가 발생하면 서버로 오류 내용을 전달하는 방식이다.

/**
Error class by blog.byuli.com
2007 02 06
*/ 

var Error= {
 errerlog : "",
 onErrorEvent: function(e)
 {
  var page= location.href;
  Errer.errerlog+= "[errer] " + page +  " : " + e.toString() + "\n";
 },
 reportEerror : function ()
 {
  if(this.errerlog!="")
  {
   /* 오류 보고 request 하는 코드
    ex) hf.location.href= "./js_log.jsp?msg=" + this.errerlog;
   **/
   
  }
 }
}

아래는 onerror 이벤트가 발생시 호출될 메서드를 명시한다.

window.onerror= Error.onErrorEvent;

오류때마다 서버로 패킷을 던질경우, 서버부하를 초래 함으로 onload되었을때 일괄 전송 되도록 한다.

window.onload = function () {
 Error.reportEerror();
}

그닥 어려운 코드는 아니나, javascript 오류에 대해 그간 방관 했던것에 문제를 제기하고, 오류보고를 해야한다는 발상과 아이디어는 좋다고 생각된다.

'Web > Client' 카테고리의 다른 글

자바스크립트로 구현한 튤팁(Tooltip)  (0) 2007/08/20
Ajax 호출시 JSON 으로 리턴 받기  (0) 2007/08/06
java냐 javascript이냐?  (0) 2007/07/31
javascript include 클래스  (0) 2007/02/23
iframe 과 같은 object 태그  (0) 2007/02/08
javascript 오류 보고에 대한 발상?  (0) 2007/02/06