'03.HTML 4.X, HTML5, XML.../HTML/Css/Script'에 해당되는 글 196건

  1. 2009.09.15 javascript 익명함수 예제
  2. 2009.09.08 유용한 자바스크립트 하나
  3. 2009.09.01 jQuery mootools 충돌 해결
  4. 2009.08.31 자바스크립트 휴대폰번호 검증 ( 간단한 정규식 표현)
  5. 2009.08.28 html 즐겨찾기 추가
  6. 2009.08.26 document.all 을 쓰지 맙시다!
  7. 2009.08.26 location.href 에서 target=_blank 효과 사용
  8. 2009.08.26 firefox 에서 form submit 이 안될경우
  9. 2009.08.26 파이어폭스에서 javascript 시 this.value 가 않먹을때
  10. 2009.07.30 테이블에 스크롤바 생성하기 1
  11. 2009.07.24 좀 괜찮은 팁. 전송버튼 두번클릭 방지.
  12. 2009.07.02 Web Hacking 3탄 구멍난 자바스크립트
  13. 2009.07.02 쿠키취야점을 이용한 해킹...
  14. 2009.07.01 마우스 오버시 말풍선
  15. 2009.06.27 [javascript] 입력 문자 한글 체크
  16. 2009.06.20 javascript get 방식으로 데이터 받기
  17. 2009.06.20 JavaScript] [브라우저]브라우저명을 정확히 알아내기
  18. 2009.06.18 html textarea 에서 엔터 값을 자동 줄바꿈으로 처리하는 방법
  19. 2009.05.13 css 버튼 모음
  20. 2009.04.25 문자열 자바스크립트에서 금액표시하기 JavaScript
  21. 2009.04.25 자주쓰는 자바스크립트 함수
  22. 2009.04.24 javascript : CalendarView
  23. 2009.04.21 HTTP 1.1 통신규약
  24. 2009.04.18 javascript print
  25. 2009.04.16 네이버 콤보스타일 셀렉트 메뉴
  26. 2009.04.16 엑셀처럼 리사이즈 되는 td 만들기 table
  27. 2009.04.16 네비게이션 메뉴바 만들기
  28. 2009.04.13 달력 스크립트
  29. 2009.04.10 접근성을 해치지 않는 자바스크립트의 사용
  30. 2009.04.07 rownum 으로 범위지정을 해주고 싶을 때
반응형

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <TITLE> New Document </TITLE>
  <META NAME="Generator" CONTENT="EditPlus">
  <META NAME="Author" CONTENT="">
  <META NAME="Keywords" CONTENT="">
  <META NAME="Description" CONTENT="">
  <SCRIPT LANGUAGE="JavaScript">
  <!--
 var sayHi = new Function("to","alert('hi'+to);");

 function test(imsi){
  sayHi(imsi);
 }
  //-->
  </SCRIPT>
 </HEAD>

 <BODY>
  <input type="button" value="123" onClick="test('바보');"/>
 

 </BODY>
</HTML>

Posted by 1010
반응형

출처 : http://okjsp.pe.kr/seq/138831

prototype.js를 보다가 유용한 기능이 있어서 글을 올립니다.

보통 자바스크립트로 아래와 같은 코드를 사용할 일이 종종있는데요.

//----------------------------------------

    var str = "히히";
    if (str == "하하" || str == "호호" || str == "후후" || str == "히히" ||  str == "헤헤") {
        alert("기존 방식!");
    }


//----------------------------------------

위의 코드를 아래처럼 줄일 수 있습니다.

//----------------------------------------

    var str = "히히";
    if (["하하", "호호", "후후", "히히", "헤헤"].include(str)) {
        alert("include 사용시!");
    }

//----------------------------------------


아래 함수를 공통.js 같은곳에 넣으셔서 사용하시면 됩니다.


<script>

    Array.prototype.include = function () {
        for (var index in this) {
            if (this[index] == arguments[0]) {
                return true;
            }
        }
        return false;
    }

</script>


예제코딩된 html 첨부합니다.

감사합니다.

Posted by 1010
반응형
 jQuery  mootools 충돌 해결

마지막으로 기억할 사항은 jQuery나 다른 자바스크립트 라이브러리를 사용할 때, 서로 어울려 동작하지 않을 경우가 있다는 사실이다. 다시 말해, 라이브러리 두 개 이상을 사용할 경우, 라이브러리 둘 이상에서 변수 "$"를 사용한다면 엔진은 어떤 라이브러리가 "$" 호출을 참조해야 할지 모르는 사태가 벌어진다. 이런 현상을 설명하는 완벽한 예제는 protyotype.js에 내장된 CakePHP 라이브러리다. 이런 라이브러리를 사용하는 페이지에서 수정없이 jQuery를 호출하려고 시도하면 오류가 발생한다. 이런 문제를 해결하기 위해 jQuery는 "$" 변수를 다른 변수로 사상하는 방법을 제공한다. 다음 예를 살펴보자.


Listing 4. jQuery 충돌 해결
j$ = jQuery.noConflict();
j$("div").addClass("a");


-------실무예제--------

j$ = jQuery.noConflict();
//j$("div").addClass("a");

// �α�
function inFocus(i) {
 (i).style.background='none';
}
function outFocus(i) {
}
// Jquery GNB
 j$(function() {
  j$("#inquiry").tabs();
  j$("#counsel").tabs();
 });

Posted by 1010
반응형

그냥 간단하게 휴대폰 번호 검증하는 스크립트 하나 올려봅니다.

정규식을 너무 않쓰고 있는거 같아서...


// 휴대폰번호를 입력시 올바른 휴대폰 번호인지 체크 
  if(f.hphone1.value != "") {
   var rgEx = /(01[016789])[-](\d{4}|\d{3})[-]\d{4}$/g; 
   var strValue = f.hphone1.value+"-"+f.hphone2.value+"-"+f.hphone3.value;
   var chkFlg = rgEx.test(strValue);  
   if(!chkFlg){
    alert("올바른 휴대폰번호가 아닙니다.");
    f.uuser.focus();
    return false;
   }
  }
 

var rgEx = /[01](0|1|6|7|8|9)[-](\d{4}|\d{3})[-]\d{4}$/g;

굳이 풀이 하자면 [01] <- 01로 시작하고
 (0|1|6|7|8|9) <- 0 이거나 1이거나....
[-] <- - (하이폰)이고
(\d{4}|\d{3}) <- \d(숫자로 시작하는 자리수가 {4} 4자리이거나 3자리 이고
[-] < -(하이폰) 이고
\d{4} <- 숫자로 시작하는 자릿수가 4자리이여야 한다.


나머지는 뭐 설명할 필요 없겠죠....


 // 휴대폰번호 입력시 올바른 휴대폰 번호인지 체크  
  if(f.hphone1.value != "" || f.hphone2.value != "" || f.hphone3.value != "") {
   var rgEx = /[01](0|1|6|7|8|9)[-](\d{4}|\d{3})[-]\d{4}$/g; 
   var strValue = f.hphone1.value+"-"+f.hphone2.value+"-"+f.hphone3.value;
   var chkFlg = rgEx.test(strValue);   
   alert(chkFlg);
   if(!chkFlg){
    alert("올바른 휴대폰번호가 아닙니다.");
    f.hphone1.focus(); 
    return false;
   }
  }


Posted by 1010
반응형
<a href="javascript:window.external.AddFavorite('http://www.myeclipseide.com', 'J2EE IDE homepage')">Add to Favorites</a>
Posted by 1010
반응형
출처 : http://www.spoork.net/153

document.all 을 쓰지 맙시다!
document.all 을 안쓰는 것 많으로도 표준을 따르는 웹 페이지 디자인에 매우 큰 걸음을 내 딛는 것입니다.
단지 저 document.all 때문에 다른 안되는 홈페이지가 부지기수 입니다.
요즘에는 FireFox가 어쩔수 없이 지원해서 되긴합니다만, 그렇다고 그게 좋다는 것을 의미하지는 않습니다. FireFox 1.0 은 document.all 을 지원하긴 하지만 if 문으로 체크하면 지원하지 않는다고 표시합니다.
다음은 한국모질라 포럼에 올라온 글입니다.

<< 내용숨기기 >>



http://forums.mozilla.or.kr/viewtopic.php?t=580&highlight=document.all

웹사이트에서 버튼이 동작 되지 않는 경우 대부분 Javascript의 객체를 MSDOM에서 사용하는 document.all을 사용하기 때문에 그렇습니다. 자바스크립트 디버거를 통해 소스를 보았을 때 document.all 이 들어 있는 경우 document.all 대신 W3C DOM의 오브젝트 판별법을 사용하도록 웹사이트 관리자에게 알려주셔야 합니다.

document.all[objectID] -> document.getElementById("objectID")

혹시 거기에서 MS IE4 때문에 getElementById를 쓸 수 없다고 하면 getObject()를 아래처럼 정의한 후에 쓸 수 있다고 알려 주십시오.

function getObject(objectId) {
// checkW3C DOM, then MSIE 4, then NN 4.
//
if(document.getElementById && document.getElementById(objectId)) {
return document.getElementById(objectId);
}
else if (document.all && document.all(objectId)) {
return document.all(objectId);
}
else if (document.layers && document.layers[objectId]) {
return document.layers[objectId];
} else {
return false;
}
}

즉, 다음처럼 하면 됩니다.

getObject('sendbn').style.visibility="hidden";

getObject는 http://www.orient-express.com/js/layers.inc 에 있습니다.

혹은 다음에 있는 'x library'를 쓰는 것도 좋은 방법입니다. http://www.cross-browser.com
Posted by 1010
반응형

출처 : http://blog.daum.net/computercode/8281294

자바스크립트로 location.href 로 이동해야 하는 경우가 있는데 이때 새창을 띄워서 쓰는 방법이 필요한 경우가 있다. 그냥 프레임이나 브라우저 창간의 계층구조인 경우에는

opener.location!.href = "http://...";

혹은

frame1.location!.href = "http://...";

이런 방법으로 사용하면 된다.
이런것도 아니고 무조건 새창을 열고 띄우는 경우는 다음과 같다.

var openNewWindow = window.open("about:blank");
openNewWindow.
location.href = "http://...";


Posted by 1010
반응형

-----------test.jsp---------------------

<form name="frmHidden" method="post" action="counselingfaq_list.jsp">
 <input type="hidden" name="seq" value="<%=Seq%>">
 <input type="hidden" name="pageNo" value="<%=pageNo%>">
 <input type="hidden" name="pageVol" value="<%=pageVol%>">
</form>


<script>
alert('정상적으로 삭제  되었습니다.');
document.frmHidden.submit();
</script>


----------------------------------


test.jsp 페이지가 EE에서는 잘 이동하는데 FF 에서는 안먹는다...

페이지에 구조가 만들어 지지 않아서 스크립트가 제대로 동작 하지 못한다.

다시 한번 웹표준을....맞춰야 겠다는 생각이 든다.

<html>

<head></head>

<body>

</body>

</html>

 

Posted by 1010
반응형
파이어폭스에서 javascript 시 this.value 가 않먹을때

onClick ="search(this.value)";

로 하면 EF 에서는 잘 먹는데 FF 에서는 잘 먹지 않는데..

this.value 는 document.all 로 찾는다

document.all 는 ms dom api 이기 때문에 FF에서는 지원하지 않고 표준도 아니기 때문에...

document.getElementsByName 형식으로 찾아줘야 함.

글구 return false 도 써주삼... 이미지 형식에 onClick 이벤트를 줄때..


 onclick="search(document.getElementsByName('sWord').item(0).value,1);return false;"

Posted by 1010
반응형
출처 : http://www.imgwizard.com/?mid=tip&category=361&page=1&document_srl=369

<HTML>
<HEAD>
<Title>테이블에 스크롤바 생성하기</Title>

<style type="text/css">
<!--
body,td {font-family:"굴림"; font-size: 9pt}
#scrollbox {width:400; height:100; overflow:auto; padding:10px; border:1; border-style:solid; border-color:black}
-->
</style>

</HEAD>

<BODY BGCOLOR="#FFFFFF">
<table width=400 height=100 border="0" cellspacing="0" cellpadding="0">
<tr>
  <td>
  <DIV id="scrollbox">
  <b>이수영 -천년이라도</b><p>
      하루종일 난 그대위해 기도했어요.<br>
      마음이 너무 아파할것같아<br>
      아무일도 아닌걸요 힘들어 말아요<br>
      시간이 조금 필요할 뿐이죠<br>
      누구도 그댈 대신할수는 없지만<br>
      이젠 추억으로 만족하겠죠<br>
      조금 걱정이 되네요<br>
      그대가 없는 나의 삷이란건 생각조차<br>
      해본적 없으니까<br>
      그대가 가면 나는 여기에<br>
      천년이라도 기다릴게요<br>
      살다가 한번 생각이나면<br>
      힘들어말고 찾아오세요<br>
      한번도 그대를 원망하지 않아요<br>
      그대에겐 부족한 나였으니<br>
      부디 멀리나마 행복하기를 바래요<br>
      이제다시는 볼수 없을테니..<br>
  </DIV>
  </td>
</tr>
</table>
</BODY>
</HTML>


===========
☞ div 태그에 id를 줘서 스타일시트를 적용해도되고, div 태그내에 직접 <DIV style="..."> 써줘도 되고...
☞ 넷스케이프에서 스크롤은 적용 안되지만 내용은 보임
☞ overflow=auto    : 내용길이에따라 스크롤바 생김
☞ overflow=scroll  : 무조건 스크롤바 생김
Posted by 1010
반응형

출처 : http://www.hof.pe.kr/wp/archives/322/

좀 괜찮은 팁. 전송버튼 두번클릭 방지.

글내용작성하고 전송버튼 누를때 수전증 또는 머리와 따로 노는 손가락때문에 타닥~ 두번 클릭이 되는 수가 있습니다. 또는 전송버튼 누르고 전송 완료페이지로 넘어갈때 시간이 걸릴때 "혹시 안눌렀나?" 하고 또한번 누르는 수가 있는데… 이것을 방지하기 위한 팁~~ (특히 설치형 블로그중에 코멘트삭제기능이 없는 경우에 적용하면 대략 괜찮음)

(누르면 없어집니다. 가만히 기다려도 안나옵니다.-_-)
소스 : <input type="submit" onClick="this.style.visibility='hidden'" value="눌러요~ 잇힝!" /> (누르면 비활성화 되어 다시 누를수 없게 됩니다.)
소스 : <input type=submit onclick="this.disabled=true" value="이것도 눌러요~ 잇힝!">
Posted by 1010
반응형

Web Hacking 1탄 SQL Injection

Web Hacking 2탄 파일조작

Web Hacking 3탄 구멍난 자바스크립트



1. 시작하기

여러분들은 사용자가 입력한 값에대해 어느정도 검증을 하는지요?

사용자 값을 이것저것 따지고 여러가지 유효성을 체크할려면 아주 귀찮은 일이 아닐수 없습니다

그중에 하나가 웹브라우져에서 실행되는 자바스크립트로 체크하는 방법이 있는데 비지니스 로직이 조금 복잡할때는 자바스크립트로 도배를 하는 경우도 종종 있지요

유효성 검증하는일 저도 정~~말 싫어합니다 하지만 해야 합니다 ㅠ.ㅠ

그럼 어디까지 그 유효성을 체크해야 할까요? 자바스크립트로만 체크하면 될까요?


처음 웹프로그래밍을 할때는 저도 자바스크립트로만 입력값을 검증하면 되는줄 알았습니다

한마디로 몰랐죠

하지만 이제는 알기때문에 자바스크립트뿐만 아니라 서버쪽에서도 동일하게 체크해 주어야 합니다

사용자가 입력한 값이 얼마나 무서운지는 앞의 1탄, 2탄의 강좌를 통해 어느정도는 감을 잡으셨으리라 생각하고 이번 강좌에서는 왜 서버쪽에서도 체크해야 하는지!에 대해 간략히 알아보겠습니다



2. 자바스크립트 체크


입력값의 자리수가 13자리인지 체크하여 맞으면 submit을 만약 그렇지 않다면 정상적인 입력값을 요구하는 입력갑검사 로직이 있다고 가정하겠습니다 그리고 서버쪽에서는 꼭 13자리가 넘어와야 정상적인 처리를 할수 있다고 하겠습니다

그럼 아래와 같은 간단한 코드가 나올겁니다


http://www.jakartaproject.com/html/input.html

<script>

/* 입력한값이 13자리인지 체크 후 전송 */

function validateValue() {
    var obj = document.f.register_no;
    if (obj.value.length != 13) {
        alert('주민번호 정상적으로 입력하세요');
        return false;
    }
}

</script>


<form name=f method=post action=process.jsp onsubmit="return validateValue()">
주민번호 <input type=text name=register_no> <input type=submit name=btn value=submit>
</form>


 실제 웹 브라우져에서 보면 아래와 같습니다

"33" 이라는 두자리 수만 입력하니 역시나 재입력을 요구하는 alert창이 떳습니다 (가끔 깜짝깜짝 놀라죠 -,-)




그럼 정상적으로 "1111111111111" 의 입력값 13자리를 입력해 보겠습니다




 

그리고 이 값은 process.jsp 라는곳에서 파라미터로 받아 아래와 같이 처리합니다

코드는 간단하게 그 입력값과 레퍼러 값을 보여주겠습니다


http://www.jakartaproject.com/html/process.jsp

<%@ page contentType="text/html; charset=euc-kr" %>


<%
String register_no = request.getParameter("register_no");
%>


헤더정보 <%=request.getHeader("referer")%><br><br>
주민번호 <%=register_no%>


request.getHeader("referer")는 헤더정보에서 referer값을 가져오는 함수로, 이전 페이지 주소값을 가져옵니다

그럼 화면은 아래와 같이 나옵니다


자 정상적으로 처리되었습니다



3. 자바 스크립트 우회

그럼 이제부터 자바스크립트로 입력값의 자리수 체크로직을 피해가는 방법을 알아봅시다

어떤 방법이 있을까요?


URL로 접근

입력값이 몇가지 되지 않는다면 아래 방법이 가장 편하겠군요

즉 브라우져 주소창에다 직접 입력 합니다


http://www.jakartaproject.com/html/process.jsp?register_no=2222

아래와 같은 화면이 나올겁니다

메쏘드정보 (request.getMethod())를 찍어보니 GET 이 나오는군요!

그렇다면 이같은 직접 URL값을 막기위해 간단히 POST만 허용하는 로직을 추가해 버립시다


http://www.jakartaproject.com/html/process.jsp

<%@ page contentType="text/html; charset=euc-kr" %>


<%
if (!"POST".equals(request.getMethod())
   return;

String register_no = request.getParameter("register_no");
%>


헤더정보 <%=request.getHeader("referer")%><br><br>
주민번호 <%=register_no%>

이러면 괜찮겠지 흐흐.. 라고만끝나면 안됩니다


로컬파일로 접근

①번의 방법은 GET방식때문에 막혔습니다 그러면 자바스크립트를 우회하면서 POST방식으로 보내는 방법은 없을까요? 물론 있습니다

웹브라우져는 "소스보기" 라는 좋은 메뉴가 있습니다 있는건 적극 활용합시다 ㅎㅎ

소스보기한 후 바탕화면에 저장하여 약간 손을 보았습니다

즉 입력값을 체크하는 자바스크립트를 무력화 시키면서, action을 수정해 주었습니다


C:\Documents and Settings\Administrator\바탕 화면\client.html

<script>

/* 입력한값이 13자리인지 체크 후 전송 */

function validateValue() {

    return true;
}

</script>


<form name=f method=post action="http://www.jakartaproject.com/html/process.jsp" onsubmit="return validateValue()">
주민번호 <input type=text name=register_no> <input type=submit name=btn value=submit>
</form>



웹화면은 다음과 같겠죠


"submit"버튼을 클릭합니다 ^^


역시나 자바스크립트를 거치지 않고 process.jsp에 13자리수가 아닌 "22"값을 무난히 보냈습니다



그럼 서버쪽에서는 "어이쿠 이런 헤더정보도 체크해야 겠군" 하고 다음 코드를 추가해 버릴겁니다

즉 레퍼러값이 null인 경우는 허용할수 없다는 것이죠


http://www.jakartaproject.com/html/process.jsp

<%@ page contentType="text/html; charset=euc-kr" %>


<%

if (!"POST".equals(request.getMethod())
   return;


if (request.getHeader("referer") == null)
   return;

String register_no = request.getParameter("register_no");
%>


헤더정보 <%=request.getHeader("referer")%><br><br>
주민번호 <%=register_no%>

그럼 위와같은 소스가 될것입니다

그럼 과연 위 소스가 안전할까요?


HEADER값 조작

그렇다면 HEADER값을 조작해 봅시다 어떻게 조작할 수 있을까요?

여러가지 프로그램들이 있지만 그중에 Achilles 라는 proxy server를 이용하여 조작해 보겠습니다

Achilles라는 proxy server는 웹브라우져와 서버간의 HTTP 세션을 중간에서 가로채어 원하는대로 수정한 후 보낼수 있도록 해주는 작으면서도 강력한 프로그램입니다


※ 참고

Achilles 문서를 보면 맨 첫줄에 나오는 문장입니다

"Achilles is a tool designed for testing the security of web applications"

이 프로그램은 웹어플리케이션의 보안 테스팅을 하는데 작성되었으므로 테스팅용으로만 사용합시다


다운로드

http://www.mavensecurity.com/achilles


우선 위에서 작성한 바탕화면에 저장된 C:\Documents and Settings\Administrator\바탕 화면\client.html 를 실행한 결과를 Achilles가 Intercept한 결과입니다

여러 가지 헤더정보들이 보이며 쿠키값까지 조작할수 있습니다

하지만 위의 헤더정보에는 referer값이 없습니다 그래서 referer체크에서 null이 나와 로직에 걸립니다

그렇다면 referer정보를 추가해 줍시다


파랑색으로 줄쳐진 부분을 에디팅하여 추가해주었습니다

Referer: http://www.jakartaproject.com/html/input.html

그런다음 "Send"버튼으로 전송합니다


짠~

그러면 조작된 헤더정보를 알아채지 못하고 헤더의 referer값을 가져오는군요!



4. 서버쪽 로직 추가!

위에서 자바스크립트를 우회하는 몇가지 방법들을 알아보았습니다

결론은 하나입니다 즉! 서버쪽에서도 동일하게 체크해 주어야 합니다


<%@ page contentType="text/html; charset=euc-kr" %>


<%

String register_no = request.getParameter("register_no");


if (!"POST".equals(request.getMethod())
   return;


if (request.getHeader("referer") == null)
   return;


if (register_no.length() != 13)

   return;
%>


헤더정보 <%=request.getHeader("referer")%><br><br>
주민번호 <%=register_no%>


그렇다면 서버쪽에서만 체크하고 클라이언트에서는 체크할 필요가 없다고 생각할지도 모르지만,

그만큼 서버쪽으로 오는 request를 줄이면 더더욱 좋겠죠

자잘한것 하나때문에 서버쪽 부하를 줄수 없는 노릇아니겠습니까?


자 이러이러 하고 저러저러한 이유로 우리는 이제부터라도 클라이언트에서는 자바스크립트로,

서버쪽에서는 또 서버쪽 스크립트로 사용자가 입력한 값에대해 유효성을 검증해야 하는것을 알았습니다

로직이 복잡한 경우 가뜩이나 자바스크립트도 복잡한데 그 로직을 서버쪽에서 다시한번 만든다는게 힘들다는거 다들 압니다 하지만 안전한 웹페이지를 만들기 위해 다같이 노력해야 되지 않겠습니까?


Web Hacking 1탄 부터 이번 3탄에 이르기까지 웹 프로그래밍 하면서 반드시 필요하고 인식해야 하는 부분에 대해 논하였습니다

마지막으로 다시한번 언급하자면 우리가 잠깐 잊고 지나가거나 혹은 귀찮아서 지나치는 사소한 부분들 때문에 엄청난 결과를 가져올 수 있다는 것입니다 미리미리 예방하고 예측해서 방지하는수 밖에 없습니다 그럼 다들 건승~!~!


이상 GoodBug였습니다~


=============================================

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

=============================================

Posted by 1010
반응형

말도많고 탈도많은 쿠키!! 어떻게 사용하면 잘사용 하는걸까요?

앞으로 나오는 document.cookie등은 자동으로 "no_"앞에 가 붙습니다

Unicorn3에서 보안상 필터링하게 되어있기 때문입니다 앞에 "no_"가 없는것으로 간주하시면 됩니다


쿠키취약점

쿠키로 인증하는 사이트에 접속하여 로그인한 후 쿠키값 확인을 해봅니다

javascript:alert(document.cookie)


로그인 하지 않은 상태라면 다음과 같이 세션 아이디만 나오게 되며



로그인 한 상태라면 다음과 같이 쿠키이름과 쿠키값을 쌍으로 정보가 출력됩니다




관리자 아이디가 goodbug 라고 가정하고 이 아이디로 조작하기 위해서는 다음과 같이 입력합니다

javascript:a=prompt(document.cookie,"");alert(document.cookie=a)

그럼 프롬프트창이 하나 나타나며 이 부분에 다음과 같이 입력합니다



어떤 쿠키이름이 아이디를 나타내는 것일까요?

몇가지 없으니 가장 유력한 이름부터 하나씩 해보면 됩니다

UID=goodbug


다시 javascript:alert(document.cookie) 를 통해 쿠키값을 확인합니다


UID가 goodbug로 변경이 되었습니다

즉 내계정을 통해 goodbug로 로그인한것과 동일한 효과를 가져왔습니다!!

만약 쿠키로만 인증하는 방식이라면 타계정의 접속이나 관리자 화면으로 쉽게 들어갈 수 있습니다



 쿠키를 이용한 SQL Injection

쿠키를 이용하여 일반 로그인 화면이나 관리자 화면을 통화할 수 있습니다

SQL Injection이 어느정도 알려졌기 때문에 로그인 폼으로 부터 넘어온 아이디나 비밀번호 정보들을

일정 값들로 치환하는 경우를 볼 수 있습니다

즉 '나 ", -, \ #등의 SQL Injection에 활용되는 문자들을 무력화 시키곤 합니다

하지만 이역시 쿠키 SQL Injection을 통해 간단히 통과할 수 있습니다


마찬가지 방법으로 자신의 계정으로 로그인 하여 쿠키를 생성 한 후 다음과 같이 값을 변경합니다

UID=goodbug' or 1=1 --

관리자 화면은 화면마다 아이디를 이용해 인증을 할것입니다

하지만 이 관리자 아이디를 쿠키로 읽어온다면 아마 많은 허점이 생길겁니다

보통 쿠키로 부터 읽어온 값은 '나 --등은 체크하지 않죠

그래서 인증 관련된 부분은 항상 "특정문자를 치환+Statement" 보다는 "PreparedStatement"를 사용해야 합니다



 쿠키취약점 보안 및 결론

 -. 쿠키에 값을 구울때는 그 값을 "암호화" 하여 저장하고, 다시 읽어올때는 "역암호화"하여 사용합니다

 -. 로그인시에 IP도 쿠키에 같이 구워버리고, 데이터베이스에도 저장하며, 항상 실제 아이피와 비교하여 사용합니다

 -. 쿠키는 웹서버가 클라이언트에 남겨놓은 정보입니다

     그래서 쿠키는 클라이언트가 마음대로 조작하는것이 가능하기때문에 서버는 어떤일이 일어나는지 검사해야 한다는 것입니다


ps. 대형사이트에서는 IDS에 걸릴수 있으니 주의하세요


=============================================

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

=============================================

Posted by 1010
반응형

 
 
How To Use The Script

1. Download the library
Download wz_tooltip.js and unzipp it.
DHTML: Tooltips via JavaScript  
Top of page
 
Features
 
Cross Browser
 
Documentation
 
Extensions
 
Download
 
 
 
2. Link wz_tooltip.js into the html file

Copy the following line to inside the BODY section, preferably immediately after the opening <body> tag:
<script type="text/javascript" src="wz_tooltip.js"></script>
If necessary, adapt the path 'src="wz_tooltip.js"' to the JavaScript file. Note: Use the downloaded file only, do not hardlink wz_tooltip.js from my site.  
 
3. Specify tooltip text inside onmouseover eventhandlers

Each of the html tags to display a tooltip requires an onmouseover and an onmouseout attribute like so:

<a href="index.htm" onmouseover="Tip('Some text')" onmouseout="UnTip()">Homepage </a>

That's all. No title attributes, no container DIV. As you can see, the text to be displayed must be enclosed with single quotes, and be passed to a function Tip(). Attention: Single quotes (apostrophes) inside the tooltip text each must be masked with a backslash. Example:
Tip('This text won\'t trigger a JavaScript error.');
 
The call of UnTip() in the onmouseout eventhandler is to hide the tooltip again.
 
Of course you may also use different eventhandlers for Tip() and/or UnTip().


 
 
4. Doesn't Work?
a) Check the (dynamically generated?) HTML and the CSS of the page, preferably with the W3C Online Validator at http://validator.w3.org/. DOM errors will probably break the script.
b) Verify that you've exactly followed steps 1 to 3 on how to include the script, and everything mentioned under "Extended Configuration" further down this page.
c) Watch the JS Error Console of your browser. If there are errors, you can be sure that either the script hasn't been included correctly, or that there are syntax or logical errors in your own JS lines, or in some other script included into the page.
d) Please don't claim you've found a bug - unless you've checked everything very carefully, and you're absolutely sure. Please understand that I like developing code much more than debugging other peoples' web pages. Feedback is welcome, of course!

 
 
 
 
Extended Configuration

5. Alternative: Convert HTML element to tooltip
Instead of defining the tooltip text directly, you can specify an arbitrary HTML element to be converted to a tooltip. This is advantageous in some aspects:
  • You can have really important stuff in tooltips, since HTML content (unlike JavaScript content) of a page is relevant to web search engines.
  • If placed conveniently in the page, the content is also available for users who have disabled JavaScript.
  • Optionally, the HTML element can even stay visible; for example, if you want to display its content in a tooltip at a different location.
  • It may be easier to define complex inner tooltip HTML directly in the HTML element to be converted, rather than in a JavaScript string.

To define a tooltip to be created from an HTML element, just pass the ID of the desired HTML tag to the function TagToTip(). Example:

<a href="index.htm" onmouseover="TagToTip('Span2')" onmouseout="UnTip()">Home page </a>
...
<span id="Span2">This is some comment<br>about my home page</span>
...

In this example, the tooltip over the link will display the content grabbed from the <span> element. Note that only the inner content including the linebreak tag will be copied, whilst the SPAN tag itself and any formatting applied to it will not be inherited.
 
While the page is loading, the Tooltip Library hides automatically HTML elements to be converted to tooltips (e.g. the <span> element in the example above). To disable this auto-hide feature, set the variable TagsToTip in the global tooltip configuration in wz_tooltip.js to the value false (preset default: true). If desired, you must hide those HTML elements yourself, by setting their CSS 'display' property to 'none'.
 
As a side note: Especially in IE, page loading performance might benefit from disabling the auto-hide feature.
DHTML: Tooltips per JavaScript  
Top of page
 
Features
 
Cross Browser
 
Documentation
 
Extensions
 
Download
 
 
 
6. HTML inside tooltips

For images inside the tooltip, the width and height attributes in the <img> tags must be specified. This enables the script to determine the tooltip size correctly.
 
Doublequotes within the tooltip text must be written as HTML character entity (&quot;), since doublequotes serve already as delimiters for the onmouseover eventhandler, and cannot be nested. Apostrophes (singlequotes) must be masked with a preceding backslash, since apostophes serve already as delimiters for the tooltip text. As delimiters for HTML tag attributes inside the tooltip text, you can use either &quot; or \' . Example:
Correct:
<a href="index.htm" onmouseover="Tip('Text with <img src=\'pics/image.jpg\' width=\'60\'>image.')" onmouseout="UnTip()"> Homepage </a>
or
<a href="index.htm" onmouseover="Tip('Text with <img src=&quot;pics/image.jpg&quot; width=&quot;60&quot;>image.')" onmouseout="UnTip()"> Homepage </a>
 
Wrong:
<a href="index.htm" onmouseover="Tip('Text with <img src="pics/image.jpg" width="60">image.')" onmouseout="UnTip()"> Homepage </a>

 
 
7. Formatting tooltips with CSS classes

Simply wrap the tooltip text in a DIV or SPAN element of the desired CSS class. You can do the same with the title text (for how to define a tooltip title, see the description of the TITLE command in the commands reference below). Example:
... onmouseover="Tip('<div class=&quot;TipCls1&quot;>Text of tooltip number one</div>')" ...
... onmouseover="Tip('<span class=\'TipCls2\'>Text of tooltip number two</span>')" ...
... onmouseover="Tip('Tooltip number 3', TITLE, '<div class=\'TitleCls\'>Some Title</div>')" ...

 
 
8. Tooltip content via variable or function call

Instead of a string enclosed with single quotes, Tip() accepts as well a variable or a call to a function defined elsewhere, for instance in a <script> block or in a separate JS file. The same is true for commands passed to Tip() or TagToTip() (listing and description of commands see below). Thus, each time a tooltip is about to be displayed, its content and formatting could be established dynamically.
Example:
<html>
<head>
...
<script type="text/javascript">
var txt1 = "This is the text of the first tooltip";

function TooltipTxt(n)
{
    return "This is the text of the " + n + " tooltip";
}

</script>
</head>
<body>
<script type="text/javascript" src="wz_tooltip.js"></script>
...
<a href="a.htm" onmouseover="Tip(txt1)" onmouseout="UnTip()">Link 1</a>
...
<a href="b.htm" onmouseover="Tip(TooltipTxt('second'))" onmouseout="UnTip()">Link 2</a>
...
<a href="c.htm" onmouseover="Tip(TooltipTxt('third'))" onmouseout="UnTip()">Link 3</a>
...
</body>
</html>
DHTML: Tooltips per JavaScript  
Top of page
 
Features
 
Cross Browser
 
Documentation
 
Extensions
 
Download
 
 
 
9. Commands to customize tooltips individually

The global default configuration, taking effect on all tooltips, can be changed in the JavaScript file itself, in the section "GLOBAL TOOLTIP CONFIGURATION". To configure tooltips individually, you can use the commands listed below. These individual commands override the global configuration in wz_tooltip.js. They can be passed to the Tip() or TagToTip() function calls in the onmouseover eventhandlers. Each command must be accompanied by the desired value, separated by a comma:
onmouseover="Tip('Some text', ABOVE, true)"
or
onmouseover="TagToTip('SomeID', TITLEFONTCOLOR, '#CCFFCC')"

Multiple commands form a comma-separated list of command-value pairs. Order of commands is arbitrary. Example:
onmouseover="Tip('Some tooltip text', SHADOW, true, TITLE, 'Some Title', PADDING, 9)"


Command Description
ABOVE Positions the tooltip above the mousepointer. Value: true or false.
 
Combine with OFFSETY to adjust the vertical distance from the mousepointer, or with CENTERMOUSE to center the tooltip horizontally above the mousepointer.
BGCOLOR Background color of the tooltip. Value: HTML color, in single quotes, e.g. '#D3E3F6' or 'DarkCyan', or empty string '' for no background.
Example:
onmouseover="Tip('Some text', BGCOLOR, '#D3E3F6')"
or
onmouseover="Tip('Some text', BGCOLOR, '')"
BGIMG Background image. Value: Path to image, in single quotes.
Example:
onmouseover="Tip('Some text', BGIMG, '../images/tipbackground.gif')"
BORDERCOLOR Border color. Value: HTML color, in single quotes, e.g. '#dd00aa'.
BORDERSTYLE Border style. Value: CSS border style, in single quotes. Recommend are 'solid' (default), 'dashed' or 'dotted', others may not work in all browsers.
BORDERWIDTH Width of tooltip border. Value: Integer ≥ 0. Default is 1. Use 0 for no border.
Example:
onmouseover="Tip('Some text', BORDERWIDTH, 2)"
CENTERMOUSE Centers the tooltip horizontally beneath (or above) the mousepointer. Value: true or false. Consider that the tooltip is offset from the center by the value globally set in wz_tooltip.js (config. OffsetX), or as specified by the OFFSETX command.
Example:
onmouseover="Tip('Some text', CENTERMOUSE, true, OFFSETX, 0)"
CLICKCLOSE Closes the tooltip once the user clicks somewhere inside the tooltip or into the document. Value: true, false.
CLICKSTICKY Enables the user to fixate the tooltip, by just clicking onto the HTML element (e.g. link) that triggered the tooltip. This might help the user to read the tooltip more conveniently. Value: true, false.
 
onmouseover="Tip('Text', CLICKSTICKY, true, CLICKCLOSE, true, CLOSEBTN, true)"
In this example, additionally specifying CLICKCLOSE enables the user to close the tooltip with just another click somewhere into the document. Redundantly provided is a closebutton.
CLOSEBTN Displays a closebutton in the titlebar. Value: true, false.
CLOSEBTNCOLORS Colors used for the closebutton.
 
Value must be a comma-separated array of 4 color values. Each color in single quotes. The entire array must be enclosed with a pair of square brackets, see example below, since it's actually a single parameter. The 4 colors have the following meanings:
1. Background color
2. Text color
3. Highlighted background, while the button is being hovered
4. Hilighted text color, while the button is being hovered
For each of these colors, you can also specify an empty string '', in which case the title background, or title text color, respectively, is used for that button state.
 
Example:
Tip('Text', CLOSEBTN, true, CLOSEBTNCOLORS, ['', '#66ff66', 'white', '#00cc00'], STICKY, true)
In this example, the first color value (background color) is an empty string. Therefore the closebutton inherits the titlebar background.
CLOSEBTNTEXT Text in the closebutton. Value must be enclosed with single quotes. Example:
Tip('Tooltip text', CLOSEBTN, true, CLOSEBTNTEXT, 'Click Me', STICKY, true)
Globally preset in wz_tooltip.js is '&nbsp;X&nbsp;' - the whitespace entities '&nbsp;' add some horizontal padding to the button.
COPYCONTENT COPYCONTENT has only effect on tooltips created with TagToTip(), that is, for HTML elements converted to tooltips.
Value: true, false.
If true (this is the default behaviour preset in wz_tooltip.js), just a copy of the text (or inner HTML) of the HTML element is inserted into the tooltip. If false, the entire HTML element (its DOM node) by itself is temporarily converted to a tooltip, which may be useful in the following aspects:
1.) If the HTML element converted to a tooltip contains a form with inputs, their current user input will be maintained even while the tooltip is not displayed.
2.) The tooltip inherits the style properties of the HTML element.
Example how to convert an HTML element entirely to a tooltip, by applying COPYCONTENT with the value false:
TagToTip('SomeID', COPYCONTENT, false, BORDERWIDTH, 0, PADDING, 0)
Moreover, this example turns off the native tooltip border (BORDERWIDTH, 0), and sets the native tooltip padding to zero, so only the padding and border defined for the HTML element itself are displayed.
DELAY Tooltip shows up after the specified timeout, in milliseconds. A behavior similar to OS based tooltips.
Value: Integer ≥ 0. Use 0 for no delay. In wz_tooltip.js preset and recommended is 400.
Example:
onmouseover="Tip('Some text', DELAY, 1000)"
DURATION Time span, in milliseconds, until the tooltip is hidden, even if the STICKY command has been applied, or even if the mouse is still on the HTML element that has triggered the tooltip.
Value: Integer. Use 0 for no limitation (this is the default).
 
A negative value has a different meaning: It specifies a duration, in milliseconds, starting with the onmouseout until the tooltip is hidden. In other words, a negative value makes tooltip hide with some delay, rather than immediately. Especially useful for tooltips that don't follow the movements of the mouse (FOLLOWMOUSE, false).
EXCLUSIVE No other tooltip can be displayed until this one has been closed actively by the user. Value: true, false. Makes only sense for sticky tooltips (STICKY command). Of course, you must also provide the CLOSEBTN or/and CLICKCLOSE command to give the user a means to close the tooltip.
FADEIN Fade-in animation. The value (integer ≥ 0) specifies the duration of the animation, in milliseconds. 0 for no animation.
 
Not supported in Opera prior to v.9.0, old versions of Safari, some versions of Konqueror. These fall back to normal, non-animated behaviour.
FADEOUT Fade-out animation. The value (integer ≥ 0) specifies the duration of the animation, in milliseconds. 0 for no animation. Recommended: combine with FADEIN. Note that a small animation duration of 100 ms (recommended) is globally preset in wz_tooltip.js.
 
Not supported in Opera prior to v.9.0, old versions of Safari, some versions of Konqueror. These fall back to normal, non-animated behaviour.
FIX
Mode 1: Fixed x and y coordinates.
Shows the tooltip at the fixed coordinates [x, y]. Value: Two comma-separated integers in square brackets.
Example:
onmouseover="Tip('Some text', FIX, [230, 874])"
You can also call function(s) defined elsewhere that calculate the coordinates dynamically:
onmouseover="Tip('Text', FIX, [CalcFixX(), CalcFixY()], BORDERWIDTH, 2)"
or
onmouseover="Tip('Text', FIX, CalcFixXY(), ABOVE, true)"
In the latter example, the function CalcFixXY() must return an array containing the two numbers.
FIX
Mode 2: Fixed position at a certain HTML element.
Displays the tooltip at any desired HTML element - optionally even a different one than Tip() is called from. Value: Three comma-separated values in square brackets. The first value specifies the HTML element to display the tooltip at, either by its ID (string, in single quotes), or by a direct reference (no quotes). The second and third value (integers) define the horizontal and vertical offset of the tooltip from the left-bottom corner of the HTML element.
 
Example 1, ID of HTML element:
... onmouseover="Tip('Some text', FIX, ['PurpleSpan', 0, 5])"
...
<span id="PurpleSpan">HTML element to show the tooltip on</span>
This code snippet lets the tooltip appear 5 pixels below the bottom edge of the SPAN element.
 
Example 2, direct reference to HTML element:
<a href="..." onmouseover="Tip('Some text', FIX, [this, 0, 5], ABOVE, true)" onmouseout="UnTip()">Link</a>
This code snippet displays the tooltip directly at the HTML element (link) hovered with the mouse. As reference, we use the JavaScript keyword this - which automatically points to the HTML element the JavaScript eventhandler (e.g. onmouseover) stands in. Additionally, the ABOVE command is used in order to place the tooltip at the top edge of the HTML element.
FOLLOWMOUSE The tooltip follows the movements of the mouse. Value: true, false. Default: true.
 
When turning this off by applying the value false, the tooltip behaves like OS-based tooltips, which usually don't follow the mouse.
FONTCOLOR Font color. Value: HTML color, in single quotes, e.g. '#990099'
FONTFACE Font face (font family).
Value: As you'd specify it in HTML or CSS, enclosed with single quotes, e.g. Tip('Some text', FONTFACE, 'Arial, Helvetica, sans-serif', FONTSIZE, '12pt')
FONTSIZE Font size. Value: Size with unit, in single quotes. Unit ('px', 'pt', 'em' etc.) is mandatory.
FONTWEIGHT Font weight. Value: 'normal' or 'bold', in single quotes.
HEIGHT Height of the tooltip body, without title, shadows etc.. Value: Any integer.
If 0 (the preset default), the height is automatically adapted to the content of the tooltip. A negative number (e.g. -100) specifies a maximum limit for the automatic adaption (in this example the height won't ever go beyond 100 pixels).
 
Note that the tooltips follow the W3C box model, which means that the specified height applies to the actual content of the tooltip only, excluding padding (see PADDING command), border and shadow. If the height of the tooltip content exceeds the specified height, the tooltip is featured with a vertical scrollbar. Therefore, make sure that such tooltips of limited height are sticky (see STICKY command), so your visitors are given the chance to scroll the tooltip content.
JUMPHORZ Value: true, false. Test again.
If true: When touching the window boundary, the tooltip jumps horizontally to the other side of the mouse.
If false (preset default in wz_tooltip.js): The tooltip just stops by the right (or left) window boundary. In either case, the tooltip is prevented from extending past the window boundary.
JUMPVERT When it touches the bottom (or top) window boundary, the tooltip jumps vertically to the other side of the mouse.
Value: true, false. This behaviour is on (true) by default (preset in wz_tooltip.js).
 
Important: At least either JUMPVERT or JUMPHORZ behaviour, or both, should be true, so the mouse cannot enter the tooltip and thus trigger an onmouseout event when the tooltip is simultaneously stopped by a vertical and horizontal window boundary. Recommended and preset in wz_tooltip.js: JUMPVERT true, JUMPHORZ false.
LEFT Tooltip positioned on the left side of the mousepointer. Value: true, false.
LEFT and ABOVE commands combined.
Example:
onmouseover="Tip('Some text', LEFT, true, ABOVE, true)"
OFFSETX Horizontal offset from mouse-pointer. Value: Any integer. May also be negative.
OFFSETY Vertical offset from the mouse-pointer. Value: Any integer. May also be negative.
OPACITY Transparency of tooltip. Value: Integer between 0 (fully transparent) and 100 (opaque, no transparency).
 
Opacity is the opposite of transparency, i.e.
opacity = 100 - transparency (in percent).
Another example with image (taken on my 9000-km / 5500-miles recumbent bicycle trip Hamburg-Northcape-Munich), shadow via SHADOW command, content centered using TEXTALIGN, background image via BGIMG and animation via FADEIN and FADEOUT commands.
 
Not supported in Opera prior to v.9.0, old versions of Safari and some versions of Konqueror.
PADDING Inner spacing of tooltip, between border and content. Value: Integer ≥ 0.
SHADOW Tooltip drops a shadow. Value: true, false
SHADOWCOLOR Shadow color. Value: HTML color, in single quotes.
Example:
onmouseover="Tip('Some text', SHADOW, true, SHADOWCOLOR, '#dd99aa')"
SHADOWWIDTH Shadow width (offset). Value: Integer ≥ 0.
Example:
onmouseover="Tip('Some text', SHADOW, true, SHADOWWIDTH, 7)"
STICKY The tooltip stays fixed at its initial position until another tooltip pops up. Value: true, false.
 
With DURATION you can enforce the tooltip to disappear after a certain time span.
TEXTALIGN Aligns the text in the body of the tooltip. Value: 'right', 'center', 'justify' or 'left'.
Example:
onmouseover="Tip('Some text', TEXTALIGN, 'right')"
TITLE Displays a titlebar. Value: Text to display, in single quotes. May even contain HTML, which gives you additional freedom in fashioning the titlebar.
TITLEALIGN Aligns the text in the titlebar. Value: 'right', 'center', 'justify' or 'left'
TITLEBGCOLOR Backgroundcolor of the titlebar. Value: HTML color, in single quotes. If it's an empty string '', the border color (see also BORDERCOLOR command) is used (this is the default).
TITLEFONTCOLOR Color of title text. Value: HTML color, in single quotes. If it's an empty string '', the backgroundcolor of the tooltip body (see also BGCOLOR command) is used (this is the default).
TITLEFONTFACE Font face for title text. Value: Like in HTML or CSS. Enclosed with single quotes. If the value is an empty string '', the tooltip body font, in boldified form, is used (this is the default).
Example:
onmouseover="Tip('Some text', TITLE, 'Some Title', TITLEFONTFACE, 'Verdana,sans-serif')"
TITLEFONTSIZE Font size of title text. Value: Size with unit, in single quotes. Unit ('px', 'pt', 'em' etc.) is mandatory. If the value is an empty string '', the fontsize of the tooltip body is applied.
TITLEPADDING Padding around the title. Value: Integer ≥ 0.
WIDTH Width of tooltip. Value: Any integer.
If 0 (the preset default), the width is automatically adapted to the content of the tooltip. A negative number (e.g. -240) specifies a maximum limit for the automatic adaption (in this example the width won't ever go wider than 240 pixels).
 
A value of -1 for WIDTH has a special meaning: In this case the width of the tooltip is determined by the extent of the title. That is, the tooltip will be as wide as the title plus, if specified, the closebutton.
 
Note that the tooltips follow the W3C box model, which means that the specified width applies to the actual content of the tooltip, excluding padding (see PADDING command), border and shadow.


 
 
 
Extensions

Visit the Extensions page for additional configuration options.
 
 
 
 
Download
wz_tooltip.js 5.31, published under the LGPL:
wz_tooltip.zip (16 KB)
 
history.htm (Changelog of wz_tooltip.js)
 
Important notes for users of previous versions
 
Starting with version 5.0, an onmouseout attribute is required for each HTML tag that has a tooltip. Example:
<a href="index.htm" onmouseover="Tip('Some text')" onmouseout="UnTip()"> Home </a>
Simply call UnTip() from inside those onmouseout attributes. See also documentation above. The additional onmouseout attribute may be a bit less elegant, but gives you more freedom in specifying the event upon which to hide a tooltip.

 
 
 
Old Version For those who are still using a version prior to v.4.0 and want to stay with the old rules of defining tooltips and including the script:
Documentation and download of wz_tooltip.js v.3.45
 
 
 
Donation
Financial support for the very numerous hours of development and for the costs of hosting this website is welcome.
Posted by 1010
반응형

[javascript] 입력 문자 한글 체크


function koreanCheck(str) {
    var i;
    var ch;
   
    for (i=0;i<str.length;i++) {
        ch = escape(str.charAt(i));        //ISO-Latin-1 문자셋으로 변경

        if (strCharByte(ch) != 2) { //한글이 아닐 경우
            return;
        }
    }
}

function strCharByte(chStr) {
    if (chStr.substring(0, 2) == '%u') {
        if (chStr.substring(2,4) == '00')
            return 1;
        else
            return 2;        //한글
    } else if (chStr.substring(0,1) == '%') {
        if (parseInt(chStr.substring(1,3), 16) > 127)
            return 2;        //한글
        else
            return 1;
    } else {
            return 1;
    }
}


출처 : http://ingenuity.egloos.com/2789643

Posted by 1010
반응형

function getParameter( name )
{
 name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");

 var regexS = "[\\?&]" + name + "=([^&#]*)";
 var regex = new RegExp( regexS );
 var results = regex.exec( window.location.href );

 if( results == null )
  return "";
 else
  return results[1];
}


출처 : http://www.netlobo.com/url_query_string_javascript.html

Posted by 1010
반응형
 

보통 브라우저명을 체크할 때 아래 코드를 많이 사용합니다.

var DOM = (document.getElementById) ? true : false; // W3C 표준
var IE4 = (!DOM && document.all) ? true : false; // IE4
var IE5 = (DOM && (navigator.userAgent.indexOf("MSIE")>-1)) ? true : false; // IE5 >= 5
var NS4 = (!DOM && document.layers) ? true : false; // NN4
var NS5 = (DOM && (navigator.userAgent.indexOf("Gecko")>-1)) ? true : false // NN5 >= 5

또는,
navigator.appName == "Microsoft Internet Explorer"
navigator.appName == "Netscape"

위처럼 하면 한 가지 문제가 생기는데 바로 NS와 FF 입니다.
알다시피 FF 도 모질라의 뿌리를 갖고 있으므로 Netscape 를 브라우저명에 같이 출력합니다.
그래서 위처럼 하게되면 근래들어 급속한 사용자증가를 보이고 있는 FF 를 제대로 가려낼 수가 없습니다.
또한 FF 는 왠만한 부분은 IE6과 비슷합니다.  하다못해 스크롤링 되는 레이어도 같은 코드로 지원합니다.  그러나 NS 는 분명히 다릅니다.  IE와 FF 에서 스크롤되는 레이어도(예를 들어 영카트1에 있는 오른쪽 움직이는 스크롤처럼) NS에서는 지원되지 않으며, 영카트의 스크롤 레이어가 브라우저명에서 NS 를 기준으로 체크하므로 FF에서는 스크롤이 움직이지 않습니다.

위와 같은 경우의 해결책이며..사실 해결책이라기 보다는 가장 정확한 브라우저명을 체크하는게 아닌가 싶습니다.

//브라우저 이름으로 브라우저 구분 : Netscape Firefox MSIE
if(new RegExp(/Firefox/).test(navigator.userAgent)){
    FF (파이어폭스)
}else if(new RegExp(/Netscape/).test(navigator.userAgent)){
    NS (넷스케이프)
}else if(new RegExp(/MSIE/).test(navigator.userAgent)){
  IE (익스플로러)
}

위와 같이 정확한 브라우저명을 체크할 수 있으며, 버젼까지 체크할 경우는
navigator.appVersion.indexOf 를 이용하여 정확히 체크할 수 있습니다.

 

=========================================================================

//브라우저 명

var user_app_name = "";

if(new RegExp(/Firefox/).test(navigator.userAgent)){
 user_app_name = "FF";
}else if(new RegExp(/Netscape/).test(navigator.userAgent)){
 user_app_name = "NS";
}else if(new RegExp(/MSIE/).test(navigator.userAgent)){
 user_app_name = "IE";
}else if(new RegExp(/Opera/).test(navigator.userAgent)){
 user_app_name = "OP";
}

 

머 이렇게 쓰면 될려나...ㅋㅋ

Posted by 1010
반응형
 \n만 치환하면 안된다 \r\n 전부다 해줘야 한다.--(이것 때문에 고생했슴)

1. textarea 에 엔터값을 그냥 DB에 넣어서 처리 할 경우

---------------------------------------------------

DB상에는 엔터값이 먹힌 상태로 들어간다. 그 값을 나중에 html 코드에 가져오면

그냥 한줄로 출력이 된다.

이 때 <pre>태그를 써서 줄바꿈이 먹게 만들면 될것이다.

하지만 잘 살펴보면 DB상에 저장된 데이터에서 맨 마지막에 엔터가 한번 더 들어가 있는 것을 볼 수 있을 것이다. 따라서 내가 원하는 이쁜 배열은 안나온다..


2. textarea에서 엔터값을 치환<권장하는 방법이다>

----------------------------------------------------

이 부분은 여러 문서가 있다. asp,php,jsp의 처리 방법이 같지 않은거 같다.

여기서 사용하는 함수는 replace 함수이다(함수에 대한 설명은 찾아보삼)

textarea의 name 값이 contents 라 한다면,

그 값을 받는 부분에서 변환을 한다.

(실질적인 JSP 코드가 들어가있는 부분을 말한다.)


String content = request.getParameter("contents");

 전페이지에서 DB쿼리 실행하는 페이지에서 쓴다.

이 부분을 통해 textarea 값을 받아올 수 있따.

textarea 상에서 엔터는 어떤문자로 인식이 되냐면

\r\n 으로 표시가 된다.

이것을 치환을 한다!


contents = contents.replace("\r\n","<br>");

이렇게 하면 엔터가 DB상에 <br>로 바껴서 저장이 되고, html 코드에 가져올 때 자동적으로 <br>태그가 먹혀서 줄바꿈이 된다.


이 방법을 쓴다면, 이 값을 불러오는 페이지에서 아무 처리를 안해도 원하는 결과를

얻을 수 있다

Posted by 1010
반응형
각각의 다운로드 버튼을 클릭하셔서 받으시던지 모두 받으시려면 제일 하단의 "모두 다운로드" 이용하세요.
gBtn1 다운로드 (DOWN)
gBtn2 다운로드 (DOWN)
gBtn3 다운로드 (DOWN)
gBtn4 다운로드 (DOWN)
gBtn5 다운로드 (DOWN)
gBtn6 다운로드 (DOWN)
gBtn7 다운로드 (DOWN)
gBtn8 다운로드 (DOWN)
gBtn9 다운로드 (DOWN)
gBtn10 다운로드 (DOWN)
gBtn11 다운로드 (DOWN)
gBtn12 다운로드 (DOWN)
gBtn13 다운로드 (DOWN)
gBtn14 다운로드 (DOWN)
gBtn15 다운로드 (DOWN)
gBtn16 다운로드 (DOWN)
gBtn17 다운로드 (DOWN)
gBtn18 다운로드 (DOWN)
gBtn19 다운로드 (DOWN)
gBtn20 다운로드 (DOWN)
gBtn21 다운로드 (DOWN)
모두 다운로드 (DOWNLOAD ALL)
출처 : http://poshopzil.com
Posted by 1010
반응형
function number_format(str){
        str = ""+str+"";
        var retValue = "";
        for(i=0; i<str.length; i++){
            if(i > 0 && (i%3)==0) {
                retValue = str.charAt(str.length - i -1) + "," + retValue;
            } else {
                retValue = str.charAt(str.length - i -1) + retValue;
            }
        }
        return retValue;
}
Posted by 1010
반응형

//var    _intValue   = '0123456789';
//var    _upperValue = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
//var    _lowerValue = 'abcdefghijklmnopqrstuvwxyz';
//var    _etcValue   = '~`!@#$%%^&*()-_=+\|[{]};:\'\",<.>/?';
//var    dayOfMonth = new Array(31,28,31,30,31,30,31,31,30,31,30,31);

n = (document.layers) ? 1:0;
ie = (document.all) ? 1:0;
if (n) document.captureEvents(Event.KEYPRESS);

function fnTest(pval) {
  fnTest =  doReverse(pval.value) ;
  alert (fnTest);
}

// -------------------------------------------------------------------
// Function name: isInt
// Description  : 숫자인가를 체크하는 함수
// Parameter    : value(체크대상 문자)
// -------------------------------------------------------------------
// Usage        : var a='3'; if(isInt(a)) { alert("숫자입니다"); }
// -------------------------------------------------------------------
function isInt(value) {
 var _intValue   = '0123456789';
    var j;
    for(j=0;j<_intValue.length;j++)
      if(value == _intValue.charAt(j)) {
    return true;
 }
    return false;
}

// --------------------------------------------------------------------
// Function name: isNumeric
// Description  : 숫자로만 구성되어 있는지를 검사
// Parameter    : obj(화면컨트롤)
// --------------------------------------------------------------------
// Usage        : <input type="text" onBlur="isNumeric(this)">
// Caution      : 화면컨트롤에 데이타가 없는 경우에는 false를 리턴
// --------------------------------------------------------------------
function isNumeric(obj) {
 var str=obj.value;
 if (str.length == 0)
 return false;
 for (var i = 0; i < str.length; i++){
 var ch = str.substring(i, i + 1);
 if ((ch < "0" || "9" < ch) ){
     obj.focus();
     obj.select();  
   return false;
  }
 }
 return true;
}

// ---------------------------------------------------------------------
// Function name : isNumber(str)
// Description   : 숫자로만 구성되어 있는지를 검사, 숫자이면 return true
// Parameter     : str(측정대상값)
// ----------------------------------------------------------------------
// Usage         : if(isNumber(str)) { alert("숫자입니다.."); },
// Caution       : isNumeric(obj)과 다른점은 obj가 아닌 value값 사용
// ----------------------------------------------------------------------
function isNumber(value) {
 var result = true;
 for(j = 0; result && (j < value.length); j++) {
  if((value.substring(j, j+1) < "0") || (value.substring(j, j+1) > "9")) {
   result = false;
  }
 }
 return result;
}

// ---------------------------------------------------------------------
// Function name: getNumOnly
// Description  : 숫자와 문자열이 혼합되어 있는 것에서 숫자만 리턴
// Parameter    : obj(검사대상 문자열)
// ---------------------------------------------------------------------
// Usage        : <input type="text" onBlur="getNumOnly(this);">
//                검사대상 문자열이 '1134sd3dkk8'일 경우 '113438'만 리턴
// ---------------------------------------------------------------------
function getNumOnly(obj) {
 var strNew = "";
  var chkstr = "0123456789";
 var str = obj.value;
 for (var i = 0; i < str.length; i++) {
   if (chkstr.indexOf(str.substring(i, i + 1)) >= 0) {
     strNew += str.substring(i, i + 1);
   }
 }
  return strNew;
}

// ---------------------------------------------------------------
// Function name : isFloat(str)
// Description   : 숫자값인지 체크, '.' 포함
// Parameter     : str(측정대상값)
// ---------------------------------------------------------------
// Usage         : if(isFloat(str)) { alert("Float값입니다."); }
// ---------------------------------------------------------------
function isFloat(value) {
 var count = 0;
 var ch;
 
 for(i=0; i<value.length; i++) {
  ch = value.charAt(i);
 
  if(isNaN(ch)) {
   if(ch == ".") {
    count++;
   } else {
    return false;
   }
  }    
 }
 
 if(count > 1) {
  return false;
 } else {
  return true;
 }
 
 return result;
}

// -------------------------------------------------------------------
// Function name : getOnlyNumberKey()
// Description   : 키보드 입력시 숫자만 입력 가능
// Parameter     :
// -------------------------------------------------------------------
// Usage         : onKeyDown=getOnlyNumberKey()
// -------------------------------------------------------------------
function getOnlyNumberKey() {
 if ((event.keyCode >=48 && event.keyCode <=57)   // 자판 0~9
  || (event.keyCode >=96 && event.keyCode <= 105)  // keypad 0~9
  || (event.keyCode == 109)             // 자판 -
  || (event.keyCode == 189)             // keypad -
  || (event.keyCode == 8)              // back space
  || (event.keyCode == 9)              // tab
  || (event.keyCode == 13)             // enter
  || (event.keyCode == 46)             // delete
  || (event.keyCode >= 37 && event.keyCode <= 40)) // 방향키
 {
  return true;
 } else {
  event.returnValue = false;
 }
}

// ---------------------------------------------------------------------
// Function name : getNumberNCommaKey() 
// Description   : 키보드 입력시 숫자 및 ','가 입력 가능
// Parameter     :
// ---------------------------------------------------------------------
// Usage         : onKeyDown=getNumberNCommaKey() 
// ---------------------------------------------------------------------
function getNumberNCommaKey() {
 if ((event.keyCode >=48 && event.keyCode <=57)   // 자판 0~9
  || (event.keyCode >=96 && event.keyCode <= 105)  // keypad 0~9
  || (event.keyCode == 109)             // 자판 -
  || (event.keyCode == 189)             // keypad -
  || (event.keyCode == 188)             // 자판 ,
  || (event.keyCode == 8)              // back space
  || (event.keyCode == 9)              // tab
  || (event.keyCode == 13)             // enter
  || (event.keyCode == 46)             // delete
  || (event.keyCode >= 37 && event.keyCode <= 40)) // 방향키
 {
  return true;
 } else {
  event.returnValue = false;
 }

}

// ----------------------------------------------------------------------
// Function name : getNumberNDotKey()
// Description   : 키보드 입력시 숫자 및 '.'가 입력 가능
// Parameter     :
// ----------------------------------------------------------------------
// Usage         : onKeyDown=getNumberNDotKey()
// ----------------------------------------------------------------------
function getNumberNDotKey() {
 if ((event.keyCode >=48 && event.keyCode <=57)   // 자판 0~9
  || (event.keyCode >=96 && event.keyCode <= 105)  // keypad 0~9
  || (event.keyCode == 109)             // 자판 -
  || (event.keyCode == 189)             // keypad -
  || (event.keyCode == 110)             // 자판 .
  || (event.keyCode == 190)             // keypad .
  || (event.keyCode == 8)              // back space
  || (event.keyCode == 9)              // tab
  || (event.keyCode == 13)             // enter
  || (event.keyCode == 46)             // delete
  || (event.keyCode >= 37 && event.keyCode <= 40)) // 방향키
 {
  return true;
 } else {
  event.returnValue = false;
 }
}

// --------------------------------------------------------------------
// Function name : isDigitOrBar(str)
// Description   : '-' 기호를 포함한 숫자여부 판단, 숫자면 return true
// Parameter     : str(대상 문자열)
// --------------------------------------------------------------------
// Usage         : isDigitOrBar(str), 부호의 선행, 후행은 체크 못함
// --------------------------------------------------------------------
function isDigitOrBar(str) {
 for(var i=0; i < str.length; i++) {
  var ch= str.charAt(i) ;
  if((ch < "0" || ch > "9") && ch!="-") {
   return false;
  }
 }
 return true;
}

//---------------------------------------------------------------------
// Function name : getFormattedVal
// Description   : 숫자를 포멧이 갖추어진 문자열로 바꿈
//                 ###3 <= 숫자3은 세자리마다 ,를 찍겠다는 말
//                 .##### <= .(소수점)뒤로 5자리까지 표현하겠다는 말
// Parameter     : value  : 검사할 값
//                 format : 변환할 형태
// Return        :  변환된 값 리턴
// --------------------------------------------------------------------
// Usage         : getFormattedVal(value , "###3.#####")
//---------------------------------------------------------------------
function getFormattedVal(value,format) {
    value = ""+value;

    if(!format)
      return value;

    var sp = parseInt(format.charAt(3));

    if(!sp)
      return value;

    var pos = 0;
    var ret = "";
    var vSplit = value.split('.');
    var fSplit = format.split('.');
    var fp = fSplit[1];
    var fv = vSplit[1];
    var lv = vSplit[0];
    var len = lv.length;

    for(var i = len % sp; i < len; i += sp){
        if(i == 0 || lv.charAt(i-1) == '-')
            ret += lv.substring(pos,i);
        else
            ret += lv.substring(pos,i)+',';
        pos = i;
    }

    ret += lv.substring(pos,len);

    if(!fv)
        fv = "";
    if(!fp)
        fp = "";

    var len1 = fp.length;
    var len2 = fv.length;

    if(len1)
      ret += '.' + fv.substring(0,len1) + fp.substring(len1,len2);
    return ret;
}


//-------------------------------------------------------------------
// Function name : changeInt2Han
// Description   : 숫자 -> 한글로 변환
// Parameter     : string  : 변환 할 값
// Return        : 변환된 값 리턴 / 123 -> 일백이십삼
// -------------------------------------------------------------------
// Usage         : changeInt2Han(string)
//--------------------------------------------------------------------
function changeInt2Han(string) {
 hn = new Array("영","일","이","삼","사","오","육","칠","팔","구");
 hj = new Array("","만","억","조","경","해");
 ul = new Array("영천","영백","영십","영");
 tm = new Array();
 result = "";

 if (string.charAt(0)=="-") {
  result = "마이너스 ";
  string = string.substr(1,string.length-1);
 }

 loop_size = Math.ceil(string.length/4);
 string2 = "";

 for (count=string.length; count >= 0; count--)
  string2 += string.substring(count,count-1);
  string = string2;

 for (A=0;A<loop_size;A++) {
  sum = hj[A] + " ";
  tm[A] = string.substr(A*4,4);

  tm2 = "";
 
  for (count=tm[A].length; count >= 0; count--)
   tm2 += tm[A].substring(count,count-1);
 
  tm[A] = tm2;
  part_jari = tm[A].length;
 
  for (D=0;D<10;D++) {
   for (B=0;B<10;B++) tm[A] = tm[A].replace(B,hn[B]);
  }

    if (part_jari == 4) tm[A] = tm[A].charAt(0)+"천"+tm[A].charAt(1)+"백"+tm[A].charAt(2)+"십"+tm[A].charAt(3);
    else if (part_jari == 3) tm[A] = tm[A].charAt(0)+"백"+tm[A].charAt(1)+"십"+tm[A].charAt(2);
  else if (part_jari == 2) tm[A] = tm[A].charAt(0)+"십"+tm[A].charAt(1);
  else tm[A] = tm[A].charAt(0);

  for (C=0;C<4;C++) {
   if (tm[A].match(ul[C])) {
    part_jari--; tm[A] = tm[A].replace(ul[C],"");
   }
  }
   
  if (part_jari != 0) tm[A] += sum;
  }

 for (loop_size;loop_size>-1;loop_size--)
  result += tm[loop_size];
 
 result = result.replace("undefined","");
 return result;
}

//-----------------------------------------------------------------------
// Function name : changeInt2HanJa
// Description   : 숫자 -> 한자로 변환
// Parameter     : string  : 변환 할 값
// Return        : 변환된 값 리턴 / 일백이십삼 -> 壹百貳拾參
// ----------------------------------------------------------------------
// Usage         : changeInt2HanJa(string)
//-----------------------------------------------------------------------
function changeInt2HanJa(string) {
 hn = new Array("영","壹","貳","參","四","五","六","七","八","九");
 hj = new Array("","萬","億","兆");
 ul = new Array("영千","영百","영拾","영");
 tm = new Array();
 result = "";

 if (string.charAt(0)=="-") {
  result = "마이너스 ";
  string = string.substr(1,string.length-1);
 }
 loop_size = Math.ceil(string.length/4);
      string2 = "";
 for (count=string.length; count >= 0; count--)
  string2 += string.substring(count,count-1);
   
 string = string2;
 
 for (A=0;A<loop_size;A++) {
  sum = hj[A] + " ";
  tm[A] = string.substr(A*4,4);

  tm2 = "";

  for (count=tm[A].length; count >= 0; count--)
   tm2 += tm[A].substring(count,count-1);
 
  tm[A] = tm2;
  part_jari = tm[A].length;
  for (D=0;D<10;D++) {
   for (B=0;B<10;B++) tm[A] = tm[A].replace(B,hn[B]);
  }

  if (part_jari == 4) tm[A] = tm[A].charAt(0)+"千"+tm[A].charAt(1)+"百"+tm[A].charAt(2)+"拾"+tm[A].charAt(3);
  else if (part_jari == 3) tm[A] = tm[A].charAt(0)+"百"+tm[A].charAt(1)+"拾"+tm[A].charAt(2);
  else if (part_jari == 2) tm[A] = tm[A].charAt(0)+"拾"+tm[A].charAt(1);
  else tm[A] = tm[A].charAt(0);
  for (C=0;C<4;C++) {
   if (tm[A].match(ul[C])) {
    part_jari--; tm[A] = tm[A].replace(ul[C],"");
   }
  }
  if (part_jari != 0) tm[A] += sum;
 }

 for (loop_size;loop_size>-1;loop_size--) result += tm[loop_size];
   result = result.replace("undefined","");

 return result;
}

//-----------------------------------------------------------------------------
// Function name : isFraction
// Description   : 입력된 문자가 숫자, 분수(1/3,2/5..)인가를 체크하는 함수
// Parameter     : obj(입력 컨트롤명)
// ----------------------------------------------------------------------------
// Usage         : 사용자가 텍스트박스에 숫자값으로만 입력되어야 할 경우 이를
//                 검증하기 위해서 아래와 같이 사용
//                 <input type="text" onBlur="isFraction(this)">
//-----------------------------------------------------------------------------
function isFraction(obj) {
 var i,j;
 var str = new String(obj.value);
 var check_slash = 0;

 if ((str == '')||(str.length == 0))
   return true;

 for(i=0;i< str.length;i++) {
  if(!isInt(str.charAt(i))) {
 
   if(str.charAt(i) != '/') {
    alert('정수 또는 분수만 입력가능합니다.');
    obj.focus();
    obj.select();
    return false;
    } else {
    check_slash++;
    if (i==0) {
     alert('정수 또는 분수만 입력가능합니다.');
     obj.focus();
     obj.select();
     return false;
    }
   }
  }
 }
 j = i -1;

 if (str.charAt(j) == '/' || check_slash > 1) {
  alert('정수 또는 분수만 입력가능합니다.');
  obj.focus();
  return false;
 }
 return true;
}

//---------------------------------------------------------------------------------------
// Function name : checkDigitBody2
// Description   : 숫자 혹은 구분자('-', '.' 등)로만 구성되어 있는지를 검사
// Parameter     : obj(화면컨트롤), sep(구분자)
// --------------------------------------------------------------------------------------
// Usage         : <input type="text" onBlur="checkDigitBody2(this, '-')">
// Caution       : 화면컨트롤에 데이타가 없는 경우에는 false를 리턴
// --------------------------------------------------------------------------------------
function checkDigitBody2(obj, sep) {
 var str=obj.value;
 if (str.length == 0)
  return false;
 for (var i = 0; i < str.length; i++) {
  var ch = str.substring(i, i + 1);
  if ((ch < "0" || "9" < ch)) {
   if (ch != sep)
    return false;
  }
 }
 return true;
}

//---------------------------------------------------------------------------------------
// Function name : getNumberOnly
// Description   : 실수,정수,금액 유효성 체크 및 허용하지 않는 문자는 경고 없이 자동 삭제
// Parameter     : 필수 : obj(입력 컨트롤명), cmd(숫자 유형)
//---------------------------------------------------------------------------------------
// Usage         : <input name="num1" type="text"  onkeyup= "getNumberOnly(this, 'money')"  ...>
// Caution       : 일반적으로 다른 function에서 내부적 호출로 쓰임
//---------------------------------------------------------------------------------------
function getNumberOnly(obj, cmd) {
 var instr = obj.value;
 var cstr = "";
 var tempstr = "";

 if(cmd == "real") {
  cstr = "0123456789.-";          //실수
 } else if(cmd == "real2") {
  cstr = "0123456789.";      //양의실수
 } else if(cmd=="int") {
  cstr="0123456789-";             //정수
 } else if(cmd=="money") {
  cstr="0123456789,";       //금액
 } else if(cmd == "real3") {
  cstr = "0123456789.-,";         //실수 : , 포함
 } else if(cmd=='numeric') {
  cstr = "0123456789";      //숫자
 }

 //거꾸로 돌려야 함
 if(instr.length) {
  var len = instr.length;
  for(var i=len-1; i>=0; i--) {
   if(cstr.lastIndexOf(instr.charAt(i)) == -1) {
    instr = instr.substring(0, i)+ instr.substring(i+1);
    obj.value = instr;
   }
  }
 }
}

// --------------------------------------------------------------------------------------------
// Function name : addCommaStr
// Description   : 입력창에 숫자 데이터를 입력할때 자동으로 3자리별로 ',' 가 붙어 입력되게함
// Parameter     : str(문자열(숫자))
// --------------------------------------------------------------------------------------------
// Usage         :
// Caution       : 이 함수를 사용할때 Input 박스 값이 숫자 값인지 체크할 때는 쉼표를 자동으로
//                 체크하여 숫자여부를 판단하는 checkDigitBody2(obj, ",")를 사용한다.
// --------------------------------------------------------------------------------------------
function addCommaStr(str) {
 if (str.length < 1) {
    return "";
  } else {
  var tm = "";
  var ck = "";
  if (str.substring(0, 1) == "-") { //음수
   tm = str.substring(1, str.length);
   ck = "Y";
  } else {//양수
   tm = str;
   ck = "N";
  }
  var st = "";
  var cm = ",";

  for (var i = tm.length, j = 0; i > 0; i--, j++) {
   if ((j % 3) == 2) {
    if (tm.length == j + 1) st = tm.substring(i - 1, i) + st;
    else st = cm + tm.substring(i - 1, i) + st;
   } else {
    st = tm.substring(i - 1, i) + st;
   }
  }
  if (ck == "Y") st = "-" + st;
 }
 return st;
}

// --------------------------------------------------------------------------------------------
// Function name : delCommaStr
// Description   : 화폐구분자로 사용되는 ','문자를 제거하는 함수.
//                 보통 화면에는 ,로 표시하고, DB에는 ','를 제외한 숫자만을 insert할 때 사용
// Parameter     : str(금액형태의 문자열)
// --------------------------------------------------------------------------------------------
// Usage         :
// --------------------------------------------------------------------------------------------
function delCommaStr(str) {
 if (str.length < 1) {
  return "";
 } else {
  var st = "";
  var sp = ",";
  for (var i = 0; i < str.length; i++) {
   if (sp.indexOf(str.substring(i, i + 1)) == -1) {
    st += str.substring(i, i + 1);
   }
  }
  return st;
 }
}

// --------------------------------------------------------------------------------------------
// Function name : delComma
// Description   : 화폐구분자로 사용되는 ','문자를 제거하는 함수.
//                 보통 화면에는 ,로 표시하고, DB에는 ','를 제외한 숫자만을 insert할 때 사용
// Parameter     : obj(화면 입력박스명)
// --------------------------------------------------------------------------------------------
// Usage         :
// Caution       : delCommaStr 과 다른점은 value 가 아닌 obj값 사용
// --------------------------------------------------------------------------------------------
function delComma(obj) {
 var str =  String(obj.value);
 if (str.length < 1) {
  return "";
 } else {
  var st = "";
  var sp = ",";
  for (var i = 0; i < str.length; i++) {
    if (sp.indexOf(str.substring(i, i + 1)) == -1) {
      st += str.substring(i, i + 1);
    }
  }
  return st;
 }
}

// --------------------------------------------------------------------------------------------
// Function name : isUpperChar
// Description   : 영문 대문자인지를 체크하는 함수
// Parameter     : value(체크대상 문자)
// --------------------------------------------------------------------------------------------
// Usage         : var a='A'; if(isUpperChar(a)) { alert("대문자입니다"); }
// --------------------------------------------------------------------------------------------
function isUpperChar(value) {
 var _upperValue = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
 var i;
 for(i=0;i<_upperValue.length;i++)
  if(value == _upperValue.charAt(i)) {
   return true;
  }

 return false;
}

// --------------------------------------------------------------------------------------------
// Function name : isLowerChar
// Description   : 영문 소문자인지를 체크하는 함수
// Parameter     : value(체크대상 문자)
// --------------------------------------------------------------------------------------------
// Usage         : var a='k'; if(isLowerChar(a)) { alert("소문자입니다"); }
// --------------------------------------------------------------------------------------------
function isLowerChar(value) {
 var _lowerValue = 'abcdefghijklmnopqrstuvwxyz';
 var i;
 for(i=0;i<_lowerValue.length;i++)
  if(value == _lowerValue.charAt(i)) {
   return true;
  }

 return false;
}

// -------------------------------------------------------------------------------------------------
// Function name : 특수문자여부체크
// Description   : 특수문자인지를 체크하는 함수(영문이나 한글이 아닌)
// Parameter     : value(체크대상 문자)
// -------------------------------------------------------------------------------------------------
// Usage         : var a='&'; if(isEtcChar(a)) { alert("특수문자입니다"); }
// -------------------------------------------------------------------------------------------------
function isEtcChar(value) {
 var _etcValue   = '~`!@#$%%^&*()-_=+\|[{]};:\'\",<.>/?';
    var j;
    for(j=0;j<_etcValue.length;j++)
        if(value == _etcValue.charAt(j)) {
            return true;
        }
    return false;
}


// -------------------------------------------------------------------------------------------------
// Function name : isEtcChar(value)
// Description   : 특수문자인지를 체크하는 함수(영문이나 한글이 아닌)
// Parameter     : value(체크대상 문자), 문자열이 아님 char하나에 대한 체크가능
// -------------------------------------------------------------------------------------------------
// Usage         : var a='&'; if(cmm_is_etc_char(a)) { alert("특수문자입니다"); }
// -------------------------------------------------------------------------------------------------
function isEtcString(value) {
 var _etcValue   = '~`!@#$%%^&*()-_=+\|[{]};:\'\",<.>/?';
 var i,j;
 for(i=0;i<value.length;i++) {
  for(j=0;j<_etcValue.length;j++)
   if(value.charAt(i) == _etcValue.charAt(j)) {
    return true;
   }
 }
 return false;
}

// -------------------------------------------------------------------------------------------------
// Function name : 영문대문자 변환
// Description   : 영문대문자로 변환하는 함수
// Parameter     : obj(변환대상 문자열을 가지고 있는 화면 컨트롤오브젝트) cmm_to_upper
// -------------------------------------------------------------------------------------------------
// Usage         : 사용자가 소문자로 입력하더라도 DB에는 대문자로 입력하고자 하는 경우
// -------------------------------------------------------------------------------------------------
function getUpperStr(obj) {
  var strNew = '';
 var str = obj.value;
    for(i=0 ; i<str.length; i++ ) {
   if(str.charAt(i) >= 'a' && str.charAt(i) <= 'z')
    strNew += str.charAt(i).toUpperCase() ;
   else
    strNew +=  str.charAt(i);
    }
 
 obj.value = strNew;
}

// 사용빈도 : 중
// 함수명: 몇개의 정해진 문자만 입력가능하도록 검사하는 함수
// 설  명: 정해진 문자열(영문자, 공백, '-', ',')만 입력하는 지를 검사하는 함수
// 인  자: ctl_digit(화면컨트롤)
// --------------------------------------------------------------------------------------------
// 사용법: <input type="text" onBlur="cmm_check_english_body(this)">
// 주의사항: 아래 소스를 변형하여 검사대상문자열을 변경하여 사용
// --------------------------------------------------------------------------------------------
function checkEnglishBody(obj) {
 var str=obj.value;
 if (str.length == 0)
  return false;
 // Checks that characters are numbers or hyphens.
 for (var i = 0; i < str.length; i++) {
  var ch = str.substring(i, i + 1);
  if(ch != "-") {
   if ((ch < "A" || "z" < ch )) {
    if (ch == " ")
      ;
    else if (ch == ",")
     ;
    else
   
    return false;
   }
  }
 }
 return true;
}

// 사용빈도 : 상
// 함수명: 문자열 좌측공백제거
// 설  명: 문자열 좌측의 공백 제거 처리 함수
// 인  자: str(체크대상 문자)
// --------------------------------------------------------------------------------------------
// 사용법: str = cmm_ltrim(str);
// --------------------------------------------------------------------------------------------
function getLtrim(str) {
 while(str.substring(0,1) == ' ')
  str = str.substring(1, str.length);
 return str;
}

// 사용빈도 : 중
// 함수명: 문자열 중간공백제거
// 설  명: 문자열 중간의 공백 제거 처리 함수
// 인  자: str(체크대상 문자)
// --------------------------------------------------------------------------------------------
// 사용법: str = cmm_mtrim(str);
// --------------------------------------------------------------------------------------------
function getMtrim(str) {
 for (i=0; i < str.length;)
  if (str.substring(i,i+1) == ' ')
   str = str.substring(0,i) + str.substring(i+1,str.length);
  else
   i++;

  return str;
}

// 사용빈도 : 상
// 함수명: 문자열 우측공백제거
// 설  명: 문자열 우측의 공백 제거 처리 함수
// 인  자: str(체크대상 문자)
// --------------------------------------------------------------------------------------------
// 사용법: str = cmm_rtrim(str);
// --------------------------------------------------------------------------------------------
function getRtrim(str) {
 while(str.substring(str.length-1,str.length) == ' ')
  str = str.substring(0, str.length-1);
 return str;
}

// 사용빈도 : 상
// 함수명: 공백문자를 제외한 문자열을 리턴하는 함수
// 설  명: 공백만을 제외한 문자열을 리턴(특수문자 등도 같이 리턴)
// 인  자: arg_str(검사대상 문자열)
// --------------------------------------------------------------------------------------------
// 사용법: cmm_str_trim('abc def');
// --------------------------------------------------------------------------------------------
function getStrTrim(arg_str) {
 var rtn_str = "";
 var i=0;
 while(arg_str.charAt(i) != "") {
  if(arg_str.charAt(i)!=' ') {
   rtn_str += arg_str.charAt(i);
  }
  i++;
 }
 return rtn_str;
}

//--------------------------------------------------------------------------------------------
// Function name : getReverse
// Description   : 주어진 문자열을 거꾸로 치환
// Parameter     : str - 치환할 문자
// Return        : 치환된 문자열
//--------------------------------------------------------------------------------------------
// Usage         : getReverse("123") => "321"
//--------------------------------------------------------------------------------------------
function getReverse(Str) {
 var ret = "";

 for (var i = 0; i < Str.length; i++)
  ret = Str.substr(i, 1) + ret;
  
  return ret;
}

//--------------------------------------------------------------------------------------------
// 함수명: 특수문자를 제거하는 함수
// 설  명: 제거하고자 하는 특수문자를 제거하여 리턴하는 함수
// 인  자: str(문자열), sep(제거하고자 하는 특수문자)
// --------------------------------------------------------------------------------------------
// 사용법: <input type="text" onBlur="cmm_remove_special_char(this.value, '-%*');">
// --------------------------------------------------------------------------------------------
function getRmSpChar(str, sep) {
 var sTmp = "";
 var sBuffer = "";
 var i, j;
 var equal=false;

 for (i=0; i < str.length; i++) {
  equal = false;
  sTmp = str.substring(i, i+1);
  for(j=0; j<sep.length;j++) {
   if(sep.charAt(j) == sTmp) {
    equal = true;
    break;
   }
  }

  if(equal == false)
   sBuffer += sTmp;
 }
 //alert(sBuffer);
 return sBuffer;
}

//---------------------------------------------------------------------------------
// Function name : isEmailCheck
// Description   : 텍스트 라인안에 값을 정규식 표현을 사용해서 메일형식(ID@도메인네임)을 검사.
//                 /(\S+)@(\S+)\.(\S+)/
//                 (\S+) : white space 즉, 공백이 아닌 하나 이상의 문자열이 존재
//                  @ : 그 뒤로 골뱅이(at)가 존재하고
//                 (\S+) : 다시 문자열이 존재
//                 \. : (.)dot
//                 (\S+) : 다시 문자열이 존재
// Parameter     : 
// Return        : 
//----------------------------------------------------------------------------------
// Usage         :  isEmailCheck(this)
//----------------------------------------------------------------------------------
function isEmailCheck(email) {
    mvalue = email ;
   
    if (mvalue.value == null || mvalue.value == "") return;
   
    if (mvalue.value.search(/(\S+)@(\S+)\.(\S+)/) == -1) {
   alert ("ID@고유도메인명 형식으로 입력하세요!!\n\n예) test@hanmail.net");
   
   mvalue.value = "";
   mvalue.focus();
   return false;
    } else {
   // alert("입력하신 메일 주소는\n\n" + mvalue.value + "\n\n입니다.");
   return false;
    }
}

//------------------------------------------------------------------
// Function name : fnBluring
// Description   :
// Parameter     :  
// Return        : 
//------------------------------------------------------------------
// Usage         :  
//------------------------------------------------------------------

function fnBluring() {
 if(event.srcElement.tagName=="A"||event.srcElement.tagName=="IMG"||event.srcElement.tagName=="Onclick"||event.srcElement.tagName=="TABLE")
    document.body.focus();
}

//------------------------------------------------------------------
// Function name : fnBsControl
// Description   : 백스페이스 제어
// Parameter     :  
// Return        : 
//------------------------------------------------------------------
// Usage         :  
//------------------------------------------------------------------
function fnBsControl() {
 var d = document;
 //var sw = 0;
   
  if (window.event.keyCode==8) {
  // 등록된 객체이름을 백스페이스 방지
  //if (d.objList == null)
  //{
  //    return false;
  //}
  //else
  //{
  //    for (i=0; i<d.objList.length; i++)
  //    {
  //         if (window.event.srcElement.name == d.objList[i].name)
  //         {
  //            sw = 1;         
  //            break;      
  //         }
  //    }
  //   
  //    if (sw == 0)
  //    {
  //        return false;
  //    }
  //}
 
  // 폼객체의 종류로 백스페이스 방지
  if (window.event.srcElement.type != 'text') {
   return false;   
  }
  }
}

//------------------------------------------------------------------
// Function name : isValidDay
// Description   : 지정 년,월,일이 달력상으로 존재하는 날짜인지 검사
// Parameter     : year - 년 , month - 월 , day - 일 
// Return        : 
//------------------------------------------------------------------
// Usage         :  
//------------------------------------------------------------------
 
function isValidDay(year, month, day) {   
 var m = parseInt(month,10) - 1;
 var d = parseInt(day,10);

 var end = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
 if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
  end[1] = 29;
 }

 return (d >= 1 && d <= end[m]);

Posted by 1010
반응형

The Calendar widget is a JavaScript-based calendar that can either be embedded within a page or popup when a trigger element is clicked. It is based very loosely on the Dynarch Calendar, only in the sense that it was used as a base, but has been almost entirely re-implemented.

Like CalendarView? Try my JavaScript list selection tool, MatrixView!

Features

  • Developed with CSS in Mind
    In CalendarView you will find no embedded style or presentation. You are encouraged to make it look how you want it to look so that it looks like it belongs in your project.
  • Embedded or Popup — You Decide!
    CalendarView can be either embedded into your page or used as a pop-up. The choice is yours!
  • Lightweight and Easy to Use
    Frustrated with the complexity and bloatedness of existing calendars, CalendarView was implemented as a lightweight alternative.
  • Utilizes the Prototype Framework
    CalendarView uses the Prototype JavaScript framework, lessening the overall JavaScript impact if Prototype is already being used in your project.

Examples

Embedded Calendar

April 2009
« Today »
S M T W T F S
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 1 2

2009-04-08

Popup Calendar

2009-03-08

Download

CalendarView requires Prototype 1.6.0 (or later).

You may also access the source code at GitHub.

Release History

Version 1.1 — October 19th, 2008

  • Upgraded to Prototype 1.6 and cleaned up code to take full advantage of its new API features.
  • Removed our dependency on Builder from script.aculo.us, as Prototype 1.6 has its own DOM Builder now
  • Fixed a bug where navigating through months of the calendar would display the wrong year when you reached December. Thanks to Dirk Koritnik for the fix and to everyone who reported the issue.

Version 1.0 — March 12th, 2007

  • Initial release

Development Roadmap

  • Add support for assigning an HTML ID and CSS classes to the Calendar at time of creation
  • Reuse Calendar objects for Popup Calendars instead of creating new objects
  • Cleanup, extract, or remove the Date object extensions

Support CalendarView Development

CalendarView is developed in the author's spare time. If you find it to be useful within your web application, please consider making a small donation to support and encourage future development.

Usage Instructions

Options

Option Description
dateField An HTML element (or DOM ID) that will be updated when a date is selected. Can be an INPUT field or any other JavaScript object that has either innerHTML or value attributes. The value of this field will also be parsed for setting the current date when the Calendar is initialized.
triggerElement An HTML element (or DOM ID) that will be observed for clicks to display a popup calendar. If a triggerElement is not specified, the dateField will be observed instead.
parentElement An HTML element (or DOM ID) that will receive the initialized embedded calendar.
selectHandler JavaScript function that will be called when a date is selected. Only define this if you want to override the default behavior.
closeHandler JavaScript function that will be called when the calendar should be closed (either after a selection has been made or if the user clicked outside of the calendar's container element). This only applies to popup calendars and should only be defined if you want to override the default behavior.

Setting up an Embedded Calendar

Embedded calendars require a parent element so that it can be appended to the DOM, such as a div element.

Embedded Calendar Example

<html>
  <head>
    ...
    <script type="text/javascript" src="prototype.js"></script>
    <script type="text/javascript" src="calendarview.js"></script>
    <script type="text/javascript">
      window.onload = function() {
        Calendar.setup({
          dateField     : 'date',
          parentElement : 'calendar'
        })
      }
    </script>
    ...
  </head>
  <body>
    ...
    <div id="calendar"></div>
    <div id="date">Select Date</div>
    ...
  </body>
</html>

Setting up a Popup Calendar

Popup calendars require a trigger element that will display the calendar when clicked. By default, the element defined as the dateField will trigger the calendar if a triggerElement has not been specified.

Popup Calendar Example

<html>
  <head>
    ...
    <script type="text/javascript" src="prototype.js"></script>
    <script type="text/javascript" src="calendarview.js"></script>
    <script type="text/javascript">
      window.onload = function() {
        Calendar.setup({
          dateField      : 'date',
          triggerElement : 'calendarButton'
        })
      }
    </script>
    ...
  </head>
  <body>
    ...
    <input type="text" name="date" id="date" />
    <input type="button" id="calendarButton" value="Show Calendar" />
    ...
  </body>
</html>

Styling the Calendar

The calendar is meant to be styled entirely with CSS. A few CSS classes are declared in the HTML output to assist in styling, but for the most part it should be styled with standard CSS element selectors.

Example HTML Output

<div class="calendar popup">
  <table>
    <thead>
      <tr>
        <td class="title" colspan="7">March 2007</td>
      </tr>
      <tr>
        <td class="button">«</td>
        <td class="button">‹</td>
        <td class="button" colspan="3">Today</td>
        <td class="button">›</td>
        <td class="button">»</td>
      </tr>
      <tr>
        <th class="weekend">S</th>
        <th>M</th>
        <th>T</th>
        <th>W</th>
        <th>T</th>
        <th>F</th>
        <th class="weekend">S</th>
      </tr>
    </thead>
    <tbody>
      <tr class="days">
        <td class="otherDay weekend">25</td>
        <td class="otherDay">26</td>
        <td class="otherDay">27</td>
        <td class="otherDay">28</td>
        <td>1</td>
        <td>2</td>
        <td class=" weekend">3</td>
      </tr>
      <tr class="days">
        <td class="weekend">4</td>
        <td>5</td>
        <td class="selected">6</td>
        <td>7</td>
        <td>8</td>
        <td>9</td>
        <td class="weekend">10</td>
      </tr>
      <tr class="days">
        <td class="weekend">11</td>
        <td class="today">12</td>
        <td>13</td>
        <td>14</td>
        <td>15</td>
        <td>16</td>
        <td class="weekend">17</td>
      </tr>
      <tr class="days">
        <td class="weekend">18</td>
        <td>19</td>
        <td>20</td>
        <td>21</td>
        <td>22</td>
        <td>23</td>
        <td class="weekend">24</td>
      </tr>
      <tr class="days">
        <td class="weekend">25</td>
        <td>26</td>
        <td>27</td>
        <td>28</td>
        <td>29</td>
        <td>30</td>
        <td class="weekend">31</td>
      </tr>
    </tbody>
  </table>
</div>
Posted by 1010
반응형
Posted by 1010
반응형
<script language="javascript">
function printWindow() {
factory.printing.header = ""
factory.printing.footer = ""
factory.printing.portrait = true
factory.printing.leftMargin = 0.45
factory.printing.topMargin = 0.45
factory.printing.rightMargin = 0.45
factory.printing.bottomMargin = 0.0
factory.printing.Print(true, window);
}
</script>
</head>

<body link=blue vlink=purple onload="printWindow();" topmargine="18">
<object id=factory style="display:none" classid="clsid:1663ed61-23eb-11d2-b92f-008048fdd814" codebase="/smrcptroot/print/smsx.cab#Version=6,4,438,06">
</object>
.
.
.
<%
// dataPerPage : 한 페이지에 보여줄 data 갯수
// currentPage : 현재 페이지
// totalPage : 전체 페이지
int dataPerPage = 2;
int currentPage = 0;
int totalPage = data.size() / dataPerPage;
if ((data.size() % dataPerPage) > 0) totalPage += 1;

for (int i = 0; i < totalPage; i++) {
currentPage = i + 1;

%>
Posted by 1010
반응형
<html>
<head>
    <title>http://technote.co.kr</title>
<style>
    #bannerbox .oherpromotion {display:inline; position:relative; float:left; margin:3px 11px 0 0 ; }
    #bannerbox .oherpromotion h3 {float:left; width:188px; height:20px; background:url(http://imgshopping2.naver.com/2007/new/main/bg_oftenview.gif) no-repeat left top; color:#666; font-weight:normal; font-size:12px; text-align:left; letter-spacing:-1px}
    #bannerbox .oherpromotion h3 a {display:block; width:184px; height:16px; padding:4px 0 0 7px; color:#666; text-decoration:none;}
    #bannerbox .oherpromotionlist {position:absolute; left:0px; top:18px; width:188px; background:url(http://imgshopping2.naver.com/2007/new/main/bg_ranking_list_mid.gif) repeat-y left top; z-index:100;}
    #bannerbox .oherpromotioninner {background:url(http://imgshopping2.naver.com/2007/new/main/bg_ranking_list_bottom.gif) no-repeat left bottom;}
    #bannerbox .oherpromotionlist ul {width:158px; margin:0 8px; padding:3px 0; overflow:hidden;}
    #bannerbox .oherpromotionlist li {width:100%; padding:6px 0 4px 0; background:url(http://imgshopping2.naver.com/2007/new/rankingshop/dot_gray01.gif) repeat-x left top; font-size:12px; vertical-align:top; line-height:1em; letter-spacing:-1px; text-align:left;}
    #bannerbox .oherpromotionlist li a {padding-left:15px; background:url(http://imgshopping2.naver.com/2007/new/rankingshop/bu_arrow02.gif) no-repeat 3px top; color:#7f7f7f;}
    #bannerbox .oherpromotionlist li a:hover {color:#64a32f;}

</style>
<script>
function toggleView(target){
    var sTarget = target.href.split("#");
    var aTarget = document.getElementById(sTarget[sTarget.length-1]);
    if(aTarget.style.display == "none") aTarget.style.display = "block";
    else aTarget.style.display = "none";   
}
</script>
</head>
<body>
<div id="bannerbox">
    <div class="oherpromotion">
    <h3><a href="#oherpromotionview" onClick="toggleView(this); return false;" onfocus=this.blur()>네이버 콤보스타일 메뉴</a></h3>
        <div id="oherpromotionview" class="oherpromotionlist" style="display:none;">
            <div class="oherpromotioninner">
                <ul>
                    <li><A HREF="http://technote.co.kr">테크 1</A>
                    <li><A HREF="http://technote.co.kr">테크 2</A>
                    <li><A HREF="http://technote.co.kr">테크 3</A>
                    <li><A HREF="http://technote.co.kr">테크 4</A>
                    <li><A HREF="http://technote.co.kr">테크 5</A>
                    <li><A HREF="http://technote.co.kr">테크 6</A>
                    <li><A HREF="http://technote.co.kr">테크 7</A>
                    <li><A HREF="http://technote.co.kr">테크 8</A>
                    <li><A HREF="http://technote.co.kr">테크 9</A>
                    <li><A HREF="http://technote.co.kr">테크 10</A>
                </ul>
            </div>
        </div>
    </div>
</div>
</body>
 
Posted by 1010
반응형

<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=euc-kr">

<style>
.ellipsis  {font:9pt "굴림"; width:100%; overflow:hidden; text-overflow:ellipsis; text-align:left; }
.colresize {font:9pt "굴림"; cursor:""; }
.input_box {width:expression(this.parentNode.clientWidth-8); }
</style>

<SCRIPT LANGUAGE="JavaScript">
<!--
// 자료출처 : phpschool.com ==> kisses
var mousedown = false; //마우스를 누른 상태
var td = "";           //사이즈 변경할 td
var td_width;          //변경할 td의 width,
var x = 0;             //마우스 드레그전 가로위치

function TCstartColResize(obj){
       mousedown = true;
       td = obj;
       td_width = td.width;
       x = event.clientX;
}
function TCColResize()
{
       if (mousedown){
              var distX = event.x - x; //이동한 간격
              td.width = parseInt(td_width) + parseInt(distX);
       }
}
function TCstopColResize(){
       mousedown = false;
       td = '';
}

function cell_left(obj){//마우스가 셀의 왼쪽인지 측정
       if(event.offsetX < 5 && obj.cellIndex!=0)
              return true;
       else
              return false;
}
function cell_right(obj){//마우스가 셀의 오른쪽인지 측정
       if(event.offsetX > obj.width-4)
              return true;
       else
              return false;
}

//리사이즈시작
document.onmousedown = function(){
try{
       var now_mousedown = window.event.srcElement;
       if(now_mousedown.className.toUpperCase()=="COLRESIZE"){
              if( cell_left(now_mousedown) ){
                     now_mousedown = now_mousedown.parentNode.childNodes[now_mousedown.cellIndex-1];
              }else if( !cell_right(now_mousedown) ){
                     return true;//오른쪽도 왼쪽도 아니면 사이즈 조절 안함
              }
              TCstartColResize(now_mousedown);
       }
}catch(e){ return true; }
}

//리사이즈
document.onmousemove = function(){
try{
       var now_mousemove = window.event.srcElement;
       if(now_mousemove.className.toUpperCase()=="COLRESIZE" || td!=""){

              //셀의 가장자리면 마우스 커서 변경
              if( cell_left(now_mousemove) || cell_right(now_mousemove) ){
                     now_mousemove.style.cursor = "col-resize";
              }else{
                     now_mousemove.style.cursor = "";
              }

              TCColResize(now_mousemove);
       }else{
              now_mousemove.style.cursor = "";
    }
}catch(e){ return true; }
}

//리사이즈종료
document.onmouseup = function(){
try{
       var now_mouseup = window.event.srcElement;
       //if(now_mouseup.className=="colResize"){
              TCstopColResize(now_mouseup);
       //}
}catch(e){ return true; }
}

//리사이즈 도중 텍스트 선택 금지
document.onselectstart = function(){
try{
    if(td != ""){
        return false;
    }
}catch(e){ return true; }
}
//-->
</SCRIPT>
</HEAD>

<BODY>
<div style="width:100%;height:100;overflow-x:auto;overflow-y:auto">
    <table width="430" border="0" cellpadding="3" cellspacing="1" bgcolor="#B8B8B8" nowrap style='table-layout:fixed'>
        <tr bgcolor="#A5D4D2" align="center" height="25">
            <td width="35"  class="colresize">선택</td>
            <td width="35"  class="colresize">순번</td>
            <td width="70" class="colresize">품목명</td>
            <td width="30"  class="colresize">수량</td>
            <td width="50"  class="colresize">단위</td>
            <td width="70"  class="colresize">날짜</td>
            <td width="70"  class="colresize">장소</td>
            <td width="70" class="colresize">비고</td>
        </tr>
        <tr bgcolor="#FFFFFF" height="27" align="center">
            <td><Input type="radio" name="radio"></td>
            <td>1</td>
            <td><input type='text' class="input_box"></td>
            <td><input type='text' class="input_box"></td>
            <td><select class="input_box"><option>EA</option></select></td>
            <td><input type='text' class="input_box"></td>
            <td><input type='text' class="input_box"></td>
            <td nowrap class="ellipsis">비고 비고 비고 비고 비고 비고 비고 비고 비고</td>
        </tr>
    </table>
</div>
</BODY>
</HTML>

Posted by 1010
반응형

<style type="text/css">

#minitabs{
margin:0;
padding: 0 0 20px 10px;
border-bottom: 1px solid #696;
}

#minitabs li{
margin: 0;
padding: 0;
display: inline;
list-style-type:none;
}



#minitabs a{
 float: left;
 line-height: 14px;
 font-weight: bold;
 margin: 0 10px 4px 10px;
 text-decoration:none;
 font-size: 12px;
 color: #9c9; // 처음 보이는 기본 색깔
}


#minitabs a.active, #minitabs a:hover {
 border-bottom: 4px solid #232; // 글씨 위에 마우스 올릴때  라인 색깔
 padding-bottom: 2px; //글씨에 라인이 떨어질 위치(거리)

 color: #344;  // active 되었을때 색깔
}


 

#minitabs a:hover{
color: #696; // 글씨 위에 마우스 올릴때 색깔
}


</style>


<body>

<ul id="minitabs">
<li><a href="#" class="active">링크</a></li>   // 하이라이트된 탭이 계속 켜져있게 하기
<li><a href="#">책</a></li>
<li><a href="#">영화</a></li>
<li><a href="#">음악</a> </li>
</ul>
</body>

Posted by 1010
반응형

사용자 삽입 이미지



<script language="javascript">

var fixedX = -1; ////////// 레이어 X축 위치 (-1 : 버튼에 바로 아래에 표시)
var fixedY = -1; ////////////// 레이어 Y축 위치 (-1 : 버튼에 바로 아래에 표시)
var startAt = 0; ///////////// 일요일 표시 부분 / 0 : 일요일(일월화...) / 1 : 월요일(...금토일)
var showToday = 1; // 오늘 날자 표시 유무 - 0 : 감춤 / 1 : 보임
var imgDir = './'; // 이미지 디렉토리 - ./ : 현재 디렉토리

/////////////////////////////// 각 변수 선언 ///////////////////
var crossobj, crossMonthObj, crossYearObj, monthSelected, yearSelected, dateSelected, omonthSelected, oyearSelected, odateSelected, monthConstructed, yearConstructed, intervalID1, intervalID2, timeoutID1, timeoutID2, ctlToPlaceValue, ctlNow, dateFormat, nStartingMonth, nStartingYear

var bPageLoaded = false;
var ie = document.all;
var dom = document.getElementById;
var bShow = false;
var ns4 = document.layers;

var today = new    Date(); /////////////// 날자 변수 선언
var dateNow = today.getDate(); //////////////// 로컬 컴퓨터의 일(day)을 구함 
var monthNow = today.getMonth(); ///////////////// 로컬 컴퓨터의 월(month)을 구함
var yearNow = today.getYear(); ///////////////// 로컬 컴퓨터의 년(year)을 구함

var    monthName =    new    Array("1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월")
var    monthName2 =    new    Array("1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월")

if (startAt==0) {
    dayName = new Array    ("일","월","화","수","목","금","토")
} else {
    dayName = new Array    ("월","화","수","목","금","토","일")
}
var oPopup = window.createPopup();
var oPopBody = oPopup.document.body;
var strCalendar;
var cleft;
var ctop;

if(dom) {
    strCalendar = "<img src='' width=0 height=0>";
    strCalendar += "<style type='text/css'>";
    strCalendar += "td {font-size:12px; font-family:굴림; text-decoration:none; }";
    strCalendar += "A:link,A:active,A:visited{text-decoration:none;font-size:12PX;color:#333333;}";
    strCalendar += "A:hover {text-decoration:none; color:ff9900}";
    strCalendar += "font { font-size: 9pt; }";
    strCalendar += ".cnj_close {font-size:8pt;color:#000000; background-color:#EFEFEF; border-width:1; border-color:#808080; border-style:solid;cursor:hand;font-weight:bold;height:16px;width:16px;text-align:center;vertical-align:bottom}";
    strCalendar += ".cnj_close2 {font-size:8pt;color:#000000; background-color:#EFEFEF; border-width:1; border-color:#808080; border-style:solid;cursor:hand;font-weight:bold;height:16px;width:16px;text-align:center;vertical-align:bottom}";
    strCalendar += ".cnj_input {background-color:rgb(240,240,240);border-width:1pt; height:16pt;cursor:hand;}";
    strCalendar += ".cnj_input2 {font-size:8pt;color:#808080; background-color:#EFEFEF; border-width:1; border-color:#808080; border-style:solid;cursor:hand;height:16px;}";
    strCalendar += ".cnj_input3 {font-size:8pt;color:#000000; background-color:#FFFFFF; border-width:1; border-color:#C00000; border-style:solid;cursor:hand;height:16px;}";
    strCalendar += ".cnj_input4 {font-size:8pt;color:#C00000; background-color:#FFFFFF; border-width:1; border-color:#808080; border-style:solid;cursor:hand;height:16px;}";
    strCalendar += ".cnj_td {border-width:1;border-style:solid;border-color:#a0a0a0;}";
    strCalendar += "</style>";

    strCalendar += "<div id='calendar' style='z-index:+999;position:absolute;;'>";
    strCalendar += "<table width='190' class='cnj_td'>";
    strCalendar += "    <tr bgcolor='#EEEEEE' height=20>";
    strCalendar += "        <td>";
    strCalendar += "            <table width='188' border=0>";
    strCalendar += "                <tr height=20>";
    strCalendar += "                    <td style='padding:0px;'><font color='#ffffff'><B><span id='caption'></span></B></font></td>";
    strCalendar += "                    <td align=right><input type='button' value='x' class='cnj_close' title='닫기' onclick='parent.oPopup.hide()' onfocus='this.blur()' onMouseover=\"this.className='cnj_close2'\" onMouseout=\"this.className='cnj_close'\"></td>";
    strCalendar += "                </tr>";
    strCalendar += "            </table>";
    strCalendar += "        </td>";
    strCalendar += "    </tr>";
    strCalendar += "    <tr height=1>";
    strCalendar += "        <td style='padding:3px' bgcolor=#ffffff><span id='content'></span></td>";
    strCalendar += "    </tr>";
           
    if(showToday==1) {
        strCalendar += "<tr bgcolor=#f0f0f0 height=20><td style='padding:5px' align=center><span id='lblToday'></span></td></tr>";
    }
           
    strCalendar += "</table>";
    strCalendar += "</div>";
    strCalendar += "<div id='selectMonth' style='z-index:+999;position:absolute;display:none;'></div> ";
    strCalendar += "<div id='selectYear' style='z-index:+999;position:absolute;display:none;'></div>";
    oPopBody.innerHTML = strCalendar;
}

function init() {
    if(!ns4) {
        if(!ie) {
            yearNow += 1900;
        }

        crossobj = oPopBody.all.calendar;
        crossMonthObj = oPopBody.all.selectMonth;
        crossYearObj = oPopBody.all.selectYear;
        monthConstructed = false;
        yearConstructed = false;

        sHTML1="<input type='button' value='◀' class='cnj_input2' onClick='javascript:parent.movedecMonth()' onfocus='this.blur()' title='이전 달(월)로 이동' "
        sHTML1+="onMouseover=\"this.className='cnj_input3';window.status='이전 달(월)로 이동'\" onMouseout=\"this.className='cnj_input2';window.status=''\"> </span> "

        sHTML1+="<input type='button' value='▶'  class='cnj_input2' onClick='javascript:parent.moveincMonth()' onfocus='this.blur()' title='다음 달(월)로 이동' "
        sHTML1+="onMouseover=\"this.className='cnj_input3';window.status='다음 달(월)로 이동'\"  onMouseout=\"this.className='cnj_input2';window.status=''\"> </span> "

        sHTML1+="<span id='spanMonth'  class='cnj_input4' onclick='parent.popUpMonth()' title='월 선택' "
        sHTML1+="onMouseover=\"this.className='cnj_input3';window.status='월 선택'\" onMouseout=\"this.className='cnj_input4';window.status=''\"></span>&nbsp;";

        sHTML1+="<span id='spanYear'  class='cnj_input4' onclick='parent.popUpYear()' title='년도 선택' "
        sHTML1+="onMouseover=\"this.className='cnj_input3';window.status='년도 선택'\" onMouseout=\"this.className='cnj_input4';window.status=''\"></span> ";

        oPopup.document.getElementById("caption").innerHTML = sHTML1;
        bPageLoaded = true;
       
        if(showToday==1) {
            oPopup.document.getElementById("lblToday").innerHTML =    ""+
            "<div onmousemove='window.status=\"오늘 날짜로 표시하기\"' onmouseout='window.status=\"\"' title='오늘 날짜로 표시하기' "+
            //" style='"+styleAnchor+"' href='javascript:monthSelected=monthNow;yearSelected=yearNow;constructCalendar();' onFocus='this.blur()'>"+
            " style='"+styleAnchor+"' onclick=parent.totoday() onFocus='this.blur()'>"+
            "오늘 날짜 :  "+yearNow+"년 "+
            ""+monthName[monthNow].substring(0,3)+" "+
            ""+dateNow+"일 "+  // 일
            "</div>";
        }       
    }
}

function totoday(){ // 오늘 날짜로 표시하기
    monthSelected=monthNow;
    yearSelected=yearNow;
    constructCalendar();
}

function HolidayRec(d, m, y, desc) {
    this.d = d;
    this.m = m;
    this.y = y;
    this.desc = desc;
}

var HolidaysCounter = 0;
var Holidays = new Array();

function addHoliday(d, m, y, desc) {
    Holidays[HolidaysCounter++] = new HolidayRec ( d, m, y, desc );
}

var styleAnchor = "text-decoration:none;color:black;cursor:hand;width:100%;height:100%";
var styleLightBorder = "border-style:solid;border-width:1px;border-color:#a0a0a0;text-decoration:underline;font-weight:bold;cursor:hand;width:100%;height:100%";

function padZero(num) {
    return (num < 10)? '0' + num : num;
}

function constructDate(d,m,y) {
    sTmp = dateFormat
    sTmp = sTmp.replace("dd","<e>");
    sTmp = sTmp.replace("d","<d>");
    sTmp = sTmp.replace("<e>",padZero(d));
    sTmp = sTmp.replace("<d>",d);
    sTmp = sTmp.replace("mmmm","<p>");
    sTmp = sTmp.replace("mmm","<o>");
    sTmp = sTmp.replace("mm","<n>");
    sTmp = sTmp.replace("m","<m>");
    sTmp = sTmp.replace("<m>",m+1);
    sTmp = sTmp.replace("<n>",padZero(m+1));
    sTmp = sTmp.replace("<o>",monthName[m]);
    sTmp = sTmp.replace("<p>",monthName2[m]);
    sTmp = sTmp.replace("yyyy",y);

    return sTmp.replace("yy",padZero(y%100));
}

function closeCalendar() {
    oPopup.hide();
    ctlToPlaceValue.value =    constructDate(dateSelected,monthSelected,yearSelected);
}

function moveincMonth() {
    monthSelected++;

    if (monthSelected>11) {
        monthSelected=0;
        yearSelected++;
    }
    constructCalendar();
}

function movedecMonth() {
    monthSelected--;

    if (monthSelected<0) {
        monthSelected=11;
        yearSelected--;
    }
    constructCalendar();
}

function incMonth() {
    if (nStartingMonth + 6 == 12) return;
    for(i = 0; i < 7; i++) {
        newMonth = (i + nStartingMonth) + 1;

        if (newMonth > 12) {nStartingMonth--; break;}
        if (newMonth == monthSelected + 1) {
            txtMonth = " <B>"+ newMonth +"월</B> ";
        } else {
            txtMonth = " " + newMonth + "월";
        }
        oPopup.document.getElementById("m"+i).innerHTML = txtMonth;
    }
    nStartingMonth++;
    bShow = true;
}

function decMonth() {
    if (nStartingMonth == 1) return;
    for (i=0; i<7; i++) {
        newMonth    = (i+nStartingMonth)-1;

        if (newMonth < 1) {nStartingMonth++; break;}
        if (newMonth==monthSelected + 1) {
            txtMonth = " <B>"+ newMonth +"월</B> ";
        } else {
            txtMonth = " " + newMonth + "월";
        }
        oPopup.document.getElementById("m"+i).innerHTML = txtMonth;
    }
    nStartingMonth--;
    bShow = true;
}

function selectMonth(nMonth) {
    monthSelected = parseInt(nMonth + nStartingMonth - 1);
    monthConstructed = false;
    constructCalendar();
    popDownMonth();
}

function constructMonth() {
    popDownYear();
    sHTML =    "";

    if(!monthConstructed) { // 월 이전 월 링크
        sHTML ="<tr><td align='center' style='cursor:pointer'     "
        sHTML +="    onmouseover='this.style.backgroundColor=\"#FFCC99\"' "
        sHTML +="    onmouseout='clearInterval(parent.intervalID1);this.style.backgroundColor=\"\"'  "
        sHTML +="    onmousedown='clearInterval(parent.intervalID1);parent.intervalID1=setInterval(\"parent.decMonth()\",30)' "
        sHTML +="    onmouseup='clearInterval(parent.intervalID1)'> "
        sHTML +="    ▲</td></tr>";
        j = 0;
       
        var nSelectedMonth = monthSelected + 1;
       
        nStartingMonth = (nSelectedMonth - 3) < 1 ? 1 : nSelectedMonth - 3; //시작월 - 3 이 1보다 작으면 1로 고정
        nStartingMonth = nStartingMonth > 6 ? 6 : nStartingMonth; //시작월이 6보다 크면 6로 고정 (6 시작 월 + 목록 숫자 6 = 12 종료 월)

        var nEndMonth = (nSelectedMonth + 3) > 12 ? 12 : (nSelectedMonth + 3); // 종료월 + 3이 12보다 크면 12로 고정
        nEndMonth = nEndMonth < 7 ? 7 : nEndMonth; //종료 월이 7보다 작으면 7로 고정
       
        for (i = nStartingMonth; i <= nEndMonth; i++) {
            sName =    i;

            //////////////// 현재 월 ////////////////////////
            if (i == nSelectedMonth) { sName = "<b>" + sName + "</b>" }
            sHTML +="<tr><td height='15' id='m" + j + "' onmouseover='this.style.backgroundColor=\"#FFCC99\"' onmouseout='this.style.backgroundColor=\"\"' "
            sHTML +=" style='cursor:pointer' onClick='parent.selectMonth("+j+");event.cancelBubble=true'> " + sName + "월"
            sHTML +="</td></tr>";
            j ++;
        }
       
         // 월 다음 월 링크
        sHTML += "<tr><td align='center' onmouseover='this.style.backgroundColor=\"#FFCC99\"' style='cursor:pointer' "
        sHTML += " onmouseout='clearInterval(parent.intervalID2);this.style.backgroundColor=\"\"' "
        sHTML += " onmousedown='clearInterval(parent.intervalID2);parent.intervalID2=setInterval(\"parent.incMonth()\",30)'    "
        sHTML += " onmouseup='clearInterval(parent.intervalID2)'> "
        sHTML += " ▼</td></tr>";

          /////// 월 표 크기 ///////////////////////////////
        oPopup.document.getElementById("selectMonth").innerHTML    = ""+
        "<table width='50' style='font-family:굴림; font-size:11px; border-width:1; border-style:solid; border-color:#a0a0a0;' bgcolor='#FFFFDD' "+
        " onmouseover='clearTimeout(parent.timeoutID2)' "+
        " onmouseout='clearTimeout(parent.timeoutID2);parent.timeoutID2=setTimeout(\"parent.popDownMonth()\",100)' cellspacing=0>"+
        ""+ sHTML    + ""+
        "</table>";
        monthConstructed    = true;
    }
}

function popUpMonth() {
    constructMonth();
    crossMonthObj.style.display = "";
    crossMonthObj.style.left = crossobj.style.left + 50;
    crossMonthObj.style.top = crossobj.style.top + 26;
}

function popDownMonth()    {
    crossMonthObj.style.display = "none";
}

function incYear() {
    for(i=0; i<7; i++) {
        newYear    = (i+nStartingYear)+1;

        if (newYear==yearSelected) {
            txtYear = " <B>"+ newYear +"년  </B> ";
        } else {
            txtYear = " " + newYear + "년  ";
        }
        oPopup.document.getElementById("y"+i).innerHTML = txtYear;
    }
    nStartingYear++;
    bShow = true;
}

function decYear() {
    for (i=0; i<7; i++) {
        newYear    = (i+nStartingYear)-1;

        if (newYear==yearSelected) {
            txtYear = " <B>"+ newYear +"년  </B> ";
        } else {
            txtYear = " " + newYear + "년  ";
        }
        oPopup.document.getElementById("y"+i).innerHTML = txtYear;
    }
    nStartingYear--;
    bShow = true;
}

function selectYear(nYear) {
    yearSelected = parseInt(nYear+nStartingYear);
    yearConstructed = false;
    constructCalendar();
    popDownYear();
}

function constructYear() {
    popDownMonth();
    sHTML =    "";

    if(!yearConstructed) { // 년도 이전 년도 링크
        sHTML ="<tr><td align='center' style='cursor:pointer'     "
        sHTML +="    onmouseover='this.style.backgroundColor=\"#FFCC99\"' "
        sHTML +="    onmouseout='clearInterval(parent.intervalID1);this.style.backgroundColor=\"\"'  "
        sHTML +="    onmousedown='clearInterval(parent.intervalID1);parent.intervalID1=setInterval(\"parent.decYear()\",30)' "
        sHTML +="    onmouseup='clearInterval(parent.intervalID1)'> "
        sHTML +="    ▲</td></tr>";
        j = 0;
        nStartingYear =    yearSelected-3;

        for (i=(yearSelected-3); i<=(yearSelected+3); i++) {
            sName =    i;

            if (i==yearSelected) { sName =    "<b>" +    sName +    "</b>" }
            sHTML +="<tr><td height='15' id='y" + j + "' onmouseover='this.style.backgroundColor=\"#FFCC99\"' onmouseout='this.style.backgroundColor=\"\"' "
            sHTML +=" style='cursor:pointer' onClick='parent.selectYear("+j+");event.cancelBubble=true'> " + sName + "년  "
            sHTML +="</td></tr>";
            j ++;
        }
       
         // 년도 다음 년도 링크
        sHTML += "<tr><td align='center' onmouseover='this.style.backgroundColor=\"#FFCC99\"' style='cursor:pointer' "
        sHTML += " onmouseout='clearInterval(parent.intervalID2);this.style.backgroundColor=\"\"' "
        sHTML += " onmousedown='clearInterval(parent.intervalID2);parent.intervalID2=setInterval(\"parent.incYear()\",30)'    "
        sHTML += " onmouseup='clearInterval(parent.intervalID2)'> "
        sHTML += " ▼</td></tr>";

         /////// 년도 표 크기 ///////////////////////////////
        oPopup.document.getElementById("selectYear").innerHTML    = ""+
        "<table width='55' style='font-family:굴림; font-size:11px; border-width:1; border-style:solid; border-color:#a0a0a0;' bgcolor='#FFFFDD' "+
        " onmouseover='clearTimeout(parent.timeoutID2)' "+
        " onmouseout='clearTimeout(parent.timeoutID2);parent.timeoutID2=setTimeout(\"parent.popDownYear()\",100)' cellspacing=0>"+
        ""+ sHTML    + ""+
        "</table>";
        yearConstructed    = true;
    }
}

function popDownYear() {
    clearInterval(intervalID1);
    clearTimeout(timeoutID1);
    clearInterval(intervalID2);
    clearTimeout(timeoutID2);
    crossYearObj.style.display = "none";
}

function popUpYear() {
    constructYear();
    crossYearObj.style.display = "";
    crossYearObj.style.left = crossobj.style.left + (6 + oPopup.document.getElementById("spanYear").offsetLeft) + "px";
    crossYearObj.style.top = crossobj.style.top + 26;
}

function constructCalendar() {
    var aNumDays = Array (31,0,31,30,31,30,31,31,30,31,30,31);
    var dateMessage;
    var startDate =    new Date (yearSelected,monthSelected,1);
    var endDate;
    var intWeekCount = 1;
   
    if(monthSelected==1) {
        endDate    = new Date (yearSelected,monthSelected+1,1);
        endDate    = new Date (endDate    - (24*60*60*1000));
        numDaysInMonth = endDate.getDate();
    } else {
        numDaysInMonth = aNumDays[monthSelected];
    }

    datePointer = 0;
    dayPointer = startDate.getDay() - startAt;
       
    if(dayPointer<0) {
        dayPointer = 6;
    }
    sHTML =    "<table     border=0 style='font-family:verdana;font-size:10px;'><tr height=16>";

    for(i=0; i<7; i++) {   /////// 요일 ///////////////////////
        sHTML += "<td width='27' align='right'><B>"+ dayName[i]+"</B></td>";
    }
    sHTML +="</tr><tr height=16>";
       
    for(var i=1; i<=dayPointer;i++)    {  // 빈 날짜
        sHTML += "<td> </td>";
    }
   
    for(datePointer=1; datePointer<=numDaysInMonth; datePointer++) {
        dayPointer++;
        sHTML += "<td align=right>";
        sStyle = styleAnchor;

        if((datePointer==odateSelected) && (monthSelected==omonthSelected) && (yearSelected==oyearSelected)) {
            sStyle += styleLightBorder;
        }
        sHint = "";

        for(k=0;k<HolidaysCounter;k++) {
            if((parseInt(Holidays[k].d)==datePointer)&&(parseInt(Holidays[k].m)==(monthSelected+1))) {
                if((parseInt(Holidays[k].y)==0)||((parseInt(Holidays[k].y)==yearSelected)&&(parseInt(Holidays[k].y)!=0))) {
                    sStyle+="background-color:#FFDDDD;";
                    sHint+=sHint==""?Holidays[k].desc:"\n"+Holidays[k].desc;
                }
            }
        }
        var regexp= /\"/g;
        sHint=sHint.replace(regexp,"&quot;");
        /////////////// 날짜 선택시 ==> 마우스가 날짜 위로 갔을때 ///////////////////////////////
        dateMessage = "title=' 날짜 선택 : "+ yearSelected + "년 " +    monthName[monthSelected] +" "  + datePointer + "일"+"' onmousemove='window.status=\" 날짜 선택 : "+ yearSelected + "년 " +    monthName[monthSelected] +" "  + datePointer + "일"+"\"' onmouseout='window.status=\"\"' ";

        if((datePointer == dateNow) && (monthSelected == monthNow) && (yearSelected == yearNow)) {  // 현재 오늘 날짜
            sHTML += "<b><div style='"+sStyle+"' onclick='javascript:parent.dateSelected="+datePointer+";parent.closeCalendar();'><font color=#0000C0> " + datePointer + "</font> </div></b>";
        } else
        if((dayPointer % 7 == (startAt * -1)+1) || (dayPointer % 7 == (startAt * -1))) {  // 일요일, 토요일일때
            sHTML += "<div style='"+sStyle+"' onclick='javascript:parent.dateSelected="+datePointer + ";parent.closeCalendar();'> <font color=red>" + datePointer + "</font> </div>";
        } else {
            sHTML += "<div style='"+sStyle+"' onclick='javascript:parent.dateSelected="+ datePointer + ";parent.closeCalendar();'>" + datePointer + "</div>";
        }
        sHTML += "";

        if((dayPointer+startAt) % 7 == startAt) {
            sHTML += "</tr><tr height=16>";
            intWeekCount ++;
        }
    }
    sHTML += "</tr>";
    sHTML = sHTML.replace("<tr height=16></tr>", "");
    if (((dayPointer+startAt) % 7) == 0) intWeekCount--;
    oPopup.document.getElementById("content").innerHTML = sHTML; 
    //////// 셀릭트 월 선택
    oPopup.document.getElementById("spanMonth").innerHTML = " " +    monthName[monthSelected] + " <input type='button'  id='changeMonth'value='▼'  class='cnj_input2' onfocus='this.blur()' onMouseover=\"this.className='cnj_input3'\" onMouseout=\"this.className='cnj_input2'\">"

    //////// 셀릭트 년도 선택
    oPopup.document.getElementById("spanYear").innerHTML =    " " + yearSelected    + "년 <input type='button'  id='changeYear'' value='▼'  class='cnj_input2' onfocus='this.blur()' onMouseover=\"this.className='cnj_input3'\" onMouseout=\"this.className='cnj_input2'\">"

    //alert(intWeekCount);
    var popHeight;
    if (intWeekCount == 6)
        popHeight = 195;
    else
        popHeight = 177;
    oPopup.show(cleft, ctop, 198, popHeight, document.body);
}

function popUpCalendar(ctl, ctl2, format) {
    var leftpos = 0;
    var toppos = 0;
    var leftscroll = 0;
    var topscroll = 0;

    if(bPageLoaded) {
        ctlToPlaceValue    = ctl2;
        dateFormat=format;
        formatChar = " ";
        aFormat    = dateFormat.split(formatChar);

            if(aFormat.length<3) {
                formatChar = "/";
                aFormat    = dateFormat.split(formatChar);

                if(aFormat.length<3) {
                    formatChar = ".";
                    aFormat    = dateFormat.split(formatChar);

                    if(aFormat.length<3) {
                        formatChar = "-";
                        aFormat    = dateFormat.split(formatChar);

                        if (aFormat.length<3) {
                            formatChar="";
                        }
                    }
                }
            }
            tokensChanged =    '0';

            if(formatChar != "") {
                aData =    ctl2.value.split(formatChar);

                for(i=0;i<3;i++) {
                    if ((aFormat[i]=="d") || (aFormat[i]=="dd")) {
                        dateSelected = parseInt(aData[i], 10);
                        tokensChanged++;
                    } else
                    if((aFormat[i]=="m") || (aFormat[i]=="mm")) {
                        monthSelected =    parseInt(aData[i], 10) - 1;
                        tokensChanged++;
                    } else
                    if(aFormat[i]=="yyyy") {
                        yearSelected = parseInt(aData[i], 10);
                        tokensChanged++;
                    }else
                    if(aFormat[i]=="mmm") {

                        for(j=0; j<12;    j++) {
                            if (aData[i]==monthName[j]) {
                                monthSelected=j;
                                tokensChanged++;
                            }
                        }
                    } else
                    if(aFormat[i]=="mmmm") {
                        for(j=0; j<12;    j++) {
                            if (aData[i]==monthName2[j]) {
                                monthSelected=j;
                                tokensChanged ++;
                            }
                        }
                    }
                }
            }

            if((tokensChanged!=3) || isNaN(dateSelected) || isNaN(monthSelected) || isNaN(yearSelected)) {
                dateSelected = dateNow;
                monthSelected =    monthNow;
                yearSelected = yearNow;
            }
            odateSelected=dateSelected;
            omonthSelected=monthSelected;
            oyearSelected=yearSelected;

            aTag = ctl;
            bTag = ctl;
           
            do {
                aTag = aTag.offsetParent;
                leftpos    += aTag.offsetLeft;
                toppos += aTag.offsetTop;
                leftscroll    += aTag.scrollLeft;
                topscroll += aTag.scrollTop;   
       
            } while(aTag.tagName!="BODY");
           
            cleft =    fixedX==-1 ? (ctl.offsetLeft + leftpos) - leftscroll : fixedX;
            ctop = fixedY==-1 ?    (ctl.offsetTop + ctl.offsetHeight + toppos) - topscroll :    fixedY;
            constructCalendar (1, monthSelected, yearSelected);

            bShow = true;
            ctlNow = ctl;
        }
    }

init();
</script>

<input type="button" value="달력" onclick="popUpCalendar(this, txtDate, 'yyyy-mm-dd')">
<input type="text" name="txtDate" readonly>

Posted by 1010
반응형

디자인이 어디갔지?

왜 이 홈페이지에 스타일이 사라졌는지 궁금하다면, Annual CSS Naked Day 사이트를 방문해 주세요. 한국어 설명도 있습니다.



접근성을 해치지 않는 자바스크립트의 사용

신현석

2006년 5월

자바스크립트에 대한 잘못된 생각

자바스크립트 없이는 개발을 할 수 없다?

많은 개발자들이 자바스크립트가 없이는 개발을 할 수 없다고 생각한다. 그만큼 자바스크립트를 일상적으로 많이 사용하고, 자바스크립트에 대해서 잘못 오해하고 있는 부분이 많다는 것이다. 자바스크립트는 클라이언트 환경에서 작동하기 때문에 핵심로직에 사용해서는 안된다. 핵심적인 로직은 서버사이드 언어로 처리를 하고 자바스크립트는 그 옆에서 UI구성을 위해서 도와주기만 해야 한다. 바꿔 말하면 자바스크립트가 없어도 핵심 로직은 작동을 해야 한다. 먼저 자바스크립트없이 HTML과 서버사이드 언어만으로 완벽하게 작동 할 수 있게 개발을 끝낸 후 자바스크립트를 이용해서 좋은 UI나 유효성 검사 등을 하는 부분을 추가 하는 순서로 만들어야 한다. 만약 이를 어기고 자바스크립트를 기능의 일부로 사용하면 접근성이 떨어지는 것 뿐만 아니라 보안도 떨어지고 데이터의 무결성도 보장되지 않는다.

자바스크립트가 작동하지 않는 환경도 고려를 해 줘야 하는가?

자바스크립트가 작동하지 않는 환경이 일반적인 상황은 아니지만 스크립트를 사용할 수 없는 환경에 대한 고려는 반드시 필요하다. 실제로 브라우져에 따라서는 자바스크립트 버젼이 다를 수 있고 개발 환경에서는 잘 작동하던 기능이 어떤 사용자 환경에서는 작동하지 않을 수도 있다. 그리고 사용자 중에서도 여러 이유로 스스로 자바스크립트 사용을 중지하고 사용하는 경우도 있다. 자바스크립트를 사용하지 않아도 핵심 기능을 구현할 수 있음에도 불구하고 불필요한 자바스크립트를 사용하여 접근성을 떨어뜨리는 것이 올바른 페이지 제작 방법은 아니다.

서버 부하를 줄이기 위해서 자바스크립트로만 유효성 검사를 한다?

자바스크립트를 이용해서 서버의 부하를 줄일 수 있다는 것은 많은 사람들이 알고 있을 것이다. 자바스크립트로 선처리를 행함으로서 네트웍이나 서버의 처리를 감소시킨다는 것인데 이것을 잘못 이해하여 자바스크립트만으로 유효성을 체크하는 것이 좋다고 생각하는 사람들이 있다. 자바스크립트로 선처리를 한결과물을 그대로 믿으면 안된다. 사용자측으로 부터 넘오온 모든 값은 그 값의 유효성을 완전히 보장할 수 없기 때문에 서버측에서도 유효성 체크를 해 줘야만 한다. 이것은 서버의 부하를 높이는 것 이전에 자료의 무결성을 보장하는 중요한 과정이다. 자바스크립트를 거치지 않고 서버에 임의로 변조된 값을 보내는 일은 아주 쉬운 일이다.

자바스크립트를 사용하지 않으면 UI가 불편해 진다?

자바스크립트를 이용해서 RIA나 좋은 UI를 만들 수 있는 것은 사실이지만 웹환경을 이해하고 일반적인 웹 인터페이스를 이용해서 만드는 것이 더 좋은 UI를 제공할 수 있다. 사용자 친화적인 UI에 대한 고민을 해야지 자바스크립트를 사용했다고 좋은 UI가 나오는 것은 아니다. 실제적으로 가장 사용자가 이해하기 쉬운 UI는 사용자 OS나 브라우저에서 기본적으로 제공하는 컨트롤 인터페이스를 그대로 사용하는 것이고 이는 자바스크립트 없이도 충분히 가능하다.

자바스크립트는 사용자 환경에 내려보내지고 사용자의 브라우져에서 실행이 되기 때문에 이에 의존해서 프로그램을 만들게 되면 보안, 접근성에 문제가 생기기 쉽다. 이러한 자바스크립트의 특징을 정확히 이해하지 못한 잘못된 개발 방법이나 상식들 때문에 자바스크립트가 오용되고 있는 경우가 많다. 자바스크립트는 어디까지나 보조적인 수단이라는 것을 이해하고 핵심적인 기능을 해치지 않는 한도에서 사용하는 것이 무엇보다 중요하다.

자바스크립트 선언

<script language="Javascript">
//code
</script>

자바스크립트는 <script> 엘리먼트로 선언을 한다. 모든 <script>엘리먼트는 type을 명시해 주어야 하고 자바스크립트의 type은 "text/javascript" 이다. 많은 경우 language 만을 선언해서 자바스크립트버젼을 명시하는데 반드시 type도 같이 명시를 해 주어야 한다.

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

<a>의 href 속성과 자바스크립트의 사용

href는 Hypertext REFerence의 약자이다. 다시 말해서 hypertext의 위치를 나타내는 uri를 그 값으로 갖는다. 하지만 많은 경우 이 href안에 "javascript:myFunction()"과 같이 잘못된 구문을 이용하는 것을 볼 수 있다. 이와 같이 href안에 잘못된 값이 들어가게 될 경우, 북마크나 새창, 새탭으로 열기 등의 href 관련된 브라우저의 기능들이 정상적으로 작동하지 않게 된다. 따라서 href안에는 항상 uri가 들어가도록 하고 자바스크립트 적용은 onclick과 같은 이벤트 속성을 이용해야 한다.

의미 없는 href 값을 사용한 경우

사용자의 링크 클릭이 링크와 관련이 있고 이를 자바스크립트를 이용해서 처리를 하야 하는 경우가 있다면 우선은 자바스크립트를 빼고도 페이지의 이동을 할 수 있게 href에 적절한 값을 넣어 주어야 한다. 이와 같은 경우로 탭메뉴를 들 수 있다. 탭메뉴의 경우 탭을 누르면 해당 탭과 관련있는 컨텐츠를 보여주는 식으로 작동하게 된다. javasript가 없다면 탭을 클릭했을 때 해당 컨텐츠로 이동을 하는 식으로 구현 되면 된다. href 안의 값으로 페이지 안에서의 해당 컨텐츠 앵커 주소를 넣는 것으로 간단히 구현 된다.

<a href="#notice-list"><img src="notice-tab.gif" alt="Notice" /></a>

그리고 이 마크업을 기본으로 하여 이벤트 속성으로 원하는 기능을 넣어주면 된다.

<a href="#notice-list" onclick="showNoticeTab(); return false;"><img src="notice-tab.gif" alt="Notice" /></a>

onclick으로 탭을 보여준 후 false를 리턴하여 해당 앵커로 이동하지 않도록 처리 한다. 자바스크립트가 작동을 할 때에는 클릭하면 정상적으로 탭으로 작동을 할 것이고, 그렇지 않을 경우에는 해당 컨텐츠로 이동을 하여 높은 접근성을 유지할 수 있다.

만약 자바스크립트가 링크와 관련이 없는 경우에는 <a>태그를 사용해서 스크립트를 적용하면 안된다. 보통 특정 효과를 주는 것이 이러한 것에 해다하게 되는데 이 경우 자바스크립트가 작동을 하지 않아도 컨텐츠 이해에 크게 문제가 되지 않는 경우이다.

<img src="button.gif" style="cursor: pointer;" onclick="myAction()" />

효과를 위한 자바스크립트는 단순히 onclick을 이용해서 적용을 하고 <a>를 사용하지 않는다. 그리고 사용자가 마우스 포인터를 올렸을 때 손모양으로 나오는 것은 스타일로 처리하면 된다.

팝업창을 열 때(window.open)

<img src="openWindow.gif" onclick="window.open('popup.html', '', 'widht=300,height=200')">
<a href="#"><img src="openWindow.gif" onclick="window.open('popup.html', '', 'widht=300,height=200')"></a>

href에 #과 같은 의미 없는 값을 넣거나 onclick 안에 경로를 처리하는 경우가 있는데 팝업창은 링크이고 페이지가 별도로 존재 하기 때문에 <a>를 이용해서 기능을 구현하고 href엔느 해당 팝업의 경로를 넣어야 한다.

<a href="popup.html" onclick="window.open(this.href, 'popupName', 'width=300,height=200'); return false;"><img src="openWindow.gif"></a>

이럴 경우 사용자가 자신의 의도 대로 팝업창을 새창, 새탭 등으로 열 수 있고 심지어 즐겨 찾기도 할 수 있다.

자바스크립트를 이용한 페이지 이동

웹사이트를 이용하다 보면 폼에서 값을 입력하고 서밋을 하는 순간 "따다다닥" 하는 식으로 클릭을 여러번 한 것과 같은 소리가 나는 경우를 접하게 된다. 프로세스가 여러페이지에 걸쳐서 일어나게 되는데 이 처리를 자바스크립트로 처리를 해서 이러한 현상이 발생을 하게 된다.

<script type="text/javascript">document.location.href="redirection.html";</script>

위와 같이 페이지를 이동 하거나 아래와 같이 <form>을 이용해서 값을 넘기는 경우가 이러한 경우이다.

<form name="login_form">
	<input type="hidden" name="user_id" value="myid" />
	<input type="hidden" name="user_pwd" value="mypassword" />
	<input type="hidden" name="redirect_url" value="http://mysite.com/login/" />
	<input type="hidden" name="somevalue" value="blahblah" />
	...
</form>
<script type="text/javascript">
f = document.forms.login_form;
f.action = "http://login.oursite.com/login/";
...
f.submit();
</script>

심한 경우 아래와 같이 전혀 의미 없는 폼을 이용하기도 한다.

<form method="post" name="sg_form" action="http://www.qubi.com/" target="_top">
</form>
<script> sg_form.submit(); //3</script>

위와 같은 페이지들은 html 문법상 오류가 있는 페이지 들이고 이 때문에 작동이 안 될 수도 있다. <form>엘리먼트나 <script>엘리먼트는 상위에 <body>나 <head>엘리먼트가 있어야 하는데 위와 같은 경우 이러한 엘리먼트가 없기 때문에 html로 해석이 안되어 스크립트가 작동 되지 않거나 값이 넘어가지 않을 수도 있다. 그리고 <form>에 submit <input>이 없기 때문에 자바스크립트로 submit이 일어나지 않을 수도 있다.

이와 같이 페이지를 이동하거나 값을 넘길 필요가 있을 때 자바스크립트에 의존해서 이를 처리하게 되면 클라이언트의 환경에 따라서 동작이 실패할 수 있다. 따라서 이러한 처리는 자바스크립트에서 처리 하지 말고 서버 측에서 http헤더 정보를 이용해서 처리해야 한다.

이러한 중간과정에서의 처리를 서버측에서 모두 처리 하는 것이 가장 바람직 하지만 어쩔 수 없이 사용을 해야할 경우에는 - 그럴 경우가 많지는 않겠지만 기존의 호환성을 위해서 - DTD선언이나 <html> 루트 엘리먼트, <head>, <body>와 같이 필수 엘리먼트들이 존재하는 완결된 페이지를 사용 하도록 하고, 자바스크립트가 작동하지 않는 경우를 위해서 <form>에 submit버튼도 제공을 하고, 결과 메세지도 alert외에 일반 text와 <a>를 이용한 링크를 제공하도록 해야 한다.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr" />
<title>Redirect</title>
</head>
<body>
<script type="text/javascript">
/*
 some processes...
*/
alert('이래저래한 이유로 다시 돌아 갑니다.');
document.location.href="redirection.html";
</script>
<p><a href="redirection.html">이래저래한 이유로 다시 돌아 갑니다.</a></p>
</body>
</html>

charset이 없는 경우 브라우져의 기본 설정으로 alert이 작동하기 때문에 브라우져의 기본 설정이 ko-kr이 아닌 경우 한글이 깨지게 된다. 문서의 mime-type도 text/html인지 확인해야 한다.

<form>에서의 자바스크립트 사용

일반적으로 <form>은 사용자가 입력한 값을 서버측에 전달하는 역할을 하고 그 전달은 <form>의 submit 기능을 통해서 이루어 진다. 이러한 폼을 구현 할 때에 일반적으로 자바스크립트를 사용하는 경우가 많다.

submit

폼은 그 자체적으로 값을 보내는 서밋기능을 제공하고 있다. <input type="submit" />이나 <input type="image" />이 서밋기능을 하는 컨트롤인데 폼의 값 유효성 체크를 하는 과정에서 이러한 폼의 자체적인 서밋기능을 이용하지 않고 자바스크립트로 폼 서밋을 하는 경우가 있다.

<script type="text/javascript">
function submitForm() {
	loginForm.submit();
}
</script>
<form id="loginForm" name="loginForm" action="">
	User Id <input type="text" name="loginId">
	User Password <input type="password" name="loginPassword"><br>
	<img src="login.gif" onclick="submitForm()">
</form>

위와 같은 경우 폼에 서밋기능이 없기 때문에 브라우져에 따라서 script로 서밋이 안되는 경우도 있고 서밋 대신에 이미지가 들어가 있기 때문에 의미적으로도 맞지 않게 된다. 따라서 폼을 제작할 때에는 반드시 서밋기능을 <input>을 이용해서 제공해야 한다.

<form id="loginForm" name="loginForm" action="">
	<p>
		<label for="loginId">User Id</label>
		<input type="text" id="loginId" name="loginId" /><br />
		<label for="loginPassword">User Password</label>
		<input type="password" id="loginPassword" name="loginPassword" />
	</p>
	<p>
		<input type="image" src="login.gif" alt="Login" />
	</p>
</form>

많은 경우 <html>제작 과정에서 서밋을 <img>로 넣는 경우가 있는데 이 경우 이를 그냥 사용하면 안되고 적절한 <input>으로 바꾸어서 사용해야 한다.

validation

클라이언트 측에서 자바스크립트를 이용한 유효성 검증은 <form>의 서밋 이벤트를 캐치하는 방식으로 구현해야 하고 자바스크립트가 폼을 서밋하는 방식을 사용하면 안된다.

<script type="text/javascript">
function submitForm() {
	if (!loginForm.loginId.value) {
		alert("아이디를 넣어주세요.");
		loginForm.loginId.focus();
	} else if (!loginForm.loginPassword.value) {
		alert("비밀번호를 넣어주세요.");
		loginForm.loginPassword.focus();
	} else {
		loginForm.submit();
	}
}
</script>
<form id="loginForm" name="loginForm" action="">
	아이디 <input type="text" name="loginId">
	비밀번호 <input type="password" name="loginPassword"><br>
	<img src="login.gif" onclick="submitForm()">
</form>

위와 같은 경우 자바스크립트만을 이용해서 폼을 서밋하고 있기 때문에 자바스크립트가 없이 HTML만으로는 기능이 작동하지 않는다.

<script type="text/javascript">
function submitForm(formEl) {
	//TrimAll(formEl);

	var errorMessage = null;
	var objFocus = null;

	if (formEl.loginId.value.length == 0) {
		errorMessage = "아이디를 넣어주세요.";
		objFocus = formEl.loginId;
	} else if (formEl.loginPassword.value.length == 0) {
		errorMessage = "비밀번호를 넣어주세요.";
		objFocus = formEl.loginPassword;
	}

	if(errorMessage != null) {
		alert(errorMessage);
		objFocus.focus();
		return false;
	}
	return true;
}
</script>

<form id="loginForm" name="loginForm" action="" onsubmit="return submitForm(this)">
	<label for="loginId">아이디</label> <input type="text" id="loginId" name="loginId" />
	<label for="loginPassword">비밀번호</label> <input type="password" id="loginPassword" name="loginPassword" /><br />
	<input type="image" src="login.gif" alt="Login" />
</form>

이와 같이 onsubmit 이벤트를 이용해서 폼의 유효성을 체크하고 그 결과를 true나 false로 보내줌으로써 폼이 스크립트에 따라서 서밋을 진행하거나 멈출 수 있고, onsubmit 이벤트가 발생하지 않아도 사용자는 폼을 사용할 수 있기 때문에 접근성이 높아지게 된다.

게시판 등에서 기능을 모두 자바스크립트로 하는 경우

게시판에서 페이지의 이동을 자바스크립트만으로 하는 것을 많이 볼 수 있다. 아래와 같이 사용자 인풋이 없는 빈 <form>을 하나 만들고 이것과 자바스크립트를 이용해서 글을 읽거나 페이지를 이동하는 것이다.

<form method="post" name="vars">
	<input type="hidden" name="articleId" value="23" />
	<input type="hidden" name="page" value="3" />
	<input type="hidden" name="keysord" value="" />
	<input type="hidden" name="searchType" value="" />
	<!-- 등등 -->
</form>

...

<a href="javascript:ArticleRead()">글읽기</a>
<a href="javascript:GoList()">리스트 보기</a>

url이 간단해 지고 다루기 쉽다는 이유로 이러한 방식으로 개발을 하는 경우가 많은 것 같은데 절대로 사용해서는 안되는 방식이다.

우선 위와 같이 모든 기능을 자바스크립트를 이용해서 구현을 하게 되면 자바스크립트 오류가 있거나 핸드폰과 같이 자바스크립트가 정상적으로 작동 하지 않는 상황에서는 접근을 할 수 없게 된다. 또한 모든 변수를 post를 통해서 전달하기 때문에 url에 표시가 되지 않고 해당 페이지를 따로 북마크 한다든지 저장을 할 수가 없게된다. 게시판의 경우 해당 게시물로의 접근을 쉽게 해 주어야 하는데 사용자가 url을 알 수 없게 함으로써 접근을 원천적으로 막게 된다.

자바스크립트를 이용하지 않고도 <a>와 url만으로도 작동 가능한 페이지를 만들고 QueryString을 효율적으로 다루는 방법을 모색하여 개발을 진행하는 것이 가장 좋은 방법이다.

마치며

본인이 웹사이트 개발을 하면서 접할 수 있었던 몇몇 잘못된 자바스크립트 사용 예를 적어 보았다. 그런데 놀라운 것은 이러한 개발 방식을 초보부터 어느정도 경력이 된 개발자들 까지 아무런 고민 없이 사용하고 있다는 것이다. 책이 잘못된 것인지 교육이 잘못 된 것인지 정확히 근원을 알 수는 없지만 많은 개발자들이 웹이 가지고 있는 기본적은 특성을 무시한채 잘못된 방법을 이용하여 개발을 하고 있는 것이 사실이다. 그리고 또 초보 개발자들은 HTML을 잘 모르기 때문에 이러한 개발 방식을 아무 고민 없이 그냥 받아들이고 있는 것이 사실이다.

브라우저 접근성을 가장 크게 낮추고 있는 것이 바로 이 잘못된 자바스크립트의 사용이다. 부디 조금이라도 많은 개발자들이 링크에 기초한 웹의 특성을 이해하고 접근성 높은 웹사이트, 웹 어플리케이션을 구축 하기를 바라는 바이다.

다운로드 : accessible-javascript.pdf(pdf 225KB)



Posted by 1010
반응형

오라클에서 rownum 은 쿼리가 실행될 때 결과 레코드에 번호를 나타내어 주는 필드이다.

물론 table 을 만들 때 rownum 을 만들어줄 필요는 없다.

어떠한 테이블이라도 "select rownum from boardtable" 의 형태로 쿼리를 날리면 레코드에

번호컬럼이 생기는 것을 볼수 있다.

따라서 페이징을 위한 쿼리에서 우리는 rownum 10 보다 크고 20 보다 작은

이런 식의 조건을 주어 원하는 범위의 레코드만 쿼리 할수 있다.

Select * from boardtable where rownum > 10 and rownum <=20

 

위와 같이 쿼리 하면 어떨가? 결과가 하나도 않나올 것이다. 왜냐하면 쿼리가 실행될 때

Where 부분이 먼저 실행한다. Select 하기 전에 rownum 이 발생하지 않기 때문에

rownum 할 데이터가 없어서 아무 값도 가져오지 못하게 되는것이다.

다시 쿼리를 수정하게 되면 다음과 같다.

Select 서브 쿼리를 날려서 먼저 데이터를 가져온후에 rownum 을 하는것이다.

Select * from (select rownum numrow, boardtable from boardtable)

Where numrow > 10 and numrow <= 20

 

여기에서 문제가 다 해결된건 아니다. Order by 절을 사용하게 되면 또다른 문제에 직면하게 된다

Select * from (select rownum numrow, boardtable from boardtable order by reg_date desc)

Where numrow > 10 and numrow <= 20

 

실행해 보면 원하는 결과가 나오지 않는 것을 알수있을것이다.

이유는 order by rownum 값을 만드는데 영향을 못주는 것으로 생각된다.

order by 를 지정한다고 해도 rownum 은 최초의 order by 가 없는 상태로 만들어진다.

원하는 형태의 정렬 데이터를 rownum 하고 싶다면 서브쿼리를 order by 절로 날린후

Rownum 을 매기면 된다.

Select rownum numrow, aa.* from (select * from boardtable order by reg_date desc) aa

 

여기에 범위지정 쿼리를 써넣게 되면 어떻게 될까? 위에서 설명한 대로 아무값도 안나오게 된다

Select rownum numrow, aa.* from (select * from boardtable order by reg_date desc) aa

Where numrow > 10 and numrow <= 20

 

이것을 제대로 구현할려면 한번더 select 구문 서브쿼리를 날려야한다.

Select * from (select rownum numrow, aa.* from (select * from boardtable order by reg_date desc) aa ) where numrow > 10 and numrow <= 20

 

이와 같이 하게 되면 서브쿼리를 몇번이나 날리게 되어 데이터 양이 많을경우

퍼포먼스에 문제가 생길수가 있다. 그래서 index hint 절을 사용하여 성능을 향상시켜준다.

Index order by 구문에 나오는 reg_date 를 주면될것이다.

Create unique index  idx_board_reg_date on boardtable (reg_date, idx)

Posted by 1010