2008/06/29 02:09

웹 페이지에서 파일을 업로드 하기 위해 INPUT태그의 file을 사용합니다.
그런데 이 태그가 정말 스타일리쉬 하지 않아요.
예전에는 찾아보기 부분을 이미지로 바꾸기 위해 file태그를 숨기고 자바스크립트의 click 명령을 사용하였습니다.
이 방법이 처음엔 아주 잘되는 듯 하였으나 안 된다던 브라우져가 많이 나와 사라져 버렸지요.
이제 다른 방법을 사용하여 찾아보기를 없애고 이미지로 바꾸는 것을 알려드리겠습니다.
사실 이 방법은 많은 웹에디터에서 사용하는 방법입니다.
방법을 설명드리면...

div 태그 안에 file 태그를 위치시킵니다. div 태그안에 그냥 위치한다면..
<div style="width:300px;height:30px;border:solid 1px red;overflow:hidden;">
<input type="file" id="fileid" name="fileid"/>
</div>

만약에 div의 width값이 30px이라면 어떻게 될까요?

위처럼 file태그의 좌측 일부만 나오게 됩니다. 원래 file태그는 width 속성이 없기때문에 조정해도 소용없습니다.
하지만 IE에서는 width 속성도 적용이 됩니다. 표준을 따라야 되겠지요?
찾아보기 버튼을 누르기 위해서는 찾아보기 버튼이 div안에 나타나게 해야 되겠지요.

<div style="border-right: red 1px solid; border-top: red 1px solid; overflow: hidden; border-left: red 1px solid; width: 50px; border-bottom: red 1px solid; height: 30px;">
<div style="width:40px;height:20px;position: absolute;overflow: hidden; ">
<input id="fileid" style="font-size: 13px; right: 0px; position: absolute; top: 0px" type="file" name="fileid" />
</div>
</div>


이제 찾아보기 버튼 대신 이미지를 위치시켜야 하는데요. 이미지대신 일단 "찾기"라는 글씨를 사용하도록
하겠습니다. 그냥 안쪽 div 태그 옆에 <font id="fileid2" style="cursor: pointer">[찾기]</font> 넣습니다.

[찾기]

버튼 뒤에 가려져서 안보이는데요...이제 저 찾아보기 버튼을 사라지도록 하기 위해 opacity 값을 0으로
줍니다. 그러면 안쪽 div는 투명하게 처리가 됩니다. opacity 지정방법이 ie와 다른 브라우져가 서로
다릅니다. 그래서 두개의 코드는 style속성에 넣습니다.
FILTER: alpha(opacity=0); opacity: 0
[찾기]

이런 방법으로 찾아보기 버튼 대신 이미지를 사용할 수 있겠지요?
찾기 위에 마우스를 올려도 cursor이 변하지 않습니다. cursor:pointer; 스타일이 적용이 되면 좋으련만...
IE는 pointer가 적용이 됩니다.
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by mari
2008/03/21 08:12

얼마전에훈스님 블로그에서넥슨 사이트의 성능튜닝 - #3 HTTP 요청 줄이기라는 글을 보았습니다.


글 내용중에 HTTP요청을 줄이기 위한 하나의 방법으로 CSS Sprite 라는 기능을 설명하셨는데

그냥 보고 넘어가다가 태오사이트에서 어떤 분이 구글 메인페이지 하단의 아이콘들의 움직임을 궁금해 하시기에 저도 한번 테스트 해보기로 맘 먹고 코드를 분석하기 시작했습니다.


사용자 삽입 이미지


CSS Sprite 기능을 구글의 경우로 설명을 드리면 구글 하단에 쓰이는 이미지를 보면 하나의 통 이미지 입니다.


사용자 삽입 이미지


이 이미지를 해당 div의 background로 넣고 position의 값을 변경하면 원하는 부분의 이미지 즉 메일, 캘린더, 노트 부분만 나오게 하는 기능입니다.


그래서 IE Developer Toolbar를 이용하여 그 부분의 스타일과 HTML 코드를 보니 마우스를 올리는 순간
마우스가 가르키는 div style의 position값을 setInterval로 변경 해 주는 방법으로 보였습니다.


그 방법으로 간단하게 코딩을 해 봤습니다. 아래의 소스를 복사해서 테스트를 해 보세요.


이 기능을 모르셨던 분들은 언젠간 유용하게 사용하실 수 있겠죠? ^^;


<styletype="text/css">

  #gm{

     width:52px;

     height:37px;

     background:url(http://www.google.co.kr/ig/f/JB08UxZqEXw/intl/ALL_kr/svc_sprite_all.gif)no-repeat0px0px;

     cursor:pointer;

   }

</style>

<scripttype="text/javascript">

<!--

  varnum=0;

  varinterVal;

  functionstartSprite(bol)

   {

      num = (bol ? 0 : -312);

      interVal = setInterval("_sprite("+ bol +")",70);

   }

  function_sprite(bol)

   {

      document.getElementById("gm").style.backgroundPosition = num +"px 0px";

      num = (bol ? num-52 : num+52);

     if(num < -312 || num > 0)

         clearInterval(interVal);

   }

//-->

</script>

<divid="gm"onmouseover="startSprite(true);"onmouseout="startSprite(false);">

</div>

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by mari
2008/03/20 00:39

파이어폭스오페라로 웹사이트를 이용하다 보면 레이어가 플래시 뒤로 숨어버리는 경우를 종종 발견합니다.

물론 IE에서는 제대로 표현이 됩니다.
레이어의 z-index속성 값을 높여도 소용 없고... 평소에 IE에서 잘 되니 문제 없이 그냥 넘겨버린 제가 미워요;;
앞으로는 제대로 테스트를 해 봐야 겠습니다.

 

해결 방법은

 

object 태그에는
<param name="wmode" value="transparent">

 

embed 태그에는
<embed wmode="transparent" ...

 

이렇게 추가를 하면 해결 됩니다.

 

앞으로는windowless와 windowed 문제가 없어지길 바랍니다.

사실 이 글은 나중에 혹시 잊어 버릴까 염려되어 간단하게 남겨 봅니다. ㅋ

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by mari
2008/03/19 00:04

요즘 들어 JavaScript의 문법들이 다양하고 어렵다는 걸 알게 됩니다.
아무래도 여러 자바스크립트 라이브러리나 ajax의 활성화등이 이유가 아닌가 싶습니다.
저도 개발하면서 조금이라도 복잡한 로직을 요하는 기능이 있다면 가차 없이 함수로 따로 만들고 그것을 불러서 사용합니다.

예를 들면, 아래의 함수는 select박스(DropDownList)의 모든 option을 제거하는 함수입니다.
clearOptions =function(_arg)
{
 var_obj =document.getElementById(_arg);
 if(typeof(_obj) != "undefined")
 {
  while(_obj.options.length> 0)
  {
   _obj.remove(0);
   if(_obj.options.length== 0)
    break;
  }
 }
};

뭐... JavaScript에서 저런 기능을 아예 지원해주면 좋겠지만 있을 법 한데 분명 있을 것 같은데 없는
그런 기능들이 있습니다. 바로 trim, ltrim, rtrim 등...
다른 언어로 개발해 보신 분들이라면 아시겠지만 좌,우 공백을 제거해주는 함수죠.
왜... 없을까요? 물론 정규식을 이용하여 replace함수를 이용하면 가능해 집니다.
또, 이 replace함수도 문제 입니다. 보통 다른 언어에서는 replace(찾을값, 바꿀값) 이렇게 하면 해당 문자열에
있는 모든 값들을 찾아서 값을 변경하는데 JavaScript의 replace함수는 그렇지 않습니다.
varstr = "abcabac";
alert(str.replace("a","A");

이렇게 하면 맨 처음 나오는 a만 A로 변경이 됩니다. 즉, 처음 나오는 찾고자 하는 값을 바꾸고 끝입니다.
그래서 저 replace함수도 정규식을 사용해서 이용하는 경우가 많습니다.

str.replace(/a/g,"A");

a라는 값을 처음부터 끝까지 찾아서 A로 바꿔라 하는 명령입니다. 정규식은 /패턴/flag 형식으로 사용하는데요.
/g라고 하면 패턴을 전역 검색을 하라는 의미가 됩니다.
http://koxo.com/lang/js/object/RegularExpression.html요기를 참고 해 보세요.

자.. 이제 원하는대로 됐습니다. 그러나 문제인 것이 매번 replace를 쓸 때 마다 정규식을 계속 타이핑을 해야 합니다.
위에서 예제로 제시했던 clearOptions처럼 함수로 만들어서 사용해도 되지만 JavaScript의 prototype을 이용하면
JavaScript의 기본객체의 함수나 속성을 정의하거나 재정의 할 수 있습니다.

String은 JavaScript의 기본객체이므로 저 replace함수를 prototype을 통해 재정의 할 수 있지만
그렇게 할 수 없지요...왜냐 아래의 예문을 보세요.


String.prototype.replace = function(_findValue, _replaceValue) {
 return this.replace(new RegExp(_findValue,"g"), _replaceValue);
};

왜 그럴까요?? 실행을 해보시고 생각을 해 보세요.

결과를 말씀드리면 String객체의 replace함수를 재정의하기가 어렵습니다. 재정의하는게 아니라 replaceAll이란
이름으로 새로운 정의를 하여 사용하면 문제가 없겠죠..

아래는 위에서 설명한 방식으로 생각하면 나올 수 있는 trim, rtrim, ltrim 함수 입니다.

String.prototype.trim = function() {
    return this.replace(/(^ *)|( *$)/g, "");
};
String.prototype.ltrim = function() {
    return this.replace(/(^ *)/g, "");
};
String.prototype.rtrim = function() {
    return this.replace(/( *$)/g, "");
};

 

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by mari
2007/07/19 21:54

HTML Element의 위치 정보를 알아내는 속성이 여러가지가 있는데 이 속성들이 브라우져에서 어떤 위치인지 혹은 어디부터 어디까지인지

종종 헷갈리는 경우가 있는데요 아래의 내용을 보면 쉽게 이해할 수 있을 것 같아 MSND 내용을 옮겨 봅니다.

 

출처 -MSDN

 

Measuring Element Dimension and Location
 

The following section is designed to help Web authors understand how to access the dimension and location of elements on the page through the Dynamic HTML (DHTML) Object Model.

Understanding Properties That Measure Element Dimension and Location

The diagrams illustrated in this document represent different DHTML Object Model properties for the same page. The sample page contains adivelement that is relatively positioned on the page. Since theoverflowattribute of thedivhas been set toscrolland it contains more content than can be displayed within its limited client area, scroll bars are displayed.

사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by mari
2007/07/02 23:31

웹 표준이 점점 당연시 되면서 이제는 IE로만 테스트하는 것이 아니라 여러 브라우져로 테스트를 하게 됩니다.

이전에는 웹 표준이 있음에도 불구하고 대부분 IE에서만 동작하면 개발이 잘 된 것으로 판단을 했지요...

물론 지금도 기업에서 사용하는 웹 애플리케이션의 경우 대부분 IE에서 동작하면 만사 OK입니다.

저도 대부분 아니...100% 개발 애플리케이션이 기업용이라 IE에서만 동작하면 개발하는데 지장이 없지만 웹 개발자의 가다가 있지요...

IE와 더불어 사용자가 늘고 있는 Firefox나 Opera같은 브라우져로 나름 테스트하며 여러 브라우져에서 동작하도록 개발하고 있습니다.

safari는 아직 버그등의 문제, 한글화 문제등으로 제외했습니다.(사실...개발자 최대의 적~!! 귀차니즘 때문이겠죠;;)


개발을 하다 보면 자바스크립트를 많이 사용하는데요. Table이나 계층적인 Element구조에서 최상위 Element부터 하위 Element까지

탐색하고 각 Element의 정보를 얻거나 다른 작업을 해야 하는 경우가 자주 발생합니다.

Table 같은 경우는 document.getElementById(TableElementID).rows나 cells로 정보를 쉽게 구할 수 있지만 Table Element가 아닌

다른 Element 혹은 Table Element를 rows나 cells가 아닌 childNodes로 제어를 해야 한다고 치면...

해당 Element의 childeNodes의 length를 구하고 그만큼 반복하며 제어를 하겠지요...

그런데 이상하게도 각 브라우져마다 childNodes의 length가 다릅니다.

어찌 된 일인지 어떤 것이 표준에 맞게 Dom구조로 파싱을 하는 것 인지 모르겠네요...

IE에서는 무조건 하위 노드(element)갯수가 childNodes의 length가 됩니다.

아래의 소스에서 div1의 하위 노드 갯수는 2가 됩니다. 이것이 흔히 생각하는 것이 되겠지요..저만 그런가 ㅡㅡ;;

하지만 Firefox에서는 결과가 다릅니다. div1의 하위 노드 갯수는 5가 나옵니다. 왜 그런지 Firefox의 Dom Inspector로 살펴보니

소스상에서 각 노드(element)마다 공백/엔터가 존재하면 이것을 하나의 element인 Text Element로 간주하게 됩니다.

이 TextElement는 element에 있는 텍스트 값이 됩니다.

<div>가나다</div> 여기서 "가나다"가 Text Element가 되는 것이며 저 div Element의 하위 노드가 되는 것이지요..

IE와 Firefox에서 Dom구조를 보여주는 툴을 이용하여 아래의 소스를 본 화면 입니다.

사용자 삽입 이미지

사용자 삽입 이미지

그나마 IE와 Firefox는 양반입니다. IE는 노드사이의 공백/엔터는 무시합니다. Firefox는 노드사이의 공백/엔터도 하나의 element로 간주합니다. 그러나 Opera의 경우 아래 소스에서 div는 노드사이의 공백/엔터는 하나의 element인데 Table의 경우 무시합니다.

어떤 브라우져가 맞는 것 일까요?


<!DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<htmlxmlns="http://www.w3.org/1999/xhtml">

 <head>

  <title>New Document</title>

 </head>


 <body>

  <divid="div1">

     <divid="div2">

         div2

     </div>

     <divid="div3">

         div3

     </div>

  </div>       

  <tableid="table1"cellpadding="5"cellspacing="1"border="1">

       <tr>

           <tdstyle="background-color:Gray;color:White;">TD1</td>

           <tdstyle="background-color:Gray;color:White;">TD2</td>

       </tr>

  </table>

 </body>

</html>

<scripttype="text/javascript">

<!--

   alert("div1의 자식노드 갯수 : "+ document.getElementById("div1").childNodes.length);

   alert("table1의 자식노드 갯수 : "+ document.getElementById("table1").childNodes.length);

   alert("table1의 Row 갯수 : "+ document.getElementById("table1").rows.length);

//-->

</script>


 

 
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by mari