미리보기 : http://www.blog4u.kr/attach/1/20080617/tree/tree.html

자바스크립트를 이용한 트리메뉴이다.

기존 자바스크립트 메뉴와는 조금 구조가 다르다...

먼저 선언 하고 사용하는 엘리먼트 방식이 아닌... 그때그때 새로운 메뉴를 추가 얼마든지 확장이 가능한 스크립트 메뉴이다.

 

<script language="javascript">
<!--
//팝업윈도우, 스크린 중앙에 위치, 다중 오픈 방지
var winname_1;
var openF = 0;
function popup(fileName, intWidth, intHeight, intLeft, intTop, vScrollbars, vResizable, vStatus){
        today = new Date();
        winName = today.getTime();

        var fileName, intWidth, intHeight;
        var screenWidth = screen.availwidth;
        var screenHeight = screen.availheight;

        if(intWidth >= screenWidth){ //스크린 상태에 따라 스크롤바 자동표시
                intWidth = screenWidth - 40;
                vScrollbars = 1;
        }
        if(intHeight >= screenHeight){ //스크린 상태에 따라 스크롤바 자동표시
                intHeight = screenHeight - 40;
                intWidth = intWidth + 20;
                vScrollbars = 1;
        }
        if(intLeft == 'auto' || intTop == 'auto'){ //스크린 중앙에 위치 시키기
                var intLeft = (screenWidth - intWidth) / 2;
                var intTop = (screenHeight - intHeight / 2;
        }
        var features = eval("'width=" + intWidth + ",height=" + intHeight + ",left=" + intLeft + ",top=" + intTop + ",scrollbars=" + vScrollbars + ",resizable=" + vResizable + ",status=" + vStatus + "'");
        if(openF == 1){
                if(winname_1.closed){
                        winname_1 = window.open(fileName,winName,features);
                }else{
                        winname_1.close();
                        winname_1 = window.open(fileName,winName,features);
                }
        }else{
                winname_1 = window.open(fileName,winName,features);
                openF = 1;
        }
        winname_1.focus();
}
//-->
</script>
<style type="text/css">


<body onload="popup('http://blog4u.kr','1024','668','auto','auto','0','0','0');" leftmargin="0" marginwidth="0" topmargin="0" marginheight="0">

<a href="javascript:popup('http://blog4u.kr','1024','668','auto','auto','0','0','0')"," onFocus="this.blur();">

[input 입력창에 배경 이미지 깔기]
---------------------------------------------------------------------------------------------------------------------

<script>
var c=false;
function change() {
if ( c ) return;
document.userlogin.uid.style.backgroundImage="";
c=true;
}

var c2=false;
function change2() {
if ( c2 ) return;
document.userlogin.upw.style.backgroundImage="";
c2=true;
}
</script>

스크립트에 위를 추가하고...

<TR>
<TD align=middle height=20><INPUT onmousedown="return change();" onkeydown="return change();" style="BORDER-RIGHT: #999999 1px solid; BACKGROUND-POSITION: center center; BORDER-TOP: #999999 1px solid; FONT-SIZE: 12px; BACKGROUND-IMAGE: url(subpage/imgs/id.gif); BORDER-LEFT: #999999 1px solid; WIDTH: 120px; BORDER-BOTTOM: #999999 1px solid; BACKGROUND-REPEAT: no-repeat; FONT-FAMILY: Verdana, 굴림; HEIGHT: 20px" maxLength=6 name=uid></TD></TR>
<TR>
<TD vAlign=bottom align=middle height=24><INPUT onmousedown="return change2();" onkeydown="return change2();" style="BORDER-RIGHT: #999999 1px solid; BACKGROUND-POSITION: center center; BORDER-TOP: #999999 1px solid; FONT-SIZE: 12px; BACKGROUND-IMAGE: url(subpage/imgs/pw.gif); BORDER-LEFT: #999999 1px solid; WIDTH: 120px; BORDER-BOTTOM: #999999 1px solid; BACKGROUND-REPEAT: no-repeat; FONT-FAMILY: Verdana, 굴림; HEIGHT: 20px" maxLength=7 name=upw></TD></TR>

인풋쪽에 위처럼 설정하면 인풋배경이미지가 들어간다.
당연히 이미지 파일이 있어야 함.

//이미지 용량체크
    var isFileChecked = false;
    var isImgFile = false;
    var isEnableFileSize = false;
    var maxSize = 1*1024*1024;       //1M
    function checkFileSize(uploadImgObj){
        //
        var enableUploadFileExt=new Array("bmp","jpg","jpeg","gif");
        var uploadImgObjName = uploadImgObj.value;
        var startPoint = 0;
        var isImageFile = false;

        //File 체크확인
        isFileChecked = true;

        if(uploadImgObj.value == ""){
            return;
        }

        //이미지파일 확장자 체크
        for(var i=uploadImgObjName.length-1; i>=0; i--) {
            if(uploadImgObjName.charAt(i) == ".") {
                startPoint = i;
                break;
            }
        }
        var uploadImgObjExt = uploadImgObjName.substring(startPoint+1,uploadImgObjName.length);

        for(i=0; i<enableUploadFileExt.length; i++) {
            if(uploadImgObjExt.toLowerCase() == enableUploadFileExt[i]){
                isImageFile = true;
                break;
            }
        }
        if(!isImageFile){
            alert("이미지 파일이 아닙니다.     ");
            uploadImgObj.value="";
            isImgFile = false;
            return;
        }else{
            isImgFile = true;
        }

        //파일용량 체크
        var img = new Image();
        img.dynsrc = uploadImgObj.value;
        var filesize = img.fileSize;
        //alert(filesize);
        if(filesize > maxSize) {
            alert("파일업로드 허용용량 "+maxSize/1024+"Kbyte를 초과되었습니다.     ");
            isEnableFileSize = false;
        }else{
            isEnableFileSize = true;
        }
        //
    }

    //업로드승인체크
    function goFileUploadCheck(){
        if(!isFileChecked){
            alert("업로드할 파일을 지정해주셔야 합니다.     ");
            return;
        }

        if(!isImgFile){
            alert("이미지 파일이 아닙니다.     ");
            return;
        }

        if(!isEnableFileSize){
            alert("파일업로드 허용용량 "+maxSize/1024+"Kbyte를 초과되었습니다.     ");
            return;
        }
    }

<input id="txtUploadFile" style="width: 100%" type="file" size="40" name="NewFile"  onchange="javascript:checkFileSize(this);" />
 <input type="button" value="Upload" onclick="javascript:goFileUploadCheck();" />

추신 : 반드시 이것으로 만족하여 프로그래밍 하지 말고 반드시 서버단에서도 validation을 해주어야 한다!!!

그래도 발생하는 에러의 90%는  UI단에서 막을수 있다.

초보 웹 프로그래머를 귀찮고 당황하게 하는 경우를 하나 소개하고자 한다.

<상황>
이미 라이브된 웹 사이트에서 사용자가,
특정한 경우에 자바스크립트 에러가 난다는 것을 리포팅했다.
팀장이 그 이야기를 듣고 당장 고쳐놓으라고 주문한다.

급하게 javascript 파일인 js파일을 열어서 수정한 다음 서버에 업로드를 마쳤다.
그리고 팀장에게 '수정 완료했습니다.' 보고를 한다.

그런데 왠일인지 팀장이 확인을 해보더니
'아직 그대론데?"라고 한다.

살펴보니 아까 그 페이지를 보았을 때 사용된 js파일을
팀장의 웹 브라우저가 웹 캐쉬에 저장해두었고
그 캐쉬를 그대로 사용하여 페이지를 불렀기 때문에 갱신이 안된 것이다.

'Ctrl+F5눌러서 캐쉬 무시하고 리로드 해보세요'

그렇게 하더니 팀장은 '어.. 이제 되네.. 수고했어..'라고 한다.

그런데 그렇게 만만한 팀장은 아니다.
'근데 말이야, 다른 사용자들도 Ctrl+F5 안누르면 나처럼 다 에러나는거 아냐?'
맞는 말이다.

그래서 개발자는 이야기한다.
'시간이 좀 지나면 서서히 갱신이 될겁니다... IE가 다 그렇죠 뭐~~~'

하지만 역시 만만한 팀장은 아니다.
'무슨 소리를 하는거야, 무슨 수를 써서든 사용자들이 갱신된 js파일을 적용받도록 해!'


이런 일, 웹 개발자들이 한번씩 경험하는 일이라고 생각하는데...

이 때의 어떻게 해결하는 것이 가장 현명할까?

1. js 파일명을 바꾸어서 서버에 저장하고, HTML에서도 수정한다.
수정전 : <script type="text/javascript" src="/js/scripts.js"></script>
수정후 : <script type="text/javascript" src="/js/scripts_v2.js"></script>

이렇게 하면 당장 해결은 되겠지만,
이런 일이 반복되다 보면 서버측에 는 script파일들이 잔뜩 쌓이게 되고 버전 관리가 복잡하게 된다.
서버에서 해당 디렉토리를 열어보면,
script.js, script_v2.js, script_20071206.js, script.bk.js, script_last.js...
이렇게 되어있기 십상이다.

그러다가 어느 날 큰맘먹고 최신 버전 이외의 파일을 싹 delete하면,
갑자기 갑자기 몇개의 페이지에서 에러가 발생하기 시작한다.

'어, 여기 제가 담당하는 페이지 에러가 나는데요? 누가 script_the_last.js 파일 삭제했어요?'
'아니, 제가 지웠는데요, 아직도 그 파일쓰고 있었어요? 3개월전에 script_real_last.js로 바꿨어요~~'

차라리 이렇게 발견이라도 되면 다행이다.
발견되지 않고 몇주동안 에러가 나는 페이지를 고객에게 서비스하게 되는 일이 일어나지 말라는 법이 없다.

그래서 이방법은 비추천.
(특히 계절마다 갑자기 책상을 말끔히 정리하고 싶은 충동이 드는 사람들에게 비추천^^)

2. 웹 서버 설정을 바꾸어서, 또는 다른 방법으로, JS 파일이 캐쉬를 타지 않도록 한다.
어떤 이들은 스크립트가 호출되는 페이지를 no-cache로 하면 된다고 하기도 하는데,
해보면 잘 안될것이다. 그것은 스크립트파일을 no-cache하라는게 아니라, 그 페이지를 no-cache할 뿐

JS 파일자체를 no-cache로 해야 하며
이 파일이 있는 웹서버의 설정을 바꾸면 캐쉬를 타지 않게 할 수 있다.
그러면 원천적으로 사용자의 브라우저는 항상 JS파일을 서버에서 받아오게 된다.

하지만, 웹서버 숫자가 너무 많거나, 디렉토리 설계상 너무 복잡해서 힘들거나,
시스템 엔지니어링 팀과 평소 사이가 안좋아서 고쳐주지 않는 일이 발생할 수도 있다.
(서버에서 웹캐쉬 expire 주기를 조정하는 것도 방법이다)

그럴 때 생각해보는 방법
수정전 : <script type="text/javascript" src="/js/scripts.js"></script>
수정후 : <script type="text/javascript" src="/js/scripts.php"></script>

static파일인 js파일을 asp로 확장자를 바꾸었고,
해당 웹서버가 php확장자는 모두 php 웹스크립트로 인식하도록 되어있다면
위와 같이 바꾸면 일반적인 웹서버 설정, 브라우저 설정에서 캐쉬로 저장하는 것은
브라우저가 열려있는 동안이다. 브라우저 창 모두 닫고 새창 열어서 다시 들어가면 갱신된다는 뜻.

하지만, 위의 어떤 방법이든,
static파일로서 웹서버를 혹사시키지 않고 사용자 캐쉬를 사용해야 하는 파일을
강제로 항상 갱신하게 되는 결과가 되어, 사용자가 많은 사이트의 경우
서버 증설이 필요할 정도의 비효율이 발생할 수도 있다.

그래서 비추천.

3. 그래서 어떻게 하면 좋나?
수정전 : <script type="text/javascript" src="/js/scripts.js"></script>
수정후 : <script type="text/javascript" src="/js/scripts.js?version=20071207"></script>

1번과 2번 방법이 섞인것 같아 보이는가? 하지만 아니다.
서버에는 실제로 scripts.js 파일만 올라가 있다.
또, 수정후에 뒤에 붙은 변수인 version=20071207
php에서처럼 스크립트에 입력되는 request가 아니라 그냥 구분을 위해서 붙여놓은 것이다.
해단 request 변수는 js 파일에 영향을 미치지 않는다.
이렇게 해 두면 웹 브라우저는 버전별로 다른 웹 캐쉬를 생성하게 된다.

보통의 웹 브라우저는
/js/scripts.js?version=20071207
/js/scripts.js?version=20071208 이 있을 때
script.js파일이 변경이 없다고 하더라도 서로 다른 웹 캐쉬에 저장하도록 되어 있다

이것을 이용해서, 서버에는 scripts.js파일 하나만 존재하면서
사용자 브라우저에 남아있는 캐쉬가 갱신되어야 하는지 아닌지를 적절히 수정할 수 있다.
이런 이유로 1번 방법과는 달리 스크립트 파일의 버전관리를 쉽게 할 수 있다.

또한, 스크립트가 여러 페이지에 include되어 있는 경우라고 해도
어떤 페이지에서는
<script type="text/javascript" src="/js/scripts.js?version=20071207"></script>
또 다른 페이지에서는
<script type="text/javascript" src="/js/scripts.js?version=20071208"></script>
심지어는 어떤 페이지에서는
<script type="text/javascript" src="/js/scripts.js"></script>
와 같이 제각각으로 되어있더라도 서버에 script.js파일만 있으면 에러가 발생하지 않고,

또한 개발자가 의도하지 않은 경우에는 기본적으로 항상 인터넷 캐쉬가 정상동작하게 되어,
업그레이드시 발생할 수 있는 장애위험이 줄어들게 되고,
특히 스크립트 파일에 새로운 함수를 추가한 정도로만 변형하여 다시 갱신한 경우에 유용하다.


경험적으로 알고 있던 내용인데,
검색하면 쉬이 찾을 수가 없어서, 나라도 올려두면 누군가 찾아볼 수 있기를 바라는 마음에 올려본다.

내가 적용해 둔 것은 아니지만, 실제 예를 보고 싶으면,
2007년 12월 11일 현재, http://music.cyworld.com/ 에 가서 소스보기를 하면 상단에 다음과 같은 라인을 발견할 수 있을 것이다

<link rel="stylesheet" type="text/css" href="/include/css/music4_main.css?v=071205" media="screen" />

이런식이다
 

// client : head 쪽에 javascript : chiwoniiAjaxMission

function Read(obj)
{

            if(event.keyCode==40) //다운키가 눌리면
              {
               
                    document.form1.sel1.focus();return; //--포커스를 select로
              }  
     

            objNode.text = encodeURI(obj.value);
            //텍스트박스에서 글자를 읽어 들어와서 encodiing

             xmlhttp.open ("Post","MissionServer2.aspx",false);
            //비동기, 화면 안바뀌고 하겠다
            xmlhttp.send(xmlpara); //비동기로 보내면

            var getstr = xmlhttp.responseXML; // 서버 처리 후 받아진다

              for(i=0; i< count.length; i++)
            {
           
            //--- 핵심 코드는 여기 뿐~!!! server에는 싹 비워!!!
            //--글자는 첫글자만 남기고 싹지워!!
            //-- 셀렉트에 옵션을 새로 추가하는 방법
           var option = new Option();
          
           option.text = getstr.getElementsByTagName("name")[i].childNodes[0].nodeValue;
           option.value = getstr.getElementsByTagName("seq")[i].childNodes[0].nodeValue;
              
                document.form1.sel1.add(option);
             //---    
           
            }
}
//--client : body쪽에는
<select id="sel1" multiple="multiple" style="display:none; width: 152px" onchange="sel1_onclick (sel1)">
           
            </select>    &nbsp;
          
            <div id="a">
          </div>

//--server 쪽에서는
 protected void Page_Load(object sender, EventArgs e)
    {
        //---입력 -- 원본이고
        XmlDocument xmldom = new XmlDocument();
        xmldom.Load(Request.InputStream);//텍박의 값을 받아서
        string name = xmldom.SelectNodes("PARAMETER").Item(0).SelectSingleNode("DATA").InnerText;//입력
        //파라미터 노드여러개중 첫번째꺼의 싱글노드 data의 텍스트를
        //디폴트에서 받은 파라미터
 


        //--- 출력
        XmlDocument new_xmldom = sqlfunction(name); //쿼리 결과를 얻어서 돔(XML)로 만든다.
        //-- 쿼리를 사용해서 새로운 것을 만들지
        Response.ContentType = "text/xml;charset=euc-kr"; //반드시 해야함. //강제적으로 첫줄에 넣고
        Response.Write(new_xmldom.OuterXml); //두번째 부터 넣는거지.

    }


protected XmlDocument sqlfunction(string itname)
    {

        string sql = "SELECT seq, name, it from BBS where name like @name";
             
        SqlConnection con = new SqlConnection("Data Source=192.168.1.15;Initial Catalog=BoardProject;User ID=sa;Password=1234");
        SqlCommand com = new SqlCommand(sql, con);

                itname = HttpUtility.UrlDecode(itname);
       com.Parameters.AddWithValue("@name", "%"+itname+"%");

        con.Open();

        SqlDataReader dr = com.ExecuteReader();


        //-- START
        XmlDocument xmldom = new XmlDocument();

        XmlElement root = xmldom.CreateElement("root");
                                        :
                                        :
                                        :
                                        :
 //결국 dom을 리턴한다.
}

사용될 아이프레임에

<IFRAME name="Best_member" align="left" marginWidth="0" marginHeight="0" src="./member_lank.aspx"
              frameBorder="0" scrolling="no" onload="Resize_Frame('Best_member');"></IFRAME>



사이즈조절 스크립트

function Resize_Frame(name)  //게시판 사이즈 변경
{
  var Frame_Body  = document.frames(name).document.body;
  var Frame_name  = document.all(name);
 
  Frame_name.style.width
   = "100%"; //어짜피 넓이는 100%정도가 딱이다..
  Frame_name.style.height
   = Frame_Body.scrollHeight + (Frame_Body.offsetHeight-Frame_Body.clientHeight);

  if (Frame_name.style.height == "0px" || Frame_name.style.width == "0px")
  {
   Frame_name.style.width = "100%";       //기본 iframe 너비
   Frame_name.style.height = "300px";      //기본 iframe 높이
  }
  //alert(Frame_name.style.width );
  //alert(Frame_name.style.height );
 
}

파일명 : ch07_01.xml 로 저장한다.

<?xml version="1.0" encoding="euc-kr" standalone="yes"?>
<MEETINGS>
 <MEETING TYPE="informal">
  <MEETING_TITLE>XML 세계에 오신것을 환영합니다.</MEETING_TITLE>
  <MEETING_NUMBER>2079</MEETING_NUMBER>
  <SUBJECT>XML</SUBJECT>
  <DATE>08/02/2006</DATE>
  <PEOPLE>
   <PERSON ATTENDANCE="presend">
    <FIRST_NAME>민</FIRST_NAME>
    <LAST_NAME>슬기</LAST_NAME>
   </PERSON>
   
   <PERSON ATTENDANCE="absent">
    <FIRST_NAME>오</FIRST_NAME>
    <LAST_NAME>지명</LAST_NAME>
   </PERSON>
   
   <PERSON>
    <FIRST_NAME>이</FIRST_NAME>
    <LAST_NAME>소룡</LAST_NAME>
   </PERSON>

  </PEOPLE>
 </MEETING>
</MEETINGS>


파일명:ch07_02.html

<html>
<head>
<title>Reading XML element Values</title>
<SCRIPT LANGUAGE="JavaScript">
<!--
 function readXMLDocument(){
 
  var xmldoc, meetingsNode, meetingNode, peopleNode
  var first_nameNode, last_nameNode, outputText

  //새로운 문서객체를 만든다.
  xmldoc = new ActiveXObject("Microsoft.XMLDOM");

  //문서를 읽어들인다.
  xmldoc.load("ch07_01.xml");
 
  //문서의 루트 요소인 <MEETINGS>에 해당되는 노드 객체를 불러오며,
  //documentElement메소를 이용한다.
  meetingsNode = xmldoc.documentElement;

  //firstChild, nextChild, lastChild등의 메소드를 이용, 구성요소의
  //다른 자식 요소들로 마음대로 이동가능
  //firstSibling,nextSibling메소드를 사용하면 동일 레벨에서의 다른 구성요소에 접근 가능
  meetingNode = meetingsNode.firstChild;

  //예 -> <PEOPLE>요소 내에서 세 번째<PERSON>요소로 내려가고자 한다.
  //<PEOPLE>요소는 <MEETING>요소의 마지막 자식에 해당되므로 <PEOPLE>요소에 해당되는 노드에는 다음과
  //같이 접근할 수 있다.
  peopleNode = meetingNode.lastChild;


  //<PEOPLE>요소의 세 번째 사람을 원하는 것은 그 요소의 마지막 자식 요소를 찾아내는 것과 동일하므로
  //여기서는 lastChild 메소드를 사용하여 원하는 사람에게 접근할 수 있다.
  //personNode = peopleNode.lastChild;  /* 마지막 요소 */
  personNode = peopleNode.firstChild;   /* 첫번재 요소 */

  //마지막으로 사람의 이름을 저장하고 있는 <FIRST_NAME>과<LAST_NAME>구성요소에 해당되는
  //노드에 접근하기 위해 firstChild와 nextSibling(현재 노드와 동일 레벨에서의 다음 노드로 이동한다.) 메소드를 사용할 수 있다.
  first_nameNode = personNode.firstChild;
  last_nameNode = first_nameNode.nextSibling;

  //트리에서 자신이 원하는 실제 구성요소의 노드에 접근하는 방식
  //nodeValue속성을 사용하여 first_name과 last_name의 값을 구한다.
  var firstName, lastName
  firstName = first_nameNode.firstChild.nodeValue;
  lastName = last_nameNode.firstChild.nodeValue ;

  outputText = "Third name: " + firstName + " " + lastName;
  messgeDiv.innerHTML = outputText;

 }
//-->
</SCRIPT>
</head>
<body>
 <center>
  <h2>Reading XML element values</h2>

  <input type="button" value="Get the name of the third person" onClick="readXMLDocument();">
  <p>
  <Div id="messgeDiv"></div>
  </p>
 </center>
</body>
</html>

각각 복사해서 파일로 저장한뒤에 ch07_02.html파일을 실행해서 버턴을 클릭해보면 결과를 볼 수 있다.

JavaScript1.2 String 메소드

charCodeAt()
ie4에서는 문자의 Unicode 값을 nn4에서는 ISO-Latin-1 codeset 값을 돌려준다.
alert( "ABC".charCodeAt(0) ) 은 "ABC"에서 첫번째의 문자인 "A"의 값 65를 보여준다. 괄호 안의 숫자가 문자열에서 특정 문자의 위치를 지정한다. 

concat()
2개의 문자열을 하나의 문자열로 만든다.
alert( "안녕".concat("하세요") )는 "안녕하세요"를 보여준다. 함수의 앞에 있는 문자열 다음에 괄호 안에 있는 문자열을 덧붙인다. 

fromCharCode()
charCodeAt()와 반대의 동작을 하는 함수로 Unicode 값이나 ISO-Latin-1 codeset 값을 문자로 돌려준다
String.fromCharCode(65,66,67)은 "ABC"를 보여준다. String.fromCharCode()로 사용한다. 지정하는 인자는 여러개 지정할 수 있다. 

[match()]
Regular Expression의 exec()와 비슷한 동작하지만 RegExp 객체는 만들지 않고 맞는 문자정보를 배열로 반환한다.
var st = "abc def ghi" var arr = st.match(/\w+\s*/g)
arr은 ["abc", "def", "ghi"]를 가지고 있다.

[replace()]  
regular expression을 특정 문자열로 바꾼다. 사용 구문은 아래이다.
문자열.replace(regular expression, "바꿀문자열")
문자열 중에서 regular expression에 맞는 문자열을 "바꿀 문자열"로 바꾸어서 새로운 문자열을 만든다.
var st = "abc def ghi def" var arr = st.replace(/def/g, "DEF")
arr은 "abc DEF ghi DEF"의 문자열이 된다. 

[search()]   Regular Expression의 test()와 비슷한 동작을 하는 메소드로 문자열에서 regular expression을 검색한 것의 index를 반환한다. 검색된 것이 없으면 -1을 반환한다.
var st = "abc def ghi" var arr = st.search(/\w+\s*/g) if( arr != -1) alert("검색됨") else alert("없음") 으로 "검색됨"이 나온다. 위의 arr의 값은 0(zero)이다. 즉, exec()로 했을 때의 arr.index와 같은 값을 가진다. 

[slice()]   문자열에서 두 위치 사이의 문자열을 반환한다. substring()과의 차이점은 두번째 위치를 음수 정수로 지정하여 문자열의 끝에서의 위치를 지정할 수 있는 것이다.
alert( "abcde".slice(1, -2) )는 "bc"를 반환한다. 

[split()]
(1.2에서 수정됨)   나눌 문자로 문자열 뿐만이 아니고 regular expression도 사용할 수 있다.
"123+456+789".split(/\+/)는 ["123", "456", "789"]로 나온다. 

[substr()]   JavaScript1.1의 subString()과 비슷하게 두개의 위치안의 문자열을 반환한다. subString()과 다른점은 문자열의 끝에서 부터도 찾을 수 있는 것이다.
alert( "abcd".substr(-1, 2) )는 "cd"로 나온다. 

substring()
(1.2에서 수정됨) 수정된 사항은 nn4에서 시작위치가 끝위치 보다 더 큰 경우이다. 이 경우 JavaScript1.1에서는 끝위치에서 시작위치 - 1 까지의 문자열을 반환하지만 JavaScript1.2에서는 Run Time error 로 문자열을 반환하지 못한다.
<script language="JavaScript1.2"> "acbd".substring(3, 0) </script>
ie4, ie5에서는 이런 경우 수정되지 않았다. 


 

'Web(웹) Study > Java Script' 카테고리의 다른 글

iframe 높이 자동 조절하기  (0) 2008.03.25
자바스크립트를 통한 XML문서 파싱하기  (0) 2008.03.25
javascript 문자열 처리 함수 정리  (1) 2008.03.25
JavaScript 정규식  (0) 2008.03.25
레이어 팝업 소스  (8) 2008.03.11

문자열 처리하기

anchor()
문서의 목적지를 가리키는 Anchor택을 지정한다.
var anchorString="이 지점으로.." document.write(anchorString.anchor("anchorName1"))
위의 구문은 <A NAME="anchorName1">이 지점으로..</A> 의 HTML을 만든다. 앞의 지정한 문자열을 링크의 내용으로 괄호 안의 문자열은 anchor의 이름이다. 

big()
지정한 문자열을 <big></big> 택으로 감싼다.
var makeBig = "big 입니다." document.write(makeBig.big()) 는 <big>big 입니다.</big> 로 된다. 

blink()
문자열을 <blink></blink> 택으로 감싼다.

bold()
문자열을 <b></b> 택으로 감싼다.

charAt()
문자열에서 특정 위치의 문자를 반환한다. 괄호 속에 지정해 줄 수 있는 정수는 0에서 문자열 길이-1의 정수를 입력할 수 있다.
alert("abc".charAt(1))은 'b'를 반환한다. 

eval()
괄호 속에 있는 문자열을 JavaScript 구문으로 실행한다.
var he = "Hello" eval("alert(" + he + ")" ) 는 alert("Hello") 와 같다. 

fixed()
문자열을 <TT></TT> 택으로 감싼다. 사용법은 big()과 같다.

fontcolor()
문자열을 괄호 속에 넣어준 색상값으로 <FONT COLOR=color> 형식으로 만든다. 색상값은 색상 이름이나 RGB 값을 지정할 수 있다. RGB 값은 여섯개의 16진수 값으로 처음 2개는 red 값, 다음 2개는 green 값, 마지막 2개는 blue값이다.
document.write("빨간색".fontcolor("red")) document.write("흰색".fontcolor(000000)) 는 <FONT COLOR="red">빨간색</FONT>, <FONT COLOR=000000>흰색</FONT> 으로 나온다. 
fontsize() fontcolor()와 비슷하다. <FONTSIZE=size> 의 형식으로 만든다. 괄호 속의 값은 size에 사용할 0에서 7까지의 정수값이다.
document.write("크기 3의 글자".fontsize(3))

[indexOf()]
문자열에서 특정 문자가 있는 위치를 반환한다. 괄호 속에 넣어줄 수 있는 인자는 2개가 있고 첫째것은 찾을 문자, 두번째 것은 찾기 시작할 위치이다. 두번째 인자는 지정하지 않을 수 있고 이 경우 문자열의 첫번째 문자부터 찾기 시작한다.
alert("abc cdf".indexOf("c"))은 2를 반환한다. 만약, 찾을 문자가 없다면 정수 -1을 반환한다. 

italics()
문자열을 <i></i> 택으로 감싼다.
 
lastIndexOf()
indexOf()와 같은 동작을 한다. 유일한 차이점은 이것은 문자열의 오른쪽에서 부터 왼쪽으로 찾는다.
alert("abcd cdf".lastIndexOf("cd"))는 5를 반환한다. indexOf()나 이것이나 문자열의 위치는 모두 왼쪽에서 오른쪽으로 지정되고 첫번째 문자의 위치는 0으로 지정된다. 

link()
다른 문서로 이동하는 <A>택을 지정한다.
var linkString="다음 페이지로.." document.write(linkString.link("next.htm"))
위의 구문은 <A HREF="next.htm">다음 페이지로..</A> 의 HTML을 만든다. 앞의 지정한 문자열을 링크의 내용으로 괄호 안의 문자열은 HREF에 지정될 문서 주소의 이름이다. 

small()
문자열을 <small></small> 택으로 감싼다.

[split()]
문자열을 특정 문자를 기준으로 나누어서 하나의 배열에 차례대로 저장한다. 괄호속에 넣어주는 문자가 기준이 되는 문자이다. 이 문자를 기준으로 양쪽의 문자열을 나눈다. 지정하지 않으면 전체 문자열을 배열에 저장한다.
var strArrey; strArray = "abc,dfe,123".split(",") 는 [abc,dfe,123]으로 strArray는 배열 객체가 된다. strArray.length는 3이고 strArray[2]는 "123"이다. 

strike()
문자열을 <strike></strike> 택으로 감싼다.

sub()
문자열을 <sub></sub> 택으로 감싼다.

[substring()]
문자열에서 지정한 위치 사이에 있는 문자열을 반환한다. 괄호 속에는 두개의 위치값을 인자로 지정해 줄 수 있다. 첫번째 인자의 위치에서 부터 두번째 인자 앞까지의 문자열을 반환한다.
alert( "a12345".substring(2,4) )는 "23"을 보여준다. 두번째 인자를 지정하지 않으면 전체 문자열의 끝까지를 지정하는 것이 된다.
alert( "a12345".substring(2) )는 "2345"를 보여준다.
 
sup()
문자열을 <sup></sup> 택으로 감싼다.

toLowerCase()
문자열을 소문자로 바꾼다.
alert( "Hello My Lover".toLowerCase() )는 "hello my lover"로 된다. 

toUpperCase()
문자열을 대문자로 바꾼다.

[toString()]
String 뿐만이 아닌 모든 객체의 method이다. Array, Boolean, Function, Number 등의 모든 객체를 문자열로 변환한다.
var ar = new Array("abc", "123") alert( ar.toString() ) 은 "abc,123" 을 보여준다.
괄호안에 2에서 16 까지의 진수를 지정해 줄 수도 있는데 이 경우는 숫자를 지정해준 진수의 숫자 문자열로 변환한다. 색상 변환에 사용할 수 있다.
var xx = 255 alert( xx.toString(16) ) 는 255를 16진수 "FF"로 나온다. xx.toString(2)는 "11111111"으로 나온다. 

valueOf()
객체의 원래 값을 돌려준다.

우선 사용예는 다음과 같다.

예)
<script language="javascript">
  function chk(pstr) {
   var chkRep = /....-..-../;
   alert(chkRep.test(pstr));
  }
</script>

정규식은 다음과 같다.

(1) ^ (caret) : 라인의 처음이나 문자열의 처음을 표시
예 : ^aaa (문자열의 처음에 aaa를 포함하면 참, 그렇지 않으면 거짓)

(2) $ (dollar) : 라인의 끝이나 문자열의 끝을 표시
예 : aaa$ (문자열의 끝에 aaa를 포함하면 참, 그렇지 않으면 거짓)

(3) . (period) : 임의의 한 문자를 표시
예 : ^a.c (문자열의 처음에 abc, adc, aZc 등은 참, aa 는 거짓)
a..b$ (문자열의 끝에 aaab, abbb, azzb 등을 포함하면 참)

(4) [] (bracket) : 문자의 집합이나 범위를 나타냄, 두 문자 사이의 "-"는 범위를 나타냄
[]내에서 "^"이 선행되면 not을 나타냄
이외에도 "문자클래스"를 포함하는 [:문자클래스:]의 형태가 있다.
여기에서 "문자클래스"에는 alpha, blank, cntrl, digit, graph, lower, print, space, uppper, xdigit가 있다.
이에 대한 자세한 내용은 C언어의 <ctype.h>를 참조하면 된다.
예를 들어 [:digit:]는 [0-9]와 [:alpha:]는 [A-Za-z]와 동일하다.
이외에 [:<:]와 [:>:]는 어떤 단어(숫자, 알파벳, '_'로 구성됨)의 시작과 끝을 나타낸다.
예 : [abc] (a, b, c 중 어떤 문자, "[a-c]."과 동일)
[Yy] (Y 또는 y)
[A-Za-z0-9] (모든 알파벳과 숫자)
[-A-Z]. ("-"(hyphen)과 모든 대문자)
[^a-z] (소문자 이외의 문자)
[^0-9] (숫자 이외의 문자)
[[:digit:]] ([0-9]와 동일)

(5) {} (brace) : {} 내의 숫자는 직전의 선행문자가 나타나는 횟수 또는 범위를 나타냄
예 : a{3} ('a'의 3번 반복인 aaa만 해당됨)
a{3,} ('a'가 3번 이상 반복인 aaa, aaaa, aaaa, ... 등을 나타냄)
a{3,5} (aaa, aaaa, aaaaa 만 해당됨)
ab{2,3} (abb와 abbb 만 해당됨)
[0-9]{2} (두 자리 숫자)
doc[7-9]{2} (doc77, doc87, doc97 등이 해당)
[^Zz]{5} (Z와 z를 포함하지 않는 5개의 문자열, abcde, ttttt 등이 해당)
.{3,4}er ('er'앞에 세 개 또는 네 개의 문자를 포함하는 문자열이므로 Peter, mother 등이 해당)

(6) * (asterisk) : "*" 직전의 선행문자가 0번 또는 여러번 나타나는 문자열
예 : ab*c ('b'를 0번 또는 여러번 포함하므로 ac, ackdddd, abc, abbc, abbbbbbbc 등)
* (선행문자가 없는 경우이므로 임의의 문자열 및 공백 문자열도 해당됨)
.* (선행문자가 "."이므로 하나 이상의 문자를 포함하는 문자열, 공백 문자열은 안됨)
ab* ('b'를 0번 또는 여러번 포함하므로 a, accc, abb, abbbbbbb 등)
a* ('a'를 0번 또는 여러번 포함하므로 k, kdd, sdfrrt, a, aaaa, abb, 공백문자열 등) doc[7-9]* (doc7, doc777, doc778989, doc 등이 해당)
[A-Z].* (대문자로만 이루어진 문자열)
like.* (직전의 선행문자가 '.'이므로 like에 0 또는 하나 이상의 문자가 추가된 문자열이됨, like, likely, liker, likelihood 등)

(7) + (asterisk) : "+" 직전의 선행문자가 1번 이상 나타나는 문자열
예 : ab+c ('b'를 1번 또는 여러번 포함하므로 abc, abckdddd, abbc, abbbbbbbc 등, ac는 안됨)
ab+ ('b'를 1번 또는 여러번 포함하므로 ab, abccc, abb, abbbbbbb 등)
like.+ (직전의 선행문자가 '.'이므로 like에 하나 이상의 문자가 추가된 문자열이 됨, likely, liker, likelihood 등, 그러나 like는 해당안됨)
[A-Z]+ (대문자로만 이루어진 문자열)

(8) ? (asterisk) : "?" 직전의 선행문자가 0번 또는 1번 나타나는 문자열
예 : ab?c ('b'를 0번 또는 1번 포함하므로 abc, abcd 만 해당됨)

(9) () (parenthesis) : ()는 정규식내에서 패턴을 그룹화 할 때 사용

(10) | (bar) : or를 나타냄
예 : a|b|c (a, b, c 중 하나, 즉 [a-c]와 동일함)
yes|Yes (yes나 Yes 중 하나, [yY]es와 동일함)
korea|japan|chinese (korea, japan, chinese 중 하나)

(11) \ (backslash) : 위에서 사용된 특수 문자들을 정규식내에서 문자를 취급하고 싶을 때 '\'를 선행시켜서 사용하면됨
예 : filename\.ext ("filename.ext"를 나타냄)
[\?\[\\\]] ('?', '[', '\', ']' 중 하나)

정규식에서는 위에서 언급한 특수 문자를 제외한 나머지 문자들은 일반 문자로 취급함 

<head>
<script language="JavaScript">
<!--
function setCookie( name, value, expiredays ) {
    var todayDate = new Date();
        todayDate.setDate( todayDate.getDate() + expiredays );
        document.cookie = name + "=" + escape( value ) + "; path=/; expires=" + todayDate.toGMTString() + ";"
    }

function closeWin() {
    if ( document.notice_form.chkbox.checked ){
        setCookie( "maindiv", "done" , 1 );
    }
    document.all['divpop'].style.visibility = "hidden";
}
//--> 
</script>
</head>
<body bgcolor="#FFFFFF" text="#000000" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"> 


<!-- POPUP -->
<div id="divpop" style="position:absolute;left:395px;top:190;z-index:200;visibility:hidden;">
<table width=300 height=400 cellpadding=2 cellspacing=0>
<tr>
    <td style="border:1px #666666 solid" height=360 align=center bgcolor=white>
    여기에 내용 삽입
    </td>
</tr>
<tr>
        <form name="notice_form">
    <td align=right bgcolor=white>
        <input type="checkbox" name="chkbox" value="checkbox">오늘 하루 이 창을 열지 않음
        <a href="javascript:closeWin();"><B>[닫기]</B></a>
    </td>
</tr>
        </form>
</table>
</div> 

<script language="Javascript">
cookiedata = document.cookie;   
if ( cookiedata.indexOf("maindiv=done") < 0 ){     
    document.all['divpop'].style.visibility = "visible";
    }
    else {
        document.all['divpop'].style.visibility = "hidden";
}
</script>
 
 
 
 
 
많은 소스중에서 제일 괜찮더군요.
 
잘 사용하세요^^

'Web(웹) Study > Java Script' 카테고리의 다른 글

javascript 문자열 처리 함수 정리  (1) 2008.03.25
JavaScript 정규식  (0) 2008.03.25
자바스크립트와 쿠키(cookie) 사용법  (2) 2008.03.10
웹 비표준 innerHTML  (0) 2008.03.10
prototype.js  (0) 2008.03.10

자바스크립트 쿠키는 CGI의 HTTP Cookie와 내용 및 작동하는 법은 같으나 약간의 차이가 있습니다. 아래는 자바스크립트 쿠키에 대한 개요입니다.

1. 자바스크립트에서 지원하는 사용자의 특정 정보를 저장하는 기법
2. 클라이언트의 브라우저에 저장되나 서버에는 저장되지 않습니다.
3. 일정 기간 동안만 유효하게 할 수 있고, 유효기간(만료기한)이 설정되지 않을 경우 브라우저 종료시 자동으로 사라집니다.
4. 클라이언트에는 브라우저가 실행중에는 메모리에, 종료될 경우 만료기한에 따라 cookies.txt라는 파일에 저장될 수 있습니다.
5. 웹 서버의 환경변수 HTTP_COOKIE에는 저장되지 않습니다.

자바스크립트 쿠키는 서버와는 무관하기 때문에 일반적으로 잘 사용하지는 않습니다. 그러나, 클라이언트 내에서는 얼마든지 쿠키의 정보유지기법을 사용할 수 있으므로 간단한 방문 기록 남기기 등에서는 쓰일 수 있습니다.

자바스크립트에서 쿠키를 참조하기 위해서는 document.cookie객체를 사용합니다. 아래는 가장 일반적으로 사용되는 쿠키 관련 자바스크립트 함수들입니다. 아래 함수의 주요 기능은 document.cookie객체의 문자열 조작을 통하여 쿠키로부터 값을 빼내는데 사용됩니다.

function getCookieVal (offset) {
   var endstr = document.cookie.indexOf (";", offset);
   if (endstr == -1) endstr = document.cookie.length;
   return unescape(document.cookie.substring(offset, endstr));
}

function GetCookie (name) {
   var arg = name + "=";
   var alen = arg.length;
   var clen = document.cookie.length;
   var i = 0;
   while (i < clen) { //while open
      var j = i + alen;
      if (document.cookie.substring(i, j) == arg)
         return getCookieVal (j);
      i = document.cookie.indexOf(" ", i) + 1;
      if (i == 0) break;
   } //while close
   return null;
}

function SetCookie (name, value) {
   var argv = SetCookie.arguments;
   var argc = SetCookie.arguments.length;
   var expires = (2 < argc) ? argv[2] : null;
   var path = (3 < argc) ? argv[3] : null;
   var domain = (4 < argc) ? argv[4] : null;
   var secure = (5 < argc) ? argv[5] : false;
   document.cookie = name + "=" + escape (value) +
      ((expires == null) ? "" :
         ("; expires=" + expires.toGMTString())) +
      ((path == null) ? "" : ("; path=" + path)) +
      ((domain == null) ? "" : ("; domain=" + domain)) +
      ((secure == true) ? "; secure" : "");
}

위의 함수에서 사용자가 쓸 함수는 GetCookie(), SetCookie()입니다. 사용하는 문법은 아래와 같습니다.

* GetCookie
설정되어 있는 쿠키의 값을 가져옵니다.

쿠키값 = GetCookie(name)

인수 설명)
name(필수 요소)
저장된 Cookie의 이름
 
예)
cookieval = GetCookie('myCookie');

* SetCookie
쿠키의 값을 설정한다.

SetCookie(name, value, [expires], [path], [domain], [secure])

인수 설명)
name(필수 요소)
Cookie에 저장하고자 하는 이름
value(필수 요소)
Cookie에 저장된 이름(name)에 대한 값
expires(생략 가능)
Cookie가 설정된 후 Cookie가 무효화되는 시간이다.
(GMT Type - "Wdy, DD-Mon-YYYY HH:MM:SS GMT")
설정된 시간이 지나게 되면, 이 Cookie는 사용할 수 없게 된다.
만약 expires에 설정된 시간보다 더 일찍 브라우저가 종료될 경우, 브라우저는 자동으로
cookies.txt라는 파일을 생성하여 그 정보를 이 파일에 저장해 둡니다.

Netscape 4.x의 경우)
C:\Program Files\Netscape\Users\[Profile name]\cookies.txt
Internet Explorer 4.x의 경우)
C:\windows\Cookies\[remote user name]@[domain].txt


path(생략 가능)
문서의 경로명을 설정합니다.
설정하지 않으면 현재 Cookie를 보내는 문서의 URL상의 경로(도메인 명 제외)로 설정됩니다.
domain(생략 가능)
웹 서버의 도메인 명을 설정합니다.
설정하지 않으면 현재 Cookie를 보내는 문서가 속한 도메인 명으로 설정됩니다.
secure(생략 가능)
HTTPS Server(HTTP over SSL)와 같은 Secure Server에서 Cookie를 보낼 경우 이 값을 설정해 줍니다.
 
예 1)
쿠키값만 설정할 경우
SetCookie('myCookie', 1234); 

예 2)
쿠키값 및 만료일을 설정할 경우
var ExpDate = new Date();
ExpDate.setTime(ExpDate.getTime() + 1000*60*60*24);
SetCookie('myCookie', 1234, ExpDate);

※ 위의 예제는 만료일을 쿠키가 생성되는 현재 시간 + 1일로 설정합니다.
만약, 만료일을 쿠키가 생성된 후 1시간으로 설정하겠다면 위의 예제에서 24(시간)를
1(시간) 로 바꾸어 주면 됩니다.


아래의 예제는 쿠키값을 설정하고, 만료일을 쿠키가 설정된 후 1시간 이후로 설정하는
예제입니다.

<html>
<head>
<title>JavaScript Cookie Test</title>
<script language=javascript>
<!--
var ExpDate = new Date();

function getCookieVal (offset) {
   var endstr = document.cookie.indexOf (";", offset);
   if (endstr == -1) endstr = document.cookie.length;
   return unescape(document.cookie.substring(offset, endstr));
}

function GetCookie (name) {
   var arg = name + "=";
   var alen = arg.length;
   var clen = document.cookie.length;
   var i = 0;
   while (i < clen) { //while open
      var j = i + alen;
      if (document.cookie.substring(i, j) == arg)
         return getCookieVal (j);
      i = document.cookie.indexOf(" ", i) + 1;
      if (i == 0) break;
   } //while close
 return null;
}

function SetCookie (name, value) {
   var argv = SetCookie.arguments;
   var argc = SetCookie.arguments.length;
   var expires = (2 < argc) ? argv[2] : null;
   var path = (3 < argc) ? argv[3] : null;
   var domain = (4 < argc) ? argv[4] : null;
   var secure = (5 < argc) ? argv[5] : false;
   document.cookie = name + "=" + escape (value) +
      ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
      ((path == null) ? "" : ("; path=" + path)) +
      ((domain == null) ? "" : ("; domain=" + domain)) +
      ((secure == true) ? "; secure" : "");
}

function SetCookieVal () {
   pathname = location.pathname;
   var myDomain = pathname.substring(0, pathname.lastIndexOf('/')) +'/';
   ExpDate.setTime(ExpDate.getTime() + 1000*60*60);
   SetCookie('MyCookie', 'Hello Cookie!', ExpDate, myDomain);
}
//-->
</script>
<body>
<script language=javascript>
<!--
   if(GetCookie('MyCookie')) {
      alert("Cookie Found");
      document.write(GetCookie('MyCookie') + '<br>');
   }
   else {
      SetCookieVal();
      document.write('새로운 쿠키값이 설정되었습니다. ');
      document.write('보고 싶으시면 Reload를 누르세요.<br>');
      document.write('이 쿠키는 ' + ExpDate.toString());
      document.write(' 에 자동 폭파됩니다.<br>');
   }
//-->
</script>
</body>
</html>

쿠키는 설정된 후에 브라우저가 활성화 되어 있고 만료일이 경과되지 않는 한 브라우저에 따라 설정된 디렉토리 내의 cookies.txt를 지우더라도 값이 유지된다는 점을 주의하기 바랍니다.

'Web(웹) Study > Java Script' 카테고리의 다른 글

JavaScript 정규식  (0) 2008.03.25
레이어 팝업 소스  (8) 2008.03.11
웹 비표준 innerHTML  (0) 2008.03.10
prototype.js  (0) 2008.03.10
Ajax 관련 링크들...  (0) 2008.02.27
AJAX 코딩을 하면서 여러가지를 알아보고 있는데
아무 생각없이 사용하던 innerHTML이 비표준이라는데서 충격을 받았다.
firefox, IE에서 모두 지원해서 그런 생각을 하지 못했던 것이다.

innerHTML을 표준인 DOM API로 바꾸려고 생각을 했는데
그 생각을 접게 되었다.

http://www.quirksmode.org/dom/innerhtml.html

DOM API가 브라우저에 따라서 3배부터 93배 많은 시간이 소요되는 극악의 성능을 보여주고 있던 것이었다.

특히 놀라운 것은 Firefox 계열은 3배 정도 느린데 그치지만, IE는 93배의 시간이 걸리는 대단한 기록을 세워주셨다.

IE의 놀라운 점 또 하나. IE 5.5와 6의 성능 차이이다. DOM API 작업이 IE 5.5에서보다 IE 6에서 10배 정도 느린 점은 아이러니하기도 하고, 무슨 음모론을 떠 올리게 할 정도이다.

표준도 좋지만 사용자의 CPU 자원을 해치지 않도록 innerHTML 정도는 사용해줘도 상관없을 듯.

'Web(웹) Study > Java Script' 카테고리의 다른 글

레이어 팝업 소스  (8) 2008.03.11
자바스크립트와 쿠키(cookie) 사용법  (2) 2008.03.10
prototype.js  (0) 2008.03.10
Ajax 관련 링크들...  (0) 2008.02.27
js :: 팝업메뉴 생성하기  (0) 2008.01.18

prototype.js는 JavaScript Framework이다. 아니, Ajax Framework이라고 표현하는 것이 더 적절하다. Framework이 의미하듯이 자바스크립트로 애플리케이션을 개발하기 쉽도록 많은 Utility 함수를 포함하고 있으며 자바스크립트 자체의 오브젝트 및 클래스를 확장한 오브젝트와 클래스를 제공한다. 또한, prototype.js 자체적으로 제공하는 오브젝트와 클래스가 있다.

자바스크립트 framework이라고 해서 자바스크립트만 다루고 있는 것은 아니다. Ajax의 기본 기능인 비동기 통신과 동기 통신을 위한 클래스를 제공하고 있다.

Download

Prototype is a JavaScript Framework that aims to ease development of dynamic web applications.

Featuring a unique, easy-to-use toolkit for class-driven development and the nicest Ajax library around, Prototype is quickly becoming the codebase of choice for web application developers everywhere.

'Web(웹) Study > Java Script' 카테고리의 다른 글

자바스크립트와 쿠키(cookie) 사용법  (2) 2008.03.10
웹 비표준 innerHTML  (0) 2008.03.10
Ajax 관련 링크들...  (0) 2008.02.27
js :: 팝업메뉴 생성하기  (0) 2008.01.18
자바 스크립트에서 HTTP 요청하기  (0) 2008.01.18

Ajax 기술 정리

Ajax 클라이언트 측 정리 : http://wiki.javajigi.net/pages/viewpage.action?pageId=3921

Ajax 서버 측 정리 : http://wiki.javajigi.net/pages/viewpage.action?pageId=3920

Ajax 패턴 정리 : http://ajaxpatterns.org/Patterns


Ajax 읽어볼만한 글

 
Web 2.0 정리 : http://wiki.javajigi.net/pages/viewpage.action?pageId=4182

Web 2.0과 Ajax 애플리케이션 : http://cafe.naver.com/ajaxdev/4

Ajax의 효용성에 대한 논문 : http://cafe.naver.com/ajaxdev/101

'Web(웹) Study > Java Script' 카테고리의 다른 글

웹 비표준 innerHTML  (0) 2008.03.10
prototype.js  (0) 2008.03.10
js :: 팝업메뉴 생성하기  (0) 2008.01.18
자바 스크립트에서 HTTP 요청하기  (0) 2008.01.18
서서히, 천천히 나타나는 그림  (0) 2008.01.09

#CSS
- (background)-color
 └ menu : '화면배색'의 메뉴색상입니다.
 └ highlight : '화면배색'의 선택항목색상입니다.
- border
 └ buttonhighlight : 메뉴스타일로 입체적으로 나온 스타일입니다.
- line-height : 라인간격을 설정합니다. default는 1입니다.

#JavaScript
:: event객체 :: 이벤트를 처리합니다.
 └ srcElement : 이벤트가 발생한 객체를 반환합니다.
 └ getAttribute("속성") : 해당객체의 속성값을 반환/설정합니다.
 └ offsetX : 컨테이너를 기준으로 이벤트가 발생된 x좌표를 반환/설정합니다.
 └ offsetY : 컨테이너를 기준으로 이벤트가 발생된 y좌표를 반환/설정합니다.
 └ offsetParent : 해당 컨테이너를 가리킵니다.

사용자 삽입 이미지

소스코드<html>
<style type="text/css">
<!--

#popmenus {  // 팝메뉴스타일
 cursor : default;
 position : absolute;
 width : 100px;
 background-color : menu;
 line-height : 1.4;
 padding : 4px;
 border : 2 outset buttonhighlight;
 visibility : hidden;
}

#menuitems {  // 팝메뉴 항목 스타일
 padding-left : 15px;
 padding-right : 10px;
 font-size : 9pt;
}

// -->
</style>
<script language="JavaScript">
<!--

function show_menu() {  // 우측/하단 여분길이계산, 필요시 커서좌측/상단출력
 var rightedge = document.body.clientWidth - event.clientX;  // 우측여분
 var bottomedge = document.body.clientHeight - event.clientY;  // 하단여분

 if (rightedge < popmenus.offsetWidth) {  // 우측여분이 팝메뉴너비보다 작으면
  menuleft = document.body.scrollLeft + event.clientX - popmenus.offsetWidth;
  popmenus.style.left = menuleft;  // 커서x좌표에서 팝메뉴너비를 뺀 값을 팝메뉴x좌표로 할당
 } else {
  popmenus.style.left = document.body.scrollLeft + event.clientX;
 }

 if (bottomedge < popmenus.offsetHeight) {  // 팝메뉴의 y좌표를 할당한다.(위와동일)
  menutop = document.body.scrollTop + event.clientY - popmenus.offsetHeight;
  popmenus.style.top = menutop
 } else {
  popmenus.style.top = document.body.scrollTop + event.clientY;
 }

 popmenus.style.visibility = "visible";
 return false;
}

function hide_menu() {  // 팝메뉴숨김
 popmenus.style.visibility = "hidden";
}

function highlight() {  // 커서가 위치시 활성스타일로
 if (event.srcElement.id == "menuitems") {
  event.srcElement.style.backgroundColor = "highlight";
  event.srcElement.style.color = "white";

  window.status = event.srcElement.url;
 }
}

function lowlight() {  // 커서가 벗어나면 비활성스타일로
 if (event.srcElement.id == "menuitems") {
  event.srcElement.style.backgroundColor = "";
  event.srcElement.style.color = "black";
  window.status = "";
 }
}

function jumpto() {  // 항목클릭시 해당URL로 이동
 if (event.srcElement.id == "menuitems") {
  if (event.srcElement.getAttribute("target") == null)
   window.location = event.srcElement.url;
  else
   window.open(event.srcElement.url, event.srcElement.getAttribute("target"));
  }
}

// -->
</script>
<body>

마우스 오른쪽 버튼을 클릭하면 팝업메뉴가 나타납니다.<br>
<div id="popmenus" onmouseover="highlight()" onmouseout="lowlight()" onclick="jumpto()">

<div id="menuitems" url="http://www.naver.com/" target="win" style="width:100%;">네이버</div>
<div id="menuitems" url="http://www.google.co.kr">구글</div>

</div>
<script language="JavaScript">
<!--

document.oncontextmenu = show_menu;
document.body.onclick = hide_menu;

// -->
</script>

</body>
</html>

'Web(웹) Study > Java Script' 카테고리의 다른 글

prototype.js  (0) 2008.03.10
Ajax 관련 링크들...  (0) 2008.02.27
자바 스크립트에서 HTTP 요청하기  (0) 2008.01.18
서서히, 천천히 나타나는 그림  (0) 2008.01.09
공개소스 웹 HTML 에디터..  (0) 2007.12.27

Java Script
AJAX
2007. 7. 16.
안혁
http://hyok.kr

.참고문헌
 - Beginning Ajax with ASP.NET <Wrox>


 AJAX라는 것은 기존에 없던 새로운 언어가 아닙니다. "Java Script에서 XML비동기적으로 요청하여 기존 웹프로그래밍의 문제점을 해결한다"라고 하는 기존 기술에 대한 재발견이지요. 이미 AJAX가 이야기 된지도 오래 되었기에, 이미 다들 알고 있는 사실이 아닌가 생각됩니다. 앞에서 이야기한 기술의 핵심인 '' 비동기적 요청이라는 것을 해보도록 하겠습니다.

 Java Script에서 HTTP를 요청하려면 HTTP 객체를 먼저 생성하여야 합니다. 브라우저에 따라 조금 다른데요. 비 MS Explore에서는
    xmlHttpObj =
new XMLHttpRequest();
MS Explore에서는 버전에 따라
    xmlHttpObj =
new ActiveXObject("Microsoft.XMLHTTP");
또는
    xmlHttpObj =
new ActiveXObject("Msxml2.XMLHTTP");
의 방식으로 객체를 생성할 수 있습니다. 이를 코드로 표현하여 본다면
    if(window.XMLHttpRequest)
        xmlHttpObj =
new XMLHttpRequest();
    else
    {
       
try
        {
            xmlHttpObj =
new ActiveXObject("Microsoft.XMLHTTP");
        }
       
catch(e)
        {
            xmlHttpObj =
new ActiveXObject("Msxml2.XMLHTTP");
        }
    }
정도로 표현할 수 있겠습니다. 객체 생성시 마다 매번 이를 기술하는 것보다 함수로 만들어 호출하는 것이 좋으리라 생각됩니다. 저는 다음과 같이 작성하여 이를 CommonAJAXLibrary.js라는 파일로 저장하였습니다. 함수명에 XML글자가 들어있는 것은 이 함수의 주목적이 XML을 다루것에 있기 때문입니다. 꼭 XML만 요청할 수 있어서 그런 것은 아니며 HTML페이지도 요청할 수 있습니다. CreateXmlHttpRequestObject() 함수 위에 존재하는 5개의 변수는 이후에 사용될 상수값입니다. 이에 대해서는 잠시 후 설명드리겠습니다. 여기서는 상수 4만 필요하지만, 코드에 4만 적혀있으면 이해하기 더욱 힘들 것 같아 모두 기록해둡니다. 변수명을 보시면 각각이 무었인지 추측하실 수 있으리라 생각됩니다. 일단 넘어갑시다.


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


   
 var READYSTATE_UNINITIALIZED    = 0; 
    var READYSTATE_LOADING          = 1; 
    var READYSTATE_LOADED           = 2; 
    var READYSTATE_INTERACTIVE      = 3; 
    var READYSTATE_COMPLETE        = 4;      

    // XML HTTP Request 객체생성, 반환 
    function CreateXmlHttpRequestObject() 
    { 
        if(window.XMLHttpRequest) 
            xmlHttpObj = new XMLHttpRequest(); // for non-MS browsers 
        else 
        { 
            // for MS browser by version. 
            try 
            { 
                xmlHttpObj = new ActiveXObject("Microsoft.XMLHTTP"); 
            } 
            catch(e) 
           { 
                xmlHttpObj = new ActiveXObject("Msxml2.XMLHTTP"); 
            } 
        } 
     
        return xmlHttpObj; 
    }


 
일단 위의 코드를 CommonAJAXLibrary.js라는 화일로 저장한 다음의 코드를 따라오세요.
 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
 

   
    <script type="text/javascript" src="./CommonAJAXLibrary.js"></script> 
    <script type="text/javascript"> 
    function MakeXMLHttpCall()
    {
        var xmlHttpObj;
        xmlHttpObj = CreateXmlHttpRequestObject();
   
        if(xmlHttpObj)
        {
            var url = "./DataFile.xml";
            xmlHttpObj.open("GET", url, true);
           
xmlHttpObj.onreadystatechange = function()
           { 
                if(xmlHttpObj.readyState == READYSTATE_COMPLETE) 
                { 
                    document.getElementById("divResults").childNodes
[0].nodeValue = xmlHttpObj.responseText; 
                } 
            }
           
xmlHttpObj.send(null); 
        } 
    } 
    </script>


 6 : xmlHttpObj
변수에 방금 만든 함수를 사용하여 XMLHttpRequest객체를 생성합니다.
 10 : url
요청할 페이지의 웹주소를 넣은 11번째 url 줄에서 요청 페이지로 설정합니다.
 11 : xmlHttoObj.open("GET", url, true)
이라하여 요청 URL 설정하는데, 3번째 인자가 false이면 동기식, true이면 비동기식 요청입니다. 동기식으로 요청하면 응답이 있을때까지 대기하며, 비동기식으로 요청하면 응답이 있을때까지 다른 일을 합니다.
 12 : xmlHttpObj.onreadystatechange
이름으로 미루어 보아 요청상태가 변할때 호출하게 함수를 지정하는 것이라 추측 가능하군요. 상태가 변할때마다 호출하는데, 내용을 보면 '완료'상태가 되었을때 xmlHttpObj.responseText 요청한 HTML divResults라는 녀석에게 대입하라는 내용입니다. divResults <div>테그입니다. 오해할만한 것이 있다면, 지금까지는 실행이 아니고 설정이라는 것입니다.
 19 : xmlHttpObj.send(null)
이라는 명령으로 설정에 따라 요청이 시작됩니다. 눈에는 보이지 않지만, 뒤에서 요청이 이루어지고 완료가 되었을때 결과가 <div>테그인 divResults 입력됩니다. 그러면 순간 결과는 화면에 출력되겠지요.

 
다음은 출력을 위한 HTML페이지 입니다. 자바스크립트와 같은 화일에 입력하셨야 합니다.
 


1
2
3
4
5
6
7
8
 

   
<body> 
    <form id="form1" method="post" runat="server"> 
        <input type="button" onclick="MakeXMLHttpCall();" value="Test XMLHTTP  Call" /> 
        <br /> 
        <br /> 
        <div id="divResults">(no results)</div> 
    </form>
</body>


 
위의 자바스크립트와 HTML 화일에 작성하여 마음에 드는 이름으로 저장하십시오. 코드를 그대로 따라오셨다면, 화일과 CommonAJAXLibrary.js 같은 폴더에 있어야 합니다. 다음의 XML코드가 바로 요청대상인 DataFile.xml입니다. 물론 화일도 같은 위치에 있어야 합니다. 내용은  XML 아니어도 됩니다. 일반 HTML 작성해도 되며 텍스트 문서이어도 상관없습니다.
 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 


<?
xml version="1.0" encoding="utf-8" ?>
<Customers> 
  <Customer> 
    <Firstname>Foe</Firstname> 
    <Lastname>Bloggs</Lastname> 
    <email>joe@bloggs.com</email> 
  </Customer> 
  <Customer> 
    <Firstname>Alen</Firstname> 
    <Lastname>Anonymous</Lastname> 
    <email>anon@ymous.com</email> 
  </Customer>
  <Customer> 
    <Firstname>Marvin</Firstname> 
    <Lastname>Martian</Lastname> 
    <email>marvin@mars.com</email> 
  </Customer>
</Customers>


 HTML
화일을 브라우저로 열면 다음과 같은 화면이 나오게 됩니다.

사용자 삽입 이미지
버튼을 누르면 다음과 같이 요청된 페이지가 출력됩니다.

사용자 삽입 이미지
<head>
<script LANGUAGE="JavaScript">
function trans() {
obj1.filters[0].apply();
obj1.style.visibility = "visible";
obj1.filters[0].play();
}
</script>
</head>

<body>
<body onLoad="trans();">
<IMG ID="obj1"
SRC="image/marado.gif"
STYLE="filter: revealTrans(duration=5, transition=19); visibility: hidden">
</body>
이 놀라운 프로그램들 보면서 이제 정말 대세는 웹 플랫폼이 될 것이라는 생각이 든다..
두 프로그램 모두 아무런 설치과정이 없으니 정말 편하다..

FCKeditor - the text editor for internet
공개 HTML 에디터.. UI도 아주 멋지고 IE, FF, 모질라, 넷스케이프 4가지 웹브라우저를 지원한다.. 데모도 직접 바로 동작을 시켜볼 수 있다.. 공개 소프트웨어니 물론 소스도 바로 다운로드 받아 바로 사용해볼 수도 있다..
단점이라면 화면이 나타나는데 시간이 꽤 많이 소요된다.. CPU도 안 올라가고, HDD를 많이 읽는 것도 아닌데 암튼 꽤 기둘려야 한다.. 에디터 화면이 뜰때마다 이러니, 너무 느린게 아닌가 하는 생각도 든다..

AJAX Write - the web based word processor
구글에서 인수를 하려고 한다는 (소문만 듣고 확인을 못해봤다..) 회사의 제품.. 이제 에디터 수준을 넘어서 워드 프로세서까지 등장을 했다.. 로딩되는 속도, 위의 에디터 보다 훨씬 느리다.. 역시 워드 프로세서 답다.. (고럼~ 그래도 명색이 워드프로세서인데.. 그정도 위세는 부려야지.. 포토샵 봐.. 로딩속도, 아주 중후하잖아.. 그 정도는 안되더라도 워드 프로세서 답게 어느 정도는..) 웹 어플리케이션에서 스플래쉬 윈도우가 등장할 정도니까.. 오랜시간 기둘려 등장한 화면은 요즘의 세련된 워드프로세서에는 못 미치지만, 초창기 워드 프로세서의 모습이다.. 이제 웹에서 이런 것도 된다.. 놀랍다.. 지원하는 포멧은 MS-Word, Open Office, RTF, PDF.. 이것도 놀랍다.. 표 그리기는 정말 불편한 수준인데, 곧 좋아지겠지..
더 큰 단점은 아직은 Fire Fox 전용이라는 것이다.. 지원하는 웹브라우저에 IE를 빼놓다니.. 멋진 놈들이다.. 해서 멋진 모습을 직접 구경해보려면 FF를 설치해야 한다.. FF도 좋은 웹브라우저고, 이 웹 워드 프로세서가 돌아가는 모습은 정말 봐둬야 하는 멋진 작품이니, FF를 지금이라도 설치하는게 좋다.. (앞으로 FF와 IE를 모두 사용하면서 비교하게 될 일이 점점 더 많이 생길 것이니 얼른 깔아두는게 좋을것이다..)

웹용 워드프로세서 구현에 관심을 가졌던 사람들이 많았는가 보다.. ZOHO Writer 라는 제품도 있다.. (웹 워드 프로세서를 써보자~ 소개글 참조)
안에 html 참조해 보시고요.
http://script.aculo.us 사이트의
sortable 소스를 기본으로 했기 때문에 script.aculo.us 의 라이브러리가 기본적으로 반드시 필요합니다.


프로토 타잎 방법을 정확하게 모르는 관계로 자동으로 create 하는 부분은 못 했구요
아래와 같이 실행하셔야 합니다. ^^

var personalSort    = new personalSorts;
personalSort.create(    "firstlist,secondlist",
                        {    "callBack":"loadXml", "tmpBody":"content" },
                        {    "dropOnEmpty":true, "constraint":false,
                            "onChange":function(){
                                personalSort.makeCookies();
                            }
                        }
                    );
personalSort.parseAsync( getCookie( "firstlist" ) );
personalSort.parseAsync( getCookie( "secondlist" ) );




개인적으로 만든 personalSorts 안의 변수 및 정보들 입니다.

create(entry, personalSortsOptions, sortTableOptions)    : 개인화 스크립트를 생성합니다.
    entry                : Sortable이 구동될 document ID
    personalSortsOptions
        nodeId            : 추가시 element Domain ID    (없는경우 rss)
        nodeCalss        : 추가시 element Class        (없는경우 item)
        tmpBody            : 글 내용이 들어가는 곳의 Domain ID
        tplName            : 템플릿을 body 에서 직접 가져 오는 경우 해당 부분의 ID
        tplString        : 글 내용 부분에 들어가는 템플릿 내용
        callBack        : element를 추가한 후에 대한 액션을 정의할 콜백함수명( 인자는 무조건 identity 한개만 들어감 )
        cookieExpire    : 쿠키 지속일

    sortTableOptions    : (    http://script.aculo.us    관련 매뉴얼 참조)


makeSortItem(locate, idx, display)                        : 아이템을 생성합니다.
    locate                : entry 위치 ( 1 부터 시작 )
    idx                    : 해당 아이템의 고유 identity (Rss 를 사용 한다면, Rss idx 같은...)
    display                : 열림(1), 닫힘(0)


parseAsync(items)                                        : 문자열을 파싱해 화면에 출력합니다.
    items                : 직렬화된 아이템 문자열. 아이템간의 구분은 , 로 합니다.
                            makeSortItem 에 들어갈 정보들이 1-1-0,2-2-0,2-3-0
                            등의 문자열로 처리됩니다.


removeItem(idx)                                            : 해당 아이템을 삭제합니다.
    idx                    : 해당 아이템의 고유 identity (Rss 를 사용 한다면, Rss idx 같은...)


serialize(entryName[, loc])                                : item 정보들을 직렬화 시킵니다.
    entryName            : 직렬화된 정보를 가지고 올 해당 엔트리의 이름
    loc                    : 엔트리 위치값
                            ( 즉 loc 가 입력되지 않으면 엔트리 순서-idx-display 정보만 리턴됩니다)


serializeAll()                                            : 모든 엔트리에 대한 정보를 직렬화 시킵니다.


makeCookies()                                            : 쿠키를 생성합니다.

ajax를 이용한 파일 탐색기 입니다.

처음에 트리 구조를 공부하다가 만든건데 어쩌다 보니 탐색기가 되어 버렸네요.

조금만 수정 하시면 웹하드로도 사용하실수 있을겁니다.

safari3, FF2 , IE6,7 에서 테스트해보았습니다.

사용하실때 tree.html안의 root경로만 변경하여 주시면 됩니다.

- 반드시 접근할수 있는 경로로 변경해주세요.
- 접근할수 없는 권한의 경로로 이동하면 에러가 나네요.. -.-;

<script language="javascript">
//경로(phth=불러올수 있는 서버 주소(절대경로)) , 리턴되는 값을 받을 함수
root = "접근할수 있는 경로";
xmlHttp("data.php?path="+root,tree.view);
</script>



// 주민번호 체크
  function CheckJumin(obj, step) {
    var err = 0;
    if(step == "submit"){
        var objchar = eval("document.all."+ obj + "1");
        var objchar2 = eval("document.all."+ obj + "2");

        if(objchar.value.length != 6){
            alert("주민등록번호를 정확히 입력하여 주세요.");
            objchar.value = "";
            objchar.focus();
            return false;
        }
        if(objchar2.value.length != 7){
            alert("주민등록번호를 정확히 입력하여 주세요.");
            objchar2.value = "";
            objchar2.focus();
            return false;
        }

    }else if(step == "write"){
        var objchar = eval("document.all."+ obj.name.substring(0, obj.name.length - 1) + "1");
        var objchar2 = eval("document.all."+ obj.name.substring(0, obj.name.length - 1) + "2");
    }

    for(CJ_i=0;CJ_i<objchar2.value.length;CJ_i++){
        var juminnum=objchar2.value.charAt(CJ_i);
        if (juminnum < '0' || juminnum > '9'){
            alert("주민등록번호는 숫자만 가능합니다.");
            objchar2.value = objchar2.value.substring(0, CJ_i);;
            objchar2.focus();
            return false;
        }
    }

    if(objchar2.value) {
         if(objchar2.value.length == 7) {

            var nowdate = new Date();
            var nowyy = nowdate.getFullYear();
            var nowmm = nowdate.getMonth() +1;
            var nowdd = nowdate.getDate();

            if (objchar2.value.charAt(0) == "1" || objchar2.value.charAt(0) == "2" ){
                var objyy = 1900 + parseInt(objchar.value.charAt(0)) * 10 + parseInt(objchar.value.charAt(1));
            }else if(objchar2.value.charAt(0) == "3" || objchar2.value.charAt(0) == "4" ){
                var objyy = 2000 + parseInt(objchar.value.charAt(0)) * 10 + parseInt(objchar.value.charAt(1));
            }else{
                err=1;
            }

            var objmm = parseInt(objchar.value.charAt(2)) * 10 + parseInt(objchar.value.charAt(3));
            var objdd = parseInt(objchar.value.charAt(4)) * 10 + parseInt(objchar.value.charAt(5));

            if (nowyy < objyy){
                err = 1;
            }else if (nowyy == objyy){
                if (nowmm < objmm){
                    err = 1;
                }else if (nowmm == objmm){
                    if (nowdd < objdd){
                        err = 1;
                    }
                }
            }

            if (objmm < 1|| objmm > 12){
                err = 1;
            }

            if (objdd < 1|| objdd > 31){
                err = 1;
            }

            if (objmm == 4 || objmm == 6 || objmm == 9 || objmm == 11 ){
                if (objdd == 31){
                    err = 1;
                }
            }

            if (objmm==2){
                var g=parseInt(objyy/4)

                if (isNaN(g)) {
                    err=1;
                }
                if (objdd>29) err=1;
                if (objdd==29 && ((objyy/4)!=parseInt(objyy/4))) err=1;
            }

            var fulljumin = objchar.value + objchar2.value;
            var hap = 0;
            var j = 0;

            for (CJ_ii=0; CJ_ii<12;CJ_ii++){
                if(j < 2 || j > 9){j=2;}
                hap = hap + (parseInt(fulljumin.charAt(CJ_ii)) * j);
                j++;
            }
            
            if ((11 - (hap%11))%10 != parseInt(fulljumin.charAt(12))){
                err=1;
            }

            if (err == 1){
                alert("올바른 주민등록 번호가 아닙니다.");
                objchar.value = "";
                objchar2.value = "";
                objchar.focus();
                return false;
            }
        } 
    }
    return true;
  }

// 사업자번호 체크
  function CheckCom(obj, step) {
    var err = 0;

    if(step == "submit"){
        var objchar1 = eval("document.all."+ obj + "1");
        var objchar2 = eval("document.all."+ obj + "2");
        var objchar3 = eval("document.all."+ obj + "3");

        if(objchar1.value.length != 3){
            alert("사업자등록번호를 정확히 입력하여 주세요1.");
            objchar1.value = "";
            objchar1.focus();
            return false;
        }
        if(objchar2.value.length != 2){
            alert("사업자등록번호를 정확히 입력하여 주세요2.");
            objchar2.value = "";
            objchar2.focus();
            return false;
        }
        if(objchar3.value.length != 5){
            alert("사업자등록번호를 정확히 입력하여 주세요3.");
            objchar3.value = "";
            objchar3.focus();
            return false;
        }

    }else if(step == "write"){
        var objchar1 = eval("document.all."+ obj.name.substring(0, obj.name.length - 1) + "1");
        var objchar2 = eval("document.all."+ obj.name.substring(0, obj.name.length - 1) + "2");
        var objchar3 = eval("document.all."+ obj.name.substring(0, obj.name.length - 1) + "3");
    }

    for(CC_i=0;CC_i<objchar3.value.length;CC_i++){
        var comnum=objchar3.value.charAt(CC_i);
        if (comnum < '0' || comnum > '9'){
            alert("사업자등록번호는 숫자만 가능합니다.");
            objchar3.value = objchar3.value.substring(0, CC_i);;
            objchar3.focus();
            return false;
        }
    }

    if(objchar3.value) {
         if(objchar3.value.length == 5) {


            var fullcom = objchar1.value + objchar2.value + objchar3.value;
            var hap = 0;
            var CC_j = 0;
            var cal_arr = new Array("1","3","7","1","3","7","1","3","5");
            for (CC_ii=0; CC_ii<9;CC_ii++){
                hap = hap + (parseInt(fullcom.charAt(CC_ii)) * parseInt(cal_arr[CC_j]));
                CC_j++;
            }

            hap = hap + parseInt((parseInt(fullcom.charAt(8))*5)/10);

            if ((10 - (hap%10))%10 != parseInt(fullcom.charAt(9))){
                err=1;
            }

            if (err == 1){
                alert("올바른 사업자 번호가 아닙니다.");
                objchar1.value = "";
                objchar2.value = "";
                objchar3.value = "";
                objchar1.focus();
                return false;
            }
        } 
    }
    return true;
}

// 법인번호 체크
  function CheckBubin(obj, step) {
    var err = 0;

    if(step == "submit"){
        var objchar = eval("document.all."+ obj + "1");
        var objchar2 = eval("document.all."+ obj + "2");

        if(objchar.value.length != 6){
            alert("법인등록번호를 정확히 입력하여 주세요.");
            objchar.value = "";
            objchar.focus();
            return false;
        }
        if(objchar2.value.length != 7){
            alert("법인등록번호를 정확히 입력하여 주세요.");
            objchar2.value = "";
            objchar2.focus();
            return false;
        }

    }else if(step == "write"){
        var objchar = eval("document.all."+ obj.name.substring(0, obj.name.length - 1) + "1");
        var objchar2 = eval("document.all."+ obj.name.substring(0, obj.name.length - 1) + "2");
    }


    for(CB_i=0;CB_i<objchar2.value.length;CB_i++){
        var bubinnum=objchar2.value.charAt(CB_i);
        if (bubinnum < '0' || bubinnum > '9'){
            alert("법인등록번호는 숫자만 가능합니다.");
            objchar2.value = objchar2.value.substring(0, CB_i);;
            objchar2.focus();
            return false;
        }
    }

    if(objchar2.value) {
         if(objchar2.value.length == 7) {


            var fullbubin = objchar.value + objchar2.value;
            var hap = 0;
            var j = 0;

            for (CB_ii=0; CB_ii<12;CB_ii++){
                if(j < 1 || j > 2){j=1;}
                hap = hap + (parseInt(fullbubin.charAt(CB_ii)) * j);
                j++;
            }
            
            if ((10 - (hap%10))%10 != parseInt(fullbubin.charAt(12))){
                err=1;
            }

            if (err == 1){
                alert("올바른 법인등록번호가 아닙니다.");
                objchar.value = "";
                objchar2.value = "";
                objchar.focus();
                return false;
            }
        } 
    }
    return true;
}

IFRame 높이를 자동으로 도큐먼트 크기에 맞게 조정하는 함수입니다.
<script language="javascript">
function calcHeight(FrameName)
{
 
  var the_height= document.getElementById(FrameName).contentWindow.document.body.scrollHeight;
document.getElementById(FrameName).height=the_height;
}
</script>

예)
<iframe id="IFRAME" src="somepage.html" width="100%" onLoad="calcHeight('IFRAME')"></iframe>

동작 브라우저 : IE,FF,Netscape,Opera
===============================================

이번에 소개할 MiNiFTP 프로그램은 SWFUpload (http://swfupload.mammon.se/) 라이브러리를 이용해 구현한 것입니다. SWFUpload는 아주 심플한 javascript/flash 라이브러리로써, 플래시의 굉장한 업로드 기능을 깔끔한 UI로 편리하게 이용하고 구성할 수 있도록 해 줍니다.

본 프로그램은 MiNi(미니) FTP로써 특정 폴더내의 파일을 웹상에서 편리하게 관리 할 수 있도록 해주는데 그 목적이 있습니다. 해당 프로그램을 응용해 전체 사이트의 웹FTP로 활용할 수도 있습니다.
기존의 웹FTP라 함은 별도의 ActiveX를 설치하여 사용하거나 웹상에서 바로 사용하더라도 파일을 하나씩 업로드 해야 하는데 불편함이 있었습니다.
하지만 이 MiNiFTP 프로그램은 어떠한 ActiveX를 설치할 필요도 없으며(단, Flash Player가 설치 되어 있어야 함) SWFUpload를 이용해 여러개의 파일을 동시에 선택하고 업로드 할수 있도록 구현되었습니다.

데모 : http://miniftp.webrish.com
데모 : http://demo.swfupload.org/

<script language="JavaScript">
function copy_cont(){
window.event.returnValue = true;
window.setTimeout('copyright()', 25);
}
 function copyright() {  
if (window.clipboardData) {  
var txt = window.clipboardData.getData('Text');  
txt = '<!-- http://www.blog4u.kr -->\r\n\r\n\r\n' + txt;  
var result = window.clipboardData.setData('Text', txt);  } }
</script>

<body oncopy="copy_cont()">


복사할 때 복사 내용에 특정 내용 포함 시키기~
전통적인 웹 애플리케이션 방법에서는‘역삼1동’을 입력하고‘찾기’버튼을 클릭했을 때 한번만 수행 하면 되지만, Ajax 방법은‘역’, ‘삼’, ‘1’, ‘동’을 입력할 때마다 서버에서 우편번호와 주소 데이터를 가져와서 웹 페이지에 출력하는 일련의 과정을 수행하게 된다. 즉, 네 번을 수행하는 것이다. 예를들어, 웹 사이트 접속자가 10,000명이라고 하면 40,000번을 수행하게 되는 것이다. 물론, 반드시 이와 같은 수치가 성립되는 것은 아니지만, 실행 횟수가 많아지는 것은 사실이다.


서제스트 제공은 반드시 서버에 부하를 준다고 할 수는 없지만 부하를 줄 가능성이 매우 높다. 하지만, 웹 서버에서 HTML을 해석하지 않고 데이터만 송수신하게 되므로 전통적인 방법보다 서버의 부하를 줄이는 면도 있다. 따라서 반드시 4배의 부하를 주는 것은 아니다. 또한, 비동기 통신 방법으로 사용자가 시스템을 사용하는 동안 서버에서 데이터를 가져올 수 있으므로 사용하는 입장에서 보면 4배의 속도가 걸리는 것은 아니다.


이 시점에서 개발자가 반드시 짚고 넘어갈 사항이 있다. 사용자의 편리성과 시스템의 부하 라는 양면성 이다. 두 마리 토끼를 모두 잡을 수 없으므로 한 쪽을 선택해야 하는데, 시스템은 사용자를 위한 것이므로 사용자의 편리성을 선택해야 한다는 것이다. 시스템이 부하가 걸린다고 해서 사용자의 편리성을 포기할 수는 없다.

출처 : Tong - dozob님의 etc.통

Prototype과 Rico를 이용한 드래그... 코드없음...

 from PhpSchool : http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=ajax&wr_id=248

개발 사이트 : http://ajax.fixmedia.net/

자바스크립트 프로토타입 출처

*  Prototype JavaScript framework, version 1.4.0
 *  (c) 2005 Sam Stephenson <
sam@conio.net>
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site:
http://prototype.conio.net/

드래그 엔 드랍 프레임워크
Rico
/**
  *
  *  Copyright 2005 Sabre Airline Solutions
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
  *  file except in compliance with the License. You may obtain a copy of the License at
  *
  *       
http://www.apache.org/licenses/LICENSE-2.0
  *
  *  Unless required by applicable law or agreed to in writing, software distributed under the
  *  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  *  either express or implied. See the License for the specific language governing permissions
  *  and limitations under the License.
  **/

AJAX 기술의 독특함과 그 막강한 효과를 내내 들어오던 찰나,
구글의 한 페이지(
http://google.co.kr/ig)를 만난 이후 그 화면이 머릿속에서 지워지질
않아 드래그 앤 드랍 프레임워크를 뒤적뒤적이던 중 이 곳 스쿨 아래 글의 Rico 소스를
통해 입맛대로 커스터마이징 해보았습니다.

이것 저것 해보다보니 드래그 앤 드랍의 원리를 대충 이해할 수 있었던 것 같네요.

우선 작업하면서 재낀 부분들 몇가지를 들자면,
드래그 가능한 블럭이 있어야 하며, 그 블럭이 있었던 자리에 복귀하기 위해
"Temp Area"를 구성해주어야 했습니다.
블럭과 블럭간의 이동을 꾀하기 위해 드랍존을 구성하는 방식은 획기적인 것 같습니다.

구성 페이지 :
http://ajax.fixmedia.net

AJAX

Ajax는 자바스크립트를 통하여 비동기적으로 외부 데이터를 처리하기 위한 기법입니다.
(※ 더 자세한 정보가 필요하면 다음 링크 문서를 참조해 보시길... )

HTML, XML, Javascript 등에 대한 기초지식과 자바 JSP/Servlet을 탑재한 WebServer가 있다면,
다음 예제를 직접 실행해 보는 것이 위의 정의를 이해하는 가장 빠른 방법입니다.

예제는 두 개의 파일로 구성되어 있습니다.

(1) 클라이언트측의 DynamicUpdate.html 파일은 일정한 시간간격으로 서버측에 서비스를 요청하고,
받은 문자열을 페이지의 지정한 영역에 추가합니다. 이 때 전체페이지를 refresh 하지 않고 지정영역만을 갱신합니다.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Ajax Dynamic Update</title>

<script type="text/javascript">
 var xmlHttp;
 var urlServer = "/your/path/DynamicUpdateServlet.jsp";
 function createXMLHttpRequest() {
   if (window.ActiveXObject) {
     xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
   }
   else if (window.XMLHttpRequest) {
     xmlHttp = new XMLHttpRequest();  
   }
 }
 
 function doStart() {
   createXMLHttpRequest();
   var url = urlServer + "?task=reset";
   xmlHttp.open("GET", url, true);
   xmlHttp.onreadystatechange = startCallback;
   xmlHttp.send(null);
 }

 function startCallback() {
   if (xmlHttp.readyState == 4) {
     if (xmlHttp.status == 200) {
       setTimeout("pollServer()", 5000);
       refreshTime();
     }
   }
 }
 
 function pollServer() {
   createXMLHttpRequest();
   var url = urlServer + "?task=hoot";
   xmlHttp.open("GET", url, true);
   xmlHttp.onreadystatechange = pollCallback;
   xmlHttp.send(null);
 }
 
 function refreshTime(){
   var time_span = document.getElementById("time");
   var time_val = time_span.innerHTML;

   var int_val = parseInt(time_val);
   var new_int_val = int_val - 1;
  
   if (new_int_val > -1) {
     setTimeout("refreshTime()", 1000);
     time_span.innerHTML = new_int_val;  
   } else {
     time_span.innerHTML = 5;
   }
 }
 
 function pollCallback() {
   if (xmlHttp.readyState == 4) {
     if (xmlHttp.status == 200) {  
       var message = xmlHttp.responseXML.getElementsByTagName("message")[0].firstChild.data;
       if (message != "done") {
         var new_row = createRow(message);
         var table = document.getElementById("dynamicUpdateArea");
         var table_body = table.getElementsByTagName("tbody").item(0);
         var first_row = table_body.getElementsByTagName("tr").item(1);
         table_body.insertBefore(new_row, first_row); 
         setTimeout("pollServer()", 5000);
         refreshTime();
       }
     }
   }
 }
 
 function createRow(message) {
   var row = document.createElement("tr");
   var cell = document.createElement("td");
   var cell_data = document.createTextNode(message);
   cell.appendChild(cell_data);
   row.appendChild(cell);
   return row;
 }
</script>
</head>
<body>

<h1>Ajax를 이용한 페이지 자동 갱신 예제</h1>
버튼을 누르면 이 페이지의 자동 갱신을 시작합니다:
<input type="button" value="시~작!!" id="go" onclick="doStart();"/>
<p>
페이지는 <span id="time" style="color:blue; text-weight:bold">?</span> 초 후에 바뀝니다.
<p>
<table id="dynamicUpdateArea" align="left">
  <tbody>
   <tr id="row0">
     <td></td>
   </tr>
  </tbody>
</table>

</body>
</html>

(2) 서버측 DynamicUpdateServlet.jsp는 클라이언트의 요청에 대해 단순히, 순차적으로 하나의 문자열을 xml 형식으로 던져줍니다.

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

<%!
/**
 * @(#) DynamicUpdateServlet.jsp
 *
 * Copyright ⓒ 1999-2000 by (c) CheckersLab.com
 * All rights reserved.
 *
 * NOTICE : Refer our copy and redistribution policy guide.
 *
 * @author  Hoyal Kim, hoyal.kim@gmail.com
 *
 */
%>

<%@ page import="java.io.*" %>
<%@ page import="java.net.*" %>

<%!
 private int counter = 1;
%>
<%
     String res = "";
     String task = request.getParameter("task");
     String message = ""; 
     if (task.equals("reset")) {
     counter = 1;
     } else {
     switch (counter) {
      case 1: message = "그대 나의 사랑아"; break;
      case 2: message = "아 웃고 있어도 눈물이 난다"; break;
      case 3: message = "뜨거운 이름 가슴에 두면 왜 한숨이 나는 걸까"; break;
      case 4: message = "아름다운 죄 사랑때문에 홀로지샌 긴 밤이여"; break;
      case 5: message = "마른 꽃 걸린 창가에 앉아 외로움을 마셔요"; break;
      case 6: message = "바람속으로 걸어갔어요. 이른 아침의 그 찻집"; break;
      case 7: message = "그 겨울의 찻집"; break;
      case 8: message = "done"; break;
     }
     counter++;
     }
     res = "<message>" + message + "</message>";
     response.setContentType("text/xml; charset=utf-8");
     response.setHeader("Cache-Control", "no-cache");
     out.println("<response>");
     out.println(res);
     out.println("</response>");
%>


%% 드리프트의 openAPI v 0.000001 %%

1) BaloonToolTip v0.8 - 자바스크립트 모듈화 하라고 해서 자바 메서드처럼 표현해 봤음
    친절하게도 사용하실 수 있는 말풍선 이미지도 첨부함 - -ㅋ 포토샵으로 직접 이뿌게 그렸삼

void checkLength(Object, int limit, String messageHead){
   ~~~ examine validation & printout to that document & so on... Blah Blah ~~~
}

퍼갈때는 댓글을 남겨주셈

사용자 삽입 이미지

1. CSS단

#ssnMessage{
 z-index:0;
 position : absolute;
 float: left;
 padding: 4px 8px 0px; 
 width:190px;
 height:43px;
 font-weight:bold;
 color: #ff0000;
 text-align: center;
 background: url(../images/login/baloon.gif) no-repeat;
}


2. 헤드의 자바스크립트 단

function checkLength(obj,charLength,msg){   // 매개인자 : 1.해당 폼(text) 객체, 2. 유효문자 길이, 3. 출력 메세지 '목적어' 혹은 '주어'
 
 var x1 = event.screenX;
 var x2 = event.offsetX;
    var x3 = x1-x2-70;
   
    var y1 = event.screenY;
    var y2 = event.offsetY;
    var y3 = y1-y2-280;
   
 var messageArea = document.getElementById("ssnMessage");
  messageArea.style.left = x3;
  messageArea.style.top = y3;
 
    if(obj.value==''){
     var newMsg;
     var msgLength = msg.length;
     var lastChar = msg.substr(msg.length-1,1);
    
     if(lastChar=='은'){
      newMsg = msg.replaceAll( "은", "을" );
     }else{
     newMsg = msg.replaceAll( "는", "를" );
    }
    messageArea.style.display = "block";
     messageArea.innerHTML = newMsg+" 입력하세요 !"; 
   
     return;
 }else if(obj.value.length<charLength){
  messageArea.style.display = "block";
     messageArea.innerHTML = msg+" "+charLength+"자 이상입니다 !"; 
     return;
 }else{
  messageArea.style.display = "none";
  messageArea.innerHTML = "";
 }
}

3. BODY 단 (실제 사용)

 <th>* 아이디(ID)</th>
                <td class="con""> ※ 3~15자의 영문소문자, 숫자만 가능 합니다.<br>
                 <html:text property="memberInfo.userId" style="width:170px;ime-mode:disabled" styleClass="type-text-c" onblur="ajaxValidID(this);checkLength(this,3,'아이디는');" maxlength="15" tabindex="1"/>

+ Recent posts