[  함수(Function) ]

  -종류)

    1. 선언적 함수 : 함수에 이름이 있는 함수로 호이스팅의 대상이 된다.(호이스팅은 별도로 정리)

      function circle(radius){

        ~~

        return something;

      }

    2. 익명 함수 : 함수에 이름이 없어 주로 변수에 대입해서 사용하는 함수(호이스팅의 대상이 되지 않음)

                    -> 따라서 순차적으로 수행되기 때문에 요즘은 익명함수로 선언하는 것이 추천됨.

      var anonymousFunc = function(raidus){

        ~~

        return something;

      }

    3. 람다 함수 : 일회성으로 사용하기 위한 목적으로 사용되는 함수

      (function(radius){

        ~~

        return something;

      })(25)


  - 매개변수가 정해지지 않은 함수 처리 방식)

    -> 자바스크립트는 arguments 라는 배열을 제공함

    -> arguments[0], arguments[1], ... 하면 각 순서대로 넘긴 매개변수 값을 가져올 수 있다.

    -> arguments.length : 실재 넘긴 매개변수 개수

    -> arguments.callee 는 함수 정의부를 의미한다.

    -> 따라서, arguments.callee.length 하면 선언된 매개변수 개수

    testFunc(10,20,30,40); // 선언적 함수는 호이스팅되기 때문에 수행 가능.

    function testFunc(a, b){

      if(arguments.callee.length != arguments.callee){

        alert("선언된 함수의 매개변수 개수와 실재 호출시 넘긴 매개변수 개수가 다릅니다.");

        alert("선언 매개변수 개수 : " + arguments.callee.length);

        alert("실재 호출시 넘긴 매개변수 개수 : " + arguments.length);

        // arguments[0] // 10

        // arguments[1] // 20

        // arguments[2] // 30

      }

    }


  - 인코딩/디코딩 내장함수)

    -> 한글 등을 넘길때 값에 문제가 생길 수 있어 인코딩에 사용되는 내장함수이다.

    escape(str) <-> unescape(str)

    encodeURIComponent(str) <-> decodeURIComponent(str)


  - 숫자 판별 내장함수)

    isNaN() : 숫자면 true 아니면 false를 return함.

  - 정수 변환 내장함수)

    parseInt()

  - 실수 변환 내장함수)

    parseFloat()

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


[  객체(Object)  ]

객체 선언 방식 종류)

  1. new Object()를 통한 방식 -> 거의 사용 안함...

  2. 객체 리터럴 방식

    var circle = {

      변수 : "값",

      메서드1 : function(){

        ~~

        return something;

      },

      메서드2 : function(){}

      ...

    }


    -new 를 통해 객체를 여러개 생성할 수 없음으로 3번 생성자를 이용한 방식이 제일 자주 사용된다.

    -객체 선언 이후에 객체에 메서드, 변수를 추가하는 방법)

      circle.새변수명 = 값;

      circle.새메서드명 = function(){

         ~~

      }

      ->*** 이런 방식 말고도 변수나 문자열을 통해서도 동적으로 변수, 메서드를 추가할 수 있다.

      circle["새변수명"] = 값;

      circle["새메서드명"] = function(){};

      var newFunction = "print";

      circle[newFunction] = function(){} 처럼 동적으로 생성할 수 있다.

  3. 생성자 함수를 이용한 방식

    1) 선언적 함수를 이용하는 방식

      function constructorObject(a, b){

        this.변수명 = 값;

        this.메서드명 = function(){}

        ...

      }

    2) 익명함수를 이용하는 방식

      var constructorObject = function(a,b){

        this.변수명 = 값;

        this.메서드명 = function(){}

      }


    new constructorObject(10,20);

    처럼 new 연산자를 통해 인스턴스를 생성해서 사용하며, 이때 this는 자기 자신의 객체를 의미하게 된다.

    -> 자바스크립트에서 각 사용처 별로 this가 굉장히 다른데 추후에 정리...

    -> 일단, 생성자 함수를 통해 생성된 객체에서의 this는 자기 자신의 객체를 의미

    -> 함수 내에서 this는 window 객체를 의미


    역시 익명함수에서도 new를 통해 생성한 객체에 추가로 변수, 메서드를 추가하고 싶은 경우

    var newObject = new constructorObject(10,20);

    newObject.newVal = "새로운 값 추가";

    newObject["newMethod"] = function(){} 처럼 추가할 수 있다.


    *** [ 객체에서의 prototype ]

    -> prototype 사용 이유)

        생성자 함수를 통해 선언된 것을 new 키워드를 통해 객체 생성시 모든 인스턴스들은

        생성자 함수 내에 선언된 메서드 공간을 중복적으로 할당받게 된다.

        하지만 이러한 중복된 메서드를 공간을 객체마다 각기 할당받는 것은 비효율 적임으로

        공유될 수 있는 prototype을 통해 한군대에서만 정의될 수 있도록 해주는 방식을 사용한다.

    클래스명.prototype.변수명 = "값"; // 이 값은 해당 클래스명으로 생성되는 모든 객체에서 공유된다.

    클래스명.prototype.메서드명 = function(){}

    // 한번에 여러개를 뭉뚱그려 정의하고 싶다면...

    클래스명.prototype = {

      // 해당 클래스의 prototype을 통째로 재정의할 수도 있다.

      변수명 : "값",

      메서드1 : function(){},

      메서드2 : function(){},

      ...

    }


  - Date 내장 객체 자주사용되는 메서드)

    var date = new Date();

    date.getFullYear();

    date.getMonth() + 1; // 시작값이 0부터여서 1을 더해야함

    date.getDate(); // 일

    date.getHours();

    date.getMinutes();

    date.getSeconds();


- 콜백(Callback) 함수란? )

: 별거없다... 함수 호출시 매개변수에 함수를 넘겨서 해당 함수 내에서 특정 시점에 넘긴 함수를 수행하기 위한 목적으로 사용된다.

-> ajax등에서 success시 로딩 이미지를 없앤다거나 success가 완료된 시점에 특정 작업 등을 하려할 때 많이 사용된다.

function print(sum){

document.write(sum);

}

function testMethod(callbackF, a, b){

var sum = 0;

sum = a + b;

callbackF(sum); // 전달받은 callbackF(print메서드)를 수행한다.

}

testMethod(print, 10, 20);

[ 자바스크립트로 사용자 OS 버전 확인하는 코드(IE버전 X 운영체제 판별)]


자바스크립트로 IE8 과 같은 브라우저 버전 체크하는 코드는 많은데 막상 사용자의 운영체제가 무슨 버전인지까진 판별하는 코드가 잘 없었는데


다른분 티스토리에서 보고 유용한거같아 공유하려합니다.


조금더 덧대서 해당 윈도우 운영체제에 로그인한 사용자명의 폴더를 알아야할 경우


var net = new ActiveXObject ( "WScript.NetWork" );

var userName = net.UserName;

strFilePath = "C:\\Users\\" + userName + "\\AppData\\Local\\" + nanumTechnologiesPath; 코드를 사용하시면 로그인한 userName도 얻어올 수 있습니다.


이 아래는 자바스크립트로 운영체제 종류와 버전을 판별하는 코드입니다.


// JavaScript Document

// 만든이 : 다섯방울, THREE™ (http://the3.tistory.com)

// 주소 : http://the3.tistory.com/17

// Data : 2015. 01. 28

// Version : 0.2

// 참조 http://www.openspc2.org/userAgent/

// OS 버전 보기


var uanaVigatorOs = navigator.userAgent;

var AgentUserOs= uanaVigatorOs.replace(/ /g,'');

var Ostxt="";

var OSName="";

var OsVers="";


// This script sets OSName variable as follows:

// "Windows"    for all versions of Windows

// "MacOS"      for all versions of Macintosh OS

// "Linux"      for all versions of Linux

// "UNIX"       for all other UNIX flavors 

// "Unknown OS" indicates failure to detect the OS


new function() {

    var OsNo = navigator.userAgent.toLowerCase(); 


    jQuery.os = {

        Linux: /linux/.test(OsNo),

        Unix: /x11/.test(OsNo),

        Mac: /mac/.test(OsNo),

        Windows: /win/.test(OsNo)

    }

}


function OSInfoDev(){

if($.os.Windows) {

if(AgentUserOs.indexOf("WindowsCE") != -1) OSName="Windows CE";

else if(AgentUserOs.indexOf("Windows95") != -1) OSName="Windows 95";

else if(AgentUserOs.indexOf("Windows98") != -1) {

if (AgentUserOs.indexOf("Win9x4.90") != -1) OSName="Windows Millennium Edition (Windows Me)" 

else OSName="Windows 98"; 

}

else if(AgentUserOs.indexOf("WindowsNT4.0") != -1) OSName="Microsoft Windows NT 4.0";

else if(AgentUserOs.indexOf("WindowsNT5.0") != -1) OSName="Windows 2000";

else if(AgentUserOs.indexOf("WindowsNT5.01") != -1) OSName="Windows 2000, Service Pack 1 (SP1)";

else if(AgentUserOs.indexOf("WindowsNT5.1") != -1) OSName="Windows XP";

else if(AgentUserOs.indexOf("WindowsNT5.2") != -1) OSName="Windows 2003";

else if(AgentUserOs.indexOf("WindowsNT6.0") != -1) OSName="Windows Vista/Server 2008";

else if(AgentUserOs.indexOf("WindowsNT6.1") != -1) OSName="Windows 7";

else if(AgentUserOs.indexOf("WindowsNT6.2") != -1) OSName="Windows 8";

else if(AgentUserOs.indexOf("WindowsNT6.3") != -1) OSName="Windows 8.1";

else if(AgentUserOs.indexOf("WindowsNT6.4") != -1) OSName="Windows 10";

else if(AgentUserOs.indexOf("WindowsPhone8.0") != -1) OSName="Windows Phone 8.0";

else if(AgentUserOs.indexOf("WindowsPhoneOS7.5") != -1) OSName="Windows Phone OS 7.5";

else if(AgentUserOs.indexOf("Xbox") != -1) OSName="Xbox 360";

else if(AgentUserOs.indexOf("XboxOne") != -1) OSName="Xbox One";

else if(AgentUserOs.indexOf("Win16") != -1) OSName="Windows 3.x";

else if(AgentUserOs.indexOf("ARM") != -1) OSName="Windows RT";

else OSName="Windows (Unknown)";

if(AgentUserOs.indexOf("WOW64") != -1) OsVers=", WOW64";

else if(AgentUserOs.indexOf("Win64;x64;") != -1) OsVers=", Win64 on x64";

else if(AgentUserOs.indexOf("Win16") != -1) OsVers=" 16-bit";

else OsVers=" on x86";

} else if ($.os.Linux) {

if(AgentUserOs.indexOf("Android") != -1) { OSName = getAndroidDevName(); }

else if(AgentUserOs.indexOf("BlackBerry9000") != -1) OSName="BlackBerry9000";

else if(AgentUserOs.indexOf("BlackBerry9300") != -1) OSName="BlackBerry9300";

else if(AgentUserOs.indexOf("BlackBerry9700") != -1) OSName="BlackBerry9700";

else if(AgentUserOs.indexOf("BlackBerry9780") != -1) OSName="BlackBerry9780";

else if(AgentUserOs.indexOf("BlackBerry9900") != -1) OSName="BlackBerry9900";

else if(AgentUserOs.indexOf("BlackBerry;Opera Mini") != -1) OSName="Opera/9.80";

else if(AgentUserOs.indexOf("Symbian/3") != -1) OSName="Symbian OS3";

else if(AgentUserOs.indexOf("SymbianOS/6") != -1) OSName="Symbian OS6";

else if(AgentUserOs.indexOf("SymbianOS/9") != -1) OSName="Symbian OS9";

else if(AgentUserOs.indexOf("Ubuntu") != -1) OSName="Ubuntu";

else if(AgentUserOs.indexOf("PDA") != -1) OSName="PDA";

else if(AgentUserOs.indexOf("NintendoWii") != -1) OSName="Nintendo Wii";

else if(AgentUserOs.indexOf("PSP") != -1) OSName="PlayStation Portable";

else if(AgentUserOs.indexOf("PS2;") != -1) OSName="PlayStation 2";

else if(AgentUserOs.indexOf("PLAYSTATION3") != -1) OSName="PlayStation 3";

else OSName="Linux (Unknown)";

if(AgentUserOs.indexOf("x86_64") != -1) OsVers=", x86_64";

else if(AgentUserOs.indexOf("i686") != -1) OsVers=", i686";

else if(AgentUserOs.indexOf("i686 on x86_64") != -1) OsVers=", i686 running on x86_64";

else if(AgentUserOs.indexOf("armv7l") != -1) OsVers=" Nokia N900 Linux mobile, on the Fennec browser";

else if(AgentUserOs.indexOf("IA-32") != -1) OsVers=" 32-bit";

else OsVers="";

} else if ($.os.Unix) {

OSName="UNIX";

} else if ($.os.Mac) {

if(AgentUserOs.indexOf("iPhoneOS3") != -1) OSName="iPhone OS 3";

else if(AgentUserOs.indexOf("iPhoneOS4") != -1) OSName="iPhone OS 4";

else if(AgentUserOs.indexOf("iPhoneOS5") != -1) OSName="iPhone OS 5";

else if(AgentUserOs.indexOf("iPhoneOS6") != -1) OSName="iPhone OS 6";

else if(AgentUserOs.indexOf("iPhoneOS7") != -1) OSName="iPhone OS 7";

else if(AgentUserOs.indexOf("iPhoneOS8") != -1) OSName="iPhone OS 8";

else if(AgentUserOs.indexOf("iPad") != -1) OSName="iPad";

else if((AgentUserOs.indexOf("MacOSX10_1")||AgentUserOs.indexOf("MacOSX10.1")) != -1) OSName="Mac OS X Puma";

else if((AgentUserOs.indexOf("MacOSX10_2")||AgentUserOs.indexOf("MacOSX10.2")) != -1) OSName="Mac OS X Jaguar";

else if((AgentUserOs.indexOf("MacOSX10_3")||AgentUserOs.indexOf("MacOSX10.3")) != -1) OSName="Mac OS X Panther";

else if((AgentUserOs.indexOf("MacOSX10_4")||AgentUserOs.indexOf("MacOSX10.4")) != -1) OSName="Mac OS X Tiger";

else if((AgentUserOs.indexOf("MacOSX10_5")||AgentUserOs.indexOf("MacOSX10.5")) != -1) OSName="Mac OS X Leopard";

else if((AgentUserOs.indexOf("MacOSX10_6")||AgentUserOs.indexOf("MacOSX10.6")) != -1) OSName="Mac OS X Snow Leopard";

else if((AgentUserOs.indexOf("MacOSX10_7")||AgentUserOs.indexOf("MacOSX10.7")) != -1) OSName="Mac OS X Lion";

else if((AgentUserOs.indexOf("MacOSX10_8")||AgentUserOs.indexOf("MacOSX10.8")) != -1) OSName="Mac OS X Mountain Lion";

else if((AgentUserOs.indexOf("MacOSX10_9")||AgentUserOs.indexOf("MacOSX10.9")) != -1) OSName="Mac OS X Mavericks";

else if((AgentUserOs.indexOf("MacOSX10_10")||AgentUserOs.indexOf("MacOSX10.10")) != -1) OSName="Mac OS X Yosemite";

else OSName="MacOS (Unknown)";

if(AgentUserOs.indexOf("Intel") != -1) OsVers=" on Intel x86 or x86_64";

else if(AgentUserOs.indexOf("PPC") != -1) OsVers=" on PowerPC";

else OsVers="";

} else {

OSName="Unknown OS";

}

  var OSDev = OSName + OsVers;

  return OSDev;

}


// Android의 단말 이름을 반환

function getAndroidDevName() {

var uaAdata = navigator.userAgent;

var regex = /Android (.*);.*;\s*(.*)\sBuild/;

var match = regex.exec(uaAdata);

if(match) {

var ver = match[1];

var dev_name = match[2];

return "Android " + ver + " " + dev_name;

}

return "Android OS";

}


// OSInfoDev() 는 OS이름과 버전 출력하는 함수

// AgentUserOs 는 userAgent 출력

[Text Node 제어와 Document 및 스크린, 스크롤 위치 제어]



1. [ Text Node의 제어 ]

- 텍스트 데이터 확인 : ELEMENT.data or ELEMENT.nodeValue
- 텍스트 데이터 조작
-- element.appendData("추가할 텍스트 문자열") : 맨 마지막 부분에 문자열 추가
-- element.deleteData( startIndex, length ) : 해당 index부터 몇글자 지울지
-- element.insertData( startIndex, "추가할 문자열" ) : 해당 index 위치에 삽입
-- element.replaceData( startIndex, length, "바꿀 문자열" ) : 해당 index부터 length글자만큼을 새로운 바꿀 문자열로 교체
-- element.substringData( startIndex, length ) : 해당 인덱스부터 length개만큼 가져옴

1
2
3
4
5
6
7
8
9
10
<ul>
<li id="target">html</li>
<li>css</li>
<li>JavaScript</li>
</ul>
<script>
var t = document.getElementById('target').firstChild;
console.log(t.nodeValue);
console.log(t.data);
</script>

<!DOCTYPE html>
<html>
<head>
<style>
#target{
font-size:77px;
font-family: georgia;
border-bottom:1px solid black;
padding-bottom:10px;
}
p{
margin:5px;
}
</style>
</head>
<body>
<p id="target">Cording everybody!</p>
<p> data : <input type="text" id="datasource" value="JavaScript" /></p>
<p> start :<input type="text" id="start" value="5" /></p>
<p> end : <input type="text" id="end" value="5" /></p>
<p><input type="button" value="appendData(data)" onclick="callAppendData()" />
<input type="button" value="deleteData(start,end)" onclick="callDeleteData()" />
<input type="button" value="insertData(start,data)" onclick="callInsertData()" />
<input type="button" value="replaceData(start,end,data)" onclick="callReplaceData()" />
<input type="button" value="substringData(start,end)" onclick="callSubstringData()" /></p>
<script>
var target = document.getElementById('target').firstChild;
var data = document.getElementById('datasource');
var start = document.getElementById('start');
var end = document.getElementById('end');
function callAppendData(){
target.appendData(data.value);
}
function callDeleteData(){
target.deleteData(start.value, end.value);
}
function callInsertData(){
target.insertData(start.value, data.value);
}
function callReplaceData(){
target.replaceData(start.value, end.value, data.value);
}
function callSubstringData(){
alert(target.substringData(start.value, end.value));
}
</script>
</body>
</html>





2. [ Document(문서)의 Element 위치 알아내기 ]

var positionInfo = Element.getBoundingClientRect();
-> getBoundingClientRect()는 width, height, top, left, right, bottom 프러퍼티를 갖는 객체이다.
- width : element의 가로 길이
- height : 세로길이
- top : viewport(아래에서 설명) 맨 위에서부터 element까지 y축 길이
- left : viewport 맨 좌측에서부터 element까지 x축 길이
- right : viewport 맨 좌측에서 element 맨 오른쪽까지 길이
- bottom : viewport 맨 위에서 element 맨 아래까지 길이

1) -> 하지만, getBoundingClientRect()는 구버전 브라우저에서는 제공하지 않는 경우도 있다. 따라서,
element의 좌표를 구할 때 element.offsetLeft, element.offsetTop을 사용하면 된다. == element.getBoundingClientRect().left|top

- 테두리를 제외한 width와 height 값 구하기
- element.clientWidth
- element.clientHeight


2) -> 때떄로, 어떤 Element들은 해당 Element를 감싸고 있는 부모 Element가 position static인 경우 부모로 부터의 위치를 기준으로
자신의 offsetLeft, offsetTop값을 반환하게 된다.
따라서, 문서에서의 정확한 위치를 구하기 위해서는 다음과 같은 코드를 사용할 수 있다.
( 해당 Element를 포함하고 있는 부모 Element를 추적하면서 위치값을 더해감)




3. [ viewport란? 스크롤을 고려한 문서내의 Element의 위치 ]

- 1) Viewport(뷰포트)

: 문서 전체의 크기가 있을 때 예를들어 우리가 브라우저를 줄이게 될 경우 전체 Document가 다 보이지 않고
  창 크기에 맞춰 일부분의 문서만 보일 것이다.
  이때, 보이는 영역이 ViewPort이다.

--> 우리가 아까 위에서 element.offsetLeft, element.offsetTop 등이 viewport에서부터의 거리를 나타내고 있는 것이다.

따라서, 스크롤이 개입되게 되면, 해당 위치는 문서 전체를 기준으로했을 때 정확하지 않게 될 수 있다.

   2) 스크롤의 위치는 어떻게 구할까?

-> window.pageYoffset
: y축 스크롤을 움직인 거리(문서가 가려진 y축 길이)
-> window.pageXoffset
: x축 스크롤을 움직인 거리(문서가 가려진 x축 길이)

    3) viewport에서부터의 거리와 스크롤과의 관계

-> 스크롤을 내릴 수록 pageYoffset값은 커질 것이다. 그러면 offsetTop값을 기준으로 보면 어떻게 될까?

    스크롤이 내려간만큼 그 길이는 짧아지게 된다.

예를들어, A라는 Element의 offsetTop값이 맨 처음 200이고 pageYoffset이 0이었을 때
스크롤을 40px만큼 내려 pageYoffset이 40이 되면

offsetTop값은 200 - 40 인 160이 되게 된다.

전체문서에서 보이는 viewport를 기준으로 하기 때문이다.

따라서, 전체 문서에서의 위치를 구하려면 어떻게 해야할까?

--> element.offsetTop(뷰포트좌표) + window.pageYoffset(스크롤된 정도)


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
<style>
body{
padding:0;
margin:0;
}
div{
border:50px solid #1065e6;
padding:50px;
margin:50px;
}
#target{
width:100px;
height:2000px;
}
</style>
<div>
<div id="target">
Coding
</div>
</div>
<script>
var t = document.getElementById('target');
setInterval(function(){
console.log('getBoundingClientRect : ', t.getBoundingClientRect().top, 'pageYOffset:', window.pageYOffset);
}, 1000)
</script>




4. [ 스크롤 제어 ]

: 스크롤을 특정 위치로 이동시키는 방법

-> window.scrollTop(x, y); // x축, y축

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
<style>
body{
padding:0;
margin:0;
}
div{
border:50px solid #1065e6;
padding:50px;
margin:50px;
}
#target{
width:100px;
height:2000px;
}
</style>
<input type="button" id="scrollBtn" value="scroll(0, 1000)" />
<script>
document.getElementById('scrollBtn').addEventListener('click', function(){
window.scrollTo(0, 1000);
})
</script>
<div>
<div id="target">
Coding
</div>
</div>



5. [ Viewport의 크기와 사용자 모니터 크기 구하기 ]

- Viewport 크기

: window.innerWidth
  window.innerHeight

- 사용자 모니터 크기

: screen.width
: screen.height

[   Node 객체에 대하여(NODE 객체와 NODE객체 컨트롤하기)   ]



-> 자바스크립트의 모든 DOM ELEMENT들은 최상위로 NODE를 상속하고 있기 때문에 NODE가 가지고 있는 속성을 사용할 수 있다.


Node 객체는 Node 간의 관계 정보를 담고 있는 일련의 API를 가지고 있다. 다음은 관계와 관련된 프로퍼티들이다.


[ 1. Node의 자식 및 형제 Node에 접근하는 프러퍼티 ]

  • Node.childNodes
        자식노드들을 유사배열에 담아서 리턴한다.
  • Node.firstChild
        첫번째 자식노드
  • Node.lastChild
        마지막 자식노드
  • Node.nextSibling
        다음 형제 노드
  • Node.previousSibling
        이전 형제 노드

-> 이렇게 노드에 접근할 때 중요한 점은 줄바꿈 텍스트 또한 NODE를 상속하기 때문에 자식으로 가져올 때 주의해야 한다는 점이다. 아래의 크롬브라우저의 테스트 창을 보면서
    이해하기 바란다

   EX) Crome Browser 개발자도구(F12) console창에서 테스트하는 예
<body id="start">
<ul>
<li><a href="./532">html</a></li>
<li><a href="./533">css</a></li>
<li><a href="./534">JavaScript</a>
<ul>
<li><a href="./535">JavaScript Core</a></li>
<li><a href="./536">DOM</a></li>
<li><a href="./537">BOM</a></li>
</ul>
</li>
</ul>
</body>





[    2. Node의 타입을 알 수 있는 nodeType속성과 Node 이름을 알 수 이는 nodeName 속성    ]


노드 작업을 하게 되면 현재 선택된 노드가 어떤 타입인지를 판단해야 하는 경우가 있다. 이런 경우에 사용할 수 있는 API가 nodeType, nodeName이다. 


  • Node.nodeType
        node의 타입을 의미한다.  -> 타입값은 숫자로 나오게 된다. 주로 1(element), 3(TextNode), 9(document node) 를 주로 사용하게 된다.
  • Node.nodeName
        node의 이름 (태그명을 의미한다.)


  [ nodeType의 종류 ]


EX)


-> nodeType의 경우 1,2,3 숫자를 기억하기 어려울 수 있음으로 상수로 이를 대체하여 사용할 수도 있다.

EX)



[    노드 추가관련 프러퍼티    ]

노드의 추가와 관련된 API들은 아래와 같다.

노드를 추가하기 위해서는 추가할 엘리먼트를 생성해야 하는데 이것은 document 객체의 기능이다. 아래 API는 노드를 생성하는 API이다.



[    노드 제거    ]

노드 제거를 위해서는 아래 API를 사용한다. 이 때 메소드는 삭제 대상의 부모 노드 객체의 것을 실행해야 한다는 점에 유의하자.






[    노드 바꾸기    ]

노드 바꾸기에는 아래 API가 사용된다.



<ul>
<li>HTML</li>
<li>CSS</li>
<li id="target">JavaScript</li>
</ul>
<input type="button" onclick="callReplaceChild();" value="replaceChild()" />
<script>
function callReplaceChild(){
var a = document.createElement('a');
a.setAttribute('href', 'http://opentutorials.org/module/904/6701');
a.appendChild(document.createTextNode('Web browser JavaScript'));
var target = document.getElementById('target');
target.replaceChild(a,target.firstChild); // 새로 만든 a태그를 target의 첫번째 자식 엘리먼트와 교체한다.(즉 텍스트 JavaScript를 대체)
}
</script>



문자열로 노드 제어



위의 예들은 Node 객체를 생성한 뒤 제어했지만, 문자열로 붙이고 지우고 등을 할 수 있다. 아래는 그와 관련된 프러퍼티와 메서드이다.

1. innerHTML

innerHTML는 문자열로 자식 노드를 만들 수 있는 기능을 제공한다. 또한 자식 노드의 값을 읽어올 수도 있다. 


2. outerHTML

outerHTML은 선택한 엘리먼트를 포함해서 문자열로 가지고 오거나, 자신을 포함해서 문자열로 노드를 대체할 수 있다.


3. insertAdjacentHTML()

좀 더 정교하게 문자열을 이용해서 노드를 변경하고 싶을 때 사용한다.


EX) innerHTML

<ul id="target">
<li>HTML</li>
<li>CSS</li>
</ul>
<input type="button" onclick="get();" value="get" />
<input type="button" onclick="set();" value="set" />
<script>
function get(){
var target = document.getElementById('target');
alert(target.innerHTML); // target 내부의 HTML과 CSS li를 가지고 오게 된다.(문자열로)
}
function set(){
var target = document.getElementById('target');
target.innerHTML = "<li>JavaScript Core</li><li>BOM</li><li>DOM</li>";
}
</script>


EX) outerHTML

<ul id="target">
<li>HTML</li>
<li>CSS</li>
</ul>
<input type="button" onclick="get();" value="get" />
<input type="button" onclick="set();" value="set" />
<script>
function get(){
var target = document.getElementById('target');
alert(target.outerHTML); // target 전체를 가지고 오게 된다.(문자열로)
}
function set(){
var target = document.getElementById('target');
target.outerHTML = "<ol><li>JavaScript Core</li><li>BOM</li><li>DOM</li></ol>";
// ul태그 전체가 통째로 ol로 대체되게 된다.
}
</script>


EX) insertAdjacentHTML(arg1, arg2)

<ul id="target">
<li>CSS</li>
</ul>
<input type="button" onclick="beforebegin();" value="beforebegin" />
<input type="button" onclick="afterbegin();" value="afterbegin" />
<input type="button" onclick="beforeend();" value="beforeend" />
<input type="button" onclick="afterend();" value="afterend" />
<script>
function beforebegin(){
var target = document.getElementById('target');
target.insertAdjacentHTML('beforebegin','<h1>Client Side</h1>'); // 맨 첫번째 자식 앞에 삽입
}
function afterbegin(){
var target = document.getElementById('target');
target.insertAdjacentHTML('afterbegin','<li>HTML</li>'); // 첫번째 자식 뒤에 삽입
}
function beforeend(){
var target = document.getElementById('target');
target.insertAdjacentHTML('beforeend','<li>JavaScript</li>'); // 끝 자식 전에 삽입
}
function afterend(){
var target = document.getElementById('target');
target.insertAdjacentHTML('afterend','<h1>Server Side</h1>'); // 끝 자식 뒤에 삽입
}
</script>


[    이벤트(EVENT)    ]



[ 이벤트(EVENT)의 전파 및 전파를 막는 방법 ]



[ 태그의 기본 이벤트를 막는 방법 ]



[ FORM 태그의 대표 이벤트 종류 ]



[ 문서의 태그의 로딩과 관련된 load와 unload 이벤트 ]


[ 그 외 알아두면 좋은 이벤트 ]

- contextmenu event : 마우스 우클릭시 발생

-> 마우스 우클릭 방지 이벤트(요소 검사(F12)를 방지하기 위해 사용 가능)

- shift, ctrl 키와 같이 클릭했는지 유무를 알 수 있는 event 프러퍼티

event.shiftKey, event.ctrlKey

- 클릭한 곳의 마우스 좌표를 알 수 있는 event.clientX, event.clientY


[    5판 7장 객체(Object)와 배열(Array)    ]




[    eclipse(이클립스) 자바스크립트(javascript) 자동완성 플러그인 설정하기    ]



이클립스에서 자바스크립트 사용시 ctrl + space 를 눌러 자동완성이 가능하도록 세팅하는 방법에 대한 포스팅입니다.


두가지 작업을 해주어야 합니다.


1. Help 탭->Eclipse Market place->Webclipse 검색 후 설치(install) 후 restart합니다.



2. 두번째로 window탭->preferences->Ant->editor->Content Assist에서 enable auto activation을 체크합니다.





추가하고 나면 아래와 같이 자동완성이 가능한 것을 볼 수 있습니다.



<!DOCTYPE html>

<html>

  <head>

    <meta charset="utf-8">

    <title></title>

  </head>

  <body>

    <ul>

      <li>HTML</li>

      <li>CSS</li>

      <li id="active">JavaScript</li>

    </ul>

    <script type="text/javascript">

      // 복수개의 li가 선택됨

      var liObjs = document.getElementByTagName('li');

      for(var i=0; i<liObjs.length; i++){

        console.log(liObjs[i].innerHTML());

      }

      // 부모 요소로 접근하기

      // jquery에서는 parent()

      var ulObj = liObjs[1].parentNode;

      // 부모요소에서 2번째 자식 요소 제거하기

      ulObj.removeChild(liObjs[1]);

      // 자식 요소 중 첫번째 요소 콘솔 찍기

      console.log(ulObj.childNodes[0]);

    </script>

  </body>

</html>



[ 자바스크립트로 제어하고 싶은 대상 선택하기(찾기) ]






<!DOCTYPE html>

<html>

<head>

<title></title>

</head>

<body>

1. Javascript Inline 방식 : 

<input onclick="alert('hello world')" type="button" name="inline"><br/>


2. <h2 id="hw">script 태그 내에 삽입하는 방식 :</h2>


<script type="text/javascript">

var hw = document.getElementById("hw");

hw.addEventListener("click",function(){

alert("hello world");

})

</script>

<br/>


3. 외부 파일로 분리하는 방식 :

<script type="text/javascript" src="./script2.js"></script>

<br/>


4. 스크립트의 위치 :


스크립트는 어느 위치에나 올 수 있지만 body 태그의 마지막 부분에 위치시키는 것이 좋다.

why??

=> 제어할려는 태그가 다 로딩된 다음에 작업이 수행되어야 하니까(로딩되지 않은 상태에서 작업시 제어 불가)


=> 위치에 상관없이 태그가 다 로딩된 후 수행토록 하려면

: javascript의 경우

=> window.onload = function(){

이 내부 코드는 태그가 다 로딩된 이후 수행하게 된다.

      }


     jquery의 경우

      => document.ready(function(){


      })



</body>

</html>


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

script.js 파일

window.onload = function(){
// 웹브라우저의 모든 구성요소가 로딩된 이후에 수행되게 됨. window.onload = function(){}
var hw = document.getElementByid("hw");
hw.addEventListener("click",function(){
alert("외부 스크립트 파일");
});
}


[    동적으로 생성된 태그에 이벤트를 걸려면 어떻게 해야할까??    ]




가끔 ajax로 가져온 데이터를 문자열로 조합해서 태그에 append하는 경우 이런경우는 태그가 미리 생성되어 있는 경우가 아니라 동적으로


생성된 경우이다. 이런 경우에 문자열로 만든 태그에다가 id나 class준 다음에 $(선택자).on("click",function(event){}) 방식을 사용해서 이벤트를 걸어도


이벤트가 걸리지 않음을 알 수 있다.


이런 경우 어떻게 해야할까??


이런 경우는 document 객체에서 잡아와서 이벤트를 걸어야한다.


ex) $(document).on("click","선택자",function(event){})


[    클릭시 특정 태그 위치로 스크롤을 이동시키기    ]







[    이벤트 발생시 a 태그의 이동기능을 동작하지 않게하고 처리하기    ]




아주 가끔 a태그를 클릭시 a태그 href 에 지정된 속성으로 이동을 막고, 처리가 필요한 경우에 어떻게하는지에 대한 포스팅입니다.



[    JQuery 애니메이션 관련 정리(fadeIn,fadeOut,hide,show,animate,stop)    ]




[    script 선언의 위치와 수행 순서에 대해서...     ]



<script type="text/javascript">

...

</script>


이런식으로 스크립트를 작성하게 되는데 이때, 이 스크립트 블록을 어디다 수행하는게 좋을까요??


어디든 상관은 없습니다. 하지만 주의해야하는 사항이 몇가지 있죠


예를들어, head 태그 안에서 script를 선언하고 body 안에 선언해 놓은 태그에 대한 작업을 한다고 해봅시다.


그러면 어떻게 될까요? 


해당 script가 수행되는 시점에서 body 태그는 아직 파싱되기 전이기 때문에 script에서 해당 태그가 무엇인지 알 수가 없게 됩니다.


따라서 그냥 null을 가지고 작업을하게되죠...


따라서, body 태그가 다 로딩되고 body 태그 안에서 제일 밑 부분에 작성할 스크립트를 위치시켜주는 것이 best일 것입니다.


<!DOCTYPE html>

<html>

  <head>

    <meta charset="utf-8">

    <title></title>

  </head>

  <body>

    <input type="text" name="" value="" id="in">

    <table>

      <tr>

        <td>dd</td>

      </tr>

    </table>


    <script type="text/javascript">

      document.getElementById("in").value = "modifyValue";

    </script>

// 이처럼 아래쪽에 위치시켜주는 것이 좋습니다. 이걸 만약 head 태그 내에 위치하거나 input 태그 위에 위치시킨다면

// 스크립트가 제대로 수행될 수 없겠죠?

  </body>

</html>

[    3. 일정주기마다 callback 함수를 실행하는 setInterval()에 대해서...    ]



Callback Function

  • 조건을 등록해 두고 그 조건을 만족한 경우, 나중에 호출되는 함수

시간을 기반으로 콜백함수를 호출하는 명령

setTimeout( function, time )

  • time 시간이 지난 경우 function 함수를 콜백하는 함수
  • time 은 millisecond (1/1000초) 단위
  • timerId를 반환함

clearTimeout( timerId )

  • setTimeout 함수 호출의 결과로 반환된 timerId를 인자로 받아 예약되어 있던 function호출을 취소
    • 이미 function이 호출된 경우(시간이 지나 이벤트가 발생한 경우)에는 효과 없음

setInterval( function, time )

  • time 시간이 경과할 때마다 function 함수를 콜백하는 함수
  • timerId를 반환함

clearInterval( intervalId )

  • setInterval 함수 호출의 결과로 반환된 intervalId를 인자로 받아 주기적으로 호출되던 function 호출을 취소


다음 예시 사진을 보면, setTimeout을 호출 했을 때 3초뒤에 callback()으로 지정한 함수가 실행된 것을 알 수 있습니다.


이때, 142를 반환했는데 이것은 setTimeout의 id라고 생각하시면 되고 지정한 setTimeout을 해제하기 위해서는 clearTimeout(setTimeout의 id)를 넣어주어야 취소가 가능합니다.


다음으로


setInterval ( 수행할 메서드, 시간) 으로 여기선 5초 마다 콜백 메서드를 수행하도록 되어 있습니다. 이것을 해제하기 위해서는 역시 callback 메서드의 id가 143번 임으로


clearInterval(143)을 통해 해제 시켜 준 것을 알 수 있습니다.


콘솔에서는 id가 몇번인지 알 수 있지만 코드상에서 작성할 때에는 바로바로 확인이 어려움으로


var setIntervalId = setInterval(callback, 5000);

clearInterval(setIntervalId); 처럼 해서 사용하시면 됩니다.




[    Javascript의 브라우저 창 Window 객체(부모창 자식창 값 주고 받기 포함)    ]



window 객체


    • Javascript 실행시 가장 상위에 존재하는 객체

        • 변수를 선언하거나 함수 선언시 window 객체안에 선언됨
        • 크롬에서 F12를 눌러 console탭에서 window 객체를 입력해서 다양한 속성들을 조회해볼 수 있음.
    • 표시된 웹 페이지의 정보에 접근하거나 변경을 할 수 있음

        • window.location : 현재 브라우저 창의 주소를 나타내는 객체
        • window.location.href : 브라우저 창에 입력된 주소, 변경 가능
          • ex) window.location.href = "이동하고자하는 url "
          • ex) window.location.replace = "이동하고자하는 url" 위의 것과 차이점은 이동하고나서 뒤로가기 버튼이 활성화되지 않음.
        • window.open : 새창 띄우기
        • window.navigator : 브라우저 자체에 대한 정보
        • window.screen : 디스플레이의 사이즈
        • window.document : 웹 페이지 문서의 HTML, CSS 등에 대한 접근 가능









    • 2. [ window 객체를 이용해 새창을 띄우고 부모창과 자식창 사이에서 값을 주고 받는 방법 ]


    • var windowObj = window.open("새창에서띄울url","창이름","창의설정(옵션값)"); 처럼하면 현재창에서 새로운 창이 뜨게 됩니다. 이때 기존의 창이 부모창이 되고 새로 뜨게된 창이 자식창이되게되는데

      이때, 부모창과 자식창 사이에서 값을 주고 받기 위해서는 띄운 창의 window 객체를 저장할 변수를 선언해 저장해 놔야합니다.(windowObj)

      그런 다음 부모 창에서는 이 windowObj 변수를 이용해 자식창에 값을 전달할 수 있습니다. 예를들어, 

      windowObj.document.text2.value = "값 입력"; 이런식으로 자식창(새창)의 document 객체에 얼마든지 접근할 수 있습니다. 

      그러면, 반대로 자식창에서 부모창으로 값을 보내기 위해서는 어떤 식으로 해야할까요??

      일단, 부모창에서 자식창을 생성하면 이 자식창은 생성과 동시에 opener 라는 객체를 가지게 되고 이 opener는 바로 부모객체의 window 객체를 가리키게 됩니다. 따라서

      opener.document.parentText.value = document.text2.value; 이런식으로 자식에 있는 값을 부모 창으로 넘기는게 가능합니다.


      먼저, windowOpen1.html 즉, 부모창 예제 코드입니다.




다음으로 windowOpen2.html 즉, 자식창 예제 코드입니다.



위의 예제는 동일 폴더 내에서 테스트한걸로 크롬 보안상 작동하지 않을 수 있지만, 웹 서버에서 할 때는 잘 작동한다는 점 참고해주시기 바랍니다.



[    스프링과 안드로이드 연동5 : Javascript에서 Android 함수를 호출하기    ]



요즘은 웹을 개발하고 웹뷰를 이용해서 안드로이드에 붙이는 식으로 해서 반응형으로 하이브리드 앱을 만드는 경우가 많은데,


이러한 경우 웹뷰에서 버튼을 클릭한다거나 했을 때 자바스크립트에서 안드로이드에 있는 함수를 호출해서 


안드로이드를 제어하고 싶은 경우가 있다.


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


먼저, 웹뷰를 연결해 세팅부터 하자.


1. [    WebView(웹뷰) 세팅    ]


일단 스프링 웹 프로젝트에서 작성한 웹 페이지를 띄우는 웹뷰를 작성한다.

그 다음에 


2. 자바스크립트에서 호출시 수행할 안드로이드 메서드를 작성한다.


이때, 자바스크립트와 안드로이드를 중간에서 인터페이스 역할을 할 클래스를 작성해서 그 내부에

메서드를 정의하도록 한다.


당연히 인터넷 작업을 해야함으로

<!-- 인터넷 접속 권한 추가 -->
<uses-permission android:name="android.permission.INTERNET" />

를 manifest에 추가해주어야 하고

네트워크 작업은 백그라운드 쓰레드로 해야하며


백그라운드 쓰레드에서는 메인 뷰의 화면 제어를 할 수 없음으로

handler에게 대신해달라고 요청을 해야한다.


앞에선 계속 그렇게 해왔는데 이 2가지를 한번에 하는 것이


handler.post(new Runnable(){ run() }) 을 이용한 방식이다.


이런식으로해서 JavascriptInterface 클래스를 만들도록 한다.





3. 만들어준 JavascriptInterface 클래스를 웹뷰에 등록해 주어야 한다.



이때 중요한 점은 

webView1.addJavascriptInterface(new JavascriptInterface(),"myJSInterfaceName");

에서 두번째 매개변수란에 myJSInterfaceName 처럼 인터페이스 이름을 지정하게 되어 있는데

이 이름을 이용해서 자바스크립트에서 호출하게 된다.



4. 스프링 웹 프로젝트의 자바스크립트에서 특정 이벤트 발생시 안드로이드 함수를 호출하는 구문을 작성하자.


가장 중요한 부분은 window.myJSInterfaceName.callMethodName(str); 부분이다.

window.(지정한 javascript인터페이스명).수행할메서드명() 으로 호출하게 된다.

function callAndroid(){
    var str = document.getElementById("txtName").value;
    window.myJSInterfaceName.callMethodName(str);
}

<form id="formName" action="">
    <input id="txtName" type="text" />
    <button onclick="javascript:callAndroid()">호출하기</button>
 
</form>


여기까지 했다면, 


웹뷰 상에서 안드로이드 사용자가 "호출하기" 버튼을 클릭시에 callAndroid() 자바스크립트 메서드가 수행되고


해당 자바스크립트 메서드에서 window.myJSInterfaceName.callMethodName(str); 을 통해 안드로이드 메서드를 

호출하여, TextView에 있는 메시지를 웹뷰를 통해 입력한 값으로 세팅하게 된다.



안드로이드 쪽 전체 코드는 다음과 같다.



[    HandleBars 적용하기    ]

: HandleBars는 Javascript 라이브러리 중 하나로, 보통 AJAX로 가져온 데이터를 JQuery에서 문자열로 조합한다음에 append해주는

  불편함을 줄여주기 위해 주로 사용됩니다.

  특징)

1. 태그를 이용해서 구성을 잡아준다.(템플릿을 만든다.)
2. 템플릿 사이사이에 데이터가 들어갈 곳에 {{ 변수 }} 로 넣어놓는다.
3. 템플릿과 데이터를 연결시 {{}} 부분에 데이터가 들어가게 된다.

이때, {{#변수}} {{/변수}} 부분에는 배열과 같은 타입의 데이터의 길이가 들어와 그 길이만큼 반복작업을 수행하게 된다.

제일먼저 사용하기 위해, HandleBars js 라이브러리를 다운로드하고, 

<script src="" 를 이용해서 임포트 해주고 사용해야 한다. 이후 설명은 아래 소스코드에서 이어가겠습니다.



+ Recent posts