웹마스터 팁

작업을 하다 보면 팝업 레이어가 필요할 때가 있습니다
그 흔한 예는 제로보드 게시판에서 쓰이는 이름레이어 ( 작성자 누르면 뜨는 팝업레이어 )
가 가장 편하면서도 잘 쓰이는 예이구 위지윅에디터등을 만들때 혹은 기타 사항에서도
많이 쓰입니다

위와 같은 팝업레이어의 정식 명칭은 context 메뉴라 합니다

현재 쓰이는 방법은 두가지가 있습니다
첫째는 레이어 위에서 마우스가 벗어 났을 경우 팝업이 닫히는 경우
두번째는 문서 어디든지 클릭했을 때 닫히는 경우 -일반적인 웹브라우저의 콘텍스트 메뉴
어디까지나 응용하기 나름이지만
쓰이는 곳에 따라 아주 다양한 편리성을 주기도 합니다

좀더 그럴듯한 모양새를 내기 위해서는 세이클럽의 콘텍스트 메뉴(일반적인 브라우져에서 구현되는 콘텍스트 메뉴 혹은 기타 프로그램에 쓰이는 콘텍스트 메뉴 -오른쪽 마우스 클릭시 복사 붙여넣기등이 보이는 메뉴 )가 더 멋드러진 방법이겠지만
이 방법은 아직 내공이 부족한 관계로 모양새를 다잡기가 좀 힘이 듭니다
물론 익스에서만 동작하는 환경이라면 얼마든지 만들수 있지만
익스에서 지원되는 팝업메소드 하나가 말 그대로 익스 전용이라 타 브라우져에서는
되지를 않습니다

여기에 소개하는 콘텍스트 메뉴는 문서 안에서 팝업되는 일반적인 형태로
마리홈에 들어가 있는 것을 골자만 빼왔습니다
필요한 분은 응용해 쓰시기 바랍니다
-특히 게시판에서 사용하는 사용자 정보레이어로 적합할듯 합니다 -
사실 이걸 완전히 이해하고 응용하는데 일년 조금 넘게 걸린듯 합니다
제로보드 ,알지보드, 세이클럽 ,싸이미니홈 ,그누보드,네이버등 기타
여러군데 소스를 보면서 개념 파악하고 내것으로 만드는데 정말 힘이 들더군요

처음엔 엄청난 붙여넣기 신공으로 소스가 다소 지저분 했었는데 골자만 빼와서
간추렸기 때문에 개념 파악과 소스 가공이 한결 수월할 듯 합니다

먼저 테스트된 웹브라우저 환경은
네스케이프 8.1.2 ,  오페라 9.00 ,   화이어 폭스 1.5.0.7 ,  익스플러러 6.0.2900
등에서 테스트 되었습니다

익스등 기타 하위 버젼을 테스트 해보구 싶지만 여유가 되지 않아 테스트를 못했습니다
만약 구동이 되지 않는 웹브라우져 환경과 버젼이 있으면 코멘트에 남겨 주시면 고맙겠습니다


이하 소스
--------------------------------------------------------------------------------------



<script type="text/javascript">
/*

명칭    : 마리홈 이름 팝업 레이어
종류    : context menu
제작자 : 예뜨락

*/

// 사용자 설정 부분
Layer_popup_close=1;  //메뉴 닫는 방법 1(클릭으로 닫음 )또는 2(마우스 아웃으로 닫음 )


var satuas; //마우스가 팝업창 위에 놓여 있는지를 알기 위한 전역변수 선언
function popup_Layer(event,popup_name) {    //팝업레이어 생성
     var main,_tmpx,_tmpy,_marginx,_marginy;
     main = document.getElementById(popup_name);
     if(Layer_popup_close==2){
        satuas=1;//클릭으로 인한 닫힘 방지를 위해
     }
     main.style.display = '';//팝업 생성
     _tmpx = event.clientX+parseInt(main.offsetWidth);
     _tmpy = event.clientY+parseInt(main.offsetHeight);
     _marginx = document.body.clientWidth - _tmpx;
     _marginy = document.body.clientHeight - _tmpy;

     // 좌우 위치 지정
     if(_marginx < 0){//우측;
        main.style.left = event.clientX + document.body.scrollLeft + _marginx-2+"px";
     }
     else{
        main.style.left = event.clientX + document.body.scrollLeft-5+"px";
     }
     //높이 지정
     if(_marginy < 0){//아래부분;
        main.style.top = event.clientY + document.body.scrollTop + _marginy-5+"px";
     }  
     else{
        main.style.top = event.clientY + document.body.scrollTop-5+"px";
     }

}  


function mouse_anchor(type){ //마우스의 위치에 따른 팝업의 닫음을 결정
    if(type=="1"){
       satuas="1";
    }
    if(type=="0"){
       satuas="0";
    }
}



function Layer_popup_Off() { //팝업 닫음
  if(satuas=="0"){
     document.getElementById("popup_table").style.display = "none";
   }
   if(Layer_popup_close==2){
      satuas=null;
   }
}


function mouseout_close() {
    window.setTimeout('Layer_popup_Off()',850);
}

if(Layer_popup_close==1){
   document.onmousedown = Layer_popup_Off;//클릭으로 닫기
}

if(Layer_popup_close==2){
   document.onmouseover=mouseout_close;//레이어 벋어나면 닫기
}
</script>




<div id='popup_table' style="position:absolute; left:0px; top:0px; z-index:1;display:none;" onmouseover="mouse_anchor('1');" onmouseout="mouse_anchor('0');">
     <table border="1" width="200">
         <tr>
         <td height="217" valign="top">
          들어갈 내용
         </td>
         </tr>
     </table>
</div>










<table border="1" width="982">
    <tr>
        <td width="105" height="48" align="center" valign="middle">
         <a onclick="popup_Layer(event,'popup_table');" style="CURSOR: pointer;">팝업 생성 </a>
        </td>
        <td width="748" height="48" align="center" valign="middle">
         <a onclick="popup_Layer(event,'popup_table');" style="CURSOR: pointer;">팝업 생성 </a>
        </td>
        <td width="107" height="48" align="center" valign="middle">
         <a onclick="popup_Layer(event,'popup_table');" style="CURSOR: pointer;">팝업 생성 </a>
        </td>
    </tr>
    <tr>
        <td width="105" height="517" align="center" valign="middle">
         <a onclick="popup_Layer(event,'popup_table');" style="CURSOR: pointer;">팝업 생성 </a>
        </td>
        <td width="748" height="517" align="center" valign="middle">
         <a onclick="popup_Layer(event,'popup_table'+ ');" style="CURSOR: pointer;">팝업 생성 </a>
        </td>
        <td width="107" height="517" align="center" valign="middle">
         <a onclick="popup_Layer(event,'popup_table');" style="CURSOR: pointer;">팝업 생성 </a>
        </td>
    </tr>
    <tr>
        <td width="105" height="33" align="center" valign="middle">
         <a onclick="popup_Layer(event,'popup_table');" style="CURSOR: pointer;">팝업 생성 </a>
        </td>
        <td width="748" height="33" align="center" valign="middle">
         <a onclick="popup_Layer(event,'popup_table');" style="CURSOR: pointer;">팝업 생성 </a>
        </td>
        <td width="107" height="133" align="center" valign="middle">
         <a onclick="popup_Layer(event,'popup_table');" style="CURSOR: pointer;">팝업 생성 </a>
        </td>
    </tr>
</table>

--------------------------------------------------------------------------------------
이상 소스



설정할 수 있는 부분은 사용자 설정 부분입니다
1이면 문서 아무곳이나 마우스 클릭이 이뤄졌을 때 팝업된 레이어가 닫힙니다
2면 팝업레이어를 마우스가 벗어 났을때 약간의 지연된 시간후에 팝업이 닫혀서
보기에 좀더 매끄럽습니다



소스 설명을 합니다

마우스 이벤트가 일어나서 팝업이 되어야 할 부분에

onclick="popup_Layer(event,'popup_table');"
와 같이 자바스크립트 함수호출을 해줍니다

앞에
" event "
는 말 그대로 마우스 이벤트가 일어난 좌표점을 알아내는데 쓰이며 이 부분은
고침 없이 그대로 써야 합니다  익스같은 경우 이벤트를 써주지 않아도 알아내지만 다른 브라우져에서는 알아낼 길이 없으므로 써줘야 합니다

"popup_table"
는 팝업될 테이블의 이름입니다
이 부분은 사용환경에 맞게 이름을 고치시면 같이 고쳐주면 됩니다

우선 위의 onclick에 의한 함수 호출로 인해서 popup_Layer함수가 호출됩니다
함수 자체에 팝업될 테이블의 이름이 들어가 있기 때문에 알아서 팝업될 테이블이
정의 되구 display의 기능에 의해 감춰져 있던 부분이 보여지게 됩니다
제로보드 같은 경우엔 팝업될 위치를 찾은 다음 팝업이 되지만

위의 형태는 먼저 팝업이 된후 위치를 찾아 옮겨가게 됩니다
이렇게 한 이유는 팝업될 테이블의 높이와 넓이를 자동 산출하기 위한 parseInt(main.offsetWidth)와 parseInt(main.offsetHeight)를 쓰기 위함입니다
제로보드에서는 숨김 설정을 visibility='hidden' 으로 잡고 있습니다
이럴 경우 숨겨진 테이블의 높이와 넓이 만큼 공간 찾이를 하게됩니다
그러기에 숨김 설정을 높이와 공간을 찾이하지 않는 display = "none"을 사용합니다

그런데 display를 사용하게 되면 말 그대로 숨김 설정일 때는 테이블 자체가 이벤트가 일어나기
전에 표현되어져 있지 않기에 높이와 넓이를 자동산출할 수가 없습니다
그래서 먼저 디스플레이를 이용해서 보여준후 그후 얻어진 넓이와 높이값을 자동 산출해
다음에서 고려해야할 위치점을 찾는데 가감을 하게 되는겁니다

_tmpx  _tmpy 는  이벤트가 일어난 지점+ 팝업될 테이블의 넓이와 높이입니다
_marginx _marginy 는 활성화된 창의 높이와 넓이에서 위의 값을 뺀것입니다
즉 열려진 창의 높이 넓이에서 이벤트가일어난 곳(테이블이 높이 넓이를 합한 값)을 뺀 값입니다
만약에 스크롤이 있는 제일 오른쪽 부분에서 이벤트가 일어났다면
팝업레이어는 그 지점에서 팝업되기 때문에 문서를 넘어서서 하단에 스크롤이 생깁니다
그렇기 때문에   _marginx가 0보다 작다면이라는 이프문으로 상황을 맞춰주서
창의 넓이를 넘어서게 되면 활성화된 창안에서 팝업이 되게 조절해 줍니다
높이 부분도 마찬가지입니다

mouse_anchor(type) 이 함수는 팝업된 레이어 위에 마우스가 올려졌을 경우
사용하기 위한 하나의 장치입니다
팝업 닫힘을 1로 정했을 경우 팝업된 테이블에서 마우스 클릭이 일어나면 닫히게 되므로
팝업레이어 안에서의 닫힘방지(satuas=1 )를 위한 설정입니다

Layer_popup_Off() 이 함수에 의해 팝업된 레이어가 닫힙니다
위의 mouse_anchor(type) 이 팝업된 테이블에 마우스 오버와 아웃으로 함수 호출을 함으로써
현재의 상황을 기록하게 되구 만약 satuas=="0"이면 팝업이 닫힙니다
   if(Layer_popup_close==2){
      satuas=null;
   }
이 부분은 닫힘 설정을 2로 했을 경우( 문서의 아무곳이나 마우스가 이동되었을 때 닫힘 )
팝업이 되자마자 문서가 닫히는 경우를 방지하기 위한 부분입니다

mouseout_close() setTimeout함수를 이용해서 약간의 시간이 지연된 후 문서가 닫히게
합니다 바로 닫아도 상관없지만 약간의 지연후 닫힘은 좀더 부드러운 모양새를 갖게 합니다
이 부분은 닫힘 설정 2인 팝업테이블 마우스 아웃시 닫힐 때만 사용됩니다


if(Layer_popup_close==1){
   document.onmousedown = Layer_popup_Off;//클릭으로 닫기
}
처음 사용자 설정에 의한 부분에 의해서 팝업된 테이블의 닫힘 형태를 지정하게 됩니다
만약 1일 경우 문서의 아무곳이나 클릭이 이뤄졌을 때 Layer_popup_Off 함수를 호출하게
되구 Layer_popup_Off의 함수에 의해서 팝업이 닫힙니다


if(Layer_popup_close==2){
   document.onmouseover=mouseout_close;//레이어 벋어나면 닫기
}
2일 경우 mouseout_close함수를 호출하게 되구 mouseout_close함수 안에 있는
setTimeout함수를 이용 일정 시간 지연후 Layer_popup_Off 를 호출 팝업이 닫히게 됩니다





<div id='popup_table'+ ' style="position:absolute; left:0px; top:0px; z-index:1;display:none;" onmouseover="mouse_anchor('1');" onmouseout="mouse_anchor('0');">

팝업될 테이블의 div 안에 디스 플레이를 감춤 설정으로 하고 팝업테이블에 마우스 오버시
mouse_anchor('1');함수에 1을 넣어 닫힘 방지를 해줍니다 반대로 아웃시는 0을 넣어
닫을 수 있는 조건을 만들어 줍니다




괜챦다 싶으면 추천하는 센스를   ^______________^