2016년 12월 10일 토요일

[Java] 자바 시작하기(개발 환경 구성)

자바(Java)프로그래밍을 시작하기위해 가장 선행되어야 할 것은, JRE(Java Runtime Environment, 자바 실행 환경) 설치, 즉 JVM(Java Virtual Machine, 자바 가상 머신)라 불리는 가상머신과 각종 Java API들을 포함하고 있는 JDK(Java Development Kit, 자바 개발 키트)의 설치이다. Java API는 각종 기능의 자바 클래스들이 포함된 자바 라이브러리이고 JVM은 컴파일된 자바 클래스파일들을 실행하는 가상 머신이다. 단순한 자바  프로그램 이용자라면 JVM만이 포함된 JRE를 설치하면 되겠지만 자바 개발자들은 이 2개가 모두 필요하기 때문에 Oracle에서는 JDK에 이 2가지를 포함하여 쉽게 설치할 수 있도록 하고 있다.

JDK를 다운받을려면 오라클 JDK 다운로드 페이지로 이동하자. 링크를 클릭하면 아래와 같은 페이지를 보게될것이다.

Oracle Java SE 다운로드 페이지

좌측 상단에는 각종 Java 제품들의 종류별로 카테고리가 나눠져 있고, 중앙 상단에는 JDK 설치와 NetBeans와 JDK를 함께 설치할 것인지 선택 옵션이 있다. 그리고 중앙 하단 우측에는 JDK, Server JRE, JRE 3개 선택 페이지가 있다. 참고로 형광펜으로 색칠된것을 보면 현재 Java SE는 8u112버젼이 최신 버젼인것을 알 수 있다. Java 8의 112번째 Update 라는 뜻이다.

참고로 JAVA SE는 Standard Edition, 데스크톱 어플리케이션과 간단한 서버 어플리케이션 개발 사용되며 EE는 Enterprise Edition, 복잡한 서버 어플리케이션 개발에, ME는 Micro Edition, 스마트폰과 기타 장치들에 사용된다. NetBeans는 Oracle에서 제공하는 IDE이다.

우리는 JDK가 필요하니 중앙 상단의 JDK설치만 설치를 클릭하자(왼쪽 옵션이다).
클릭 후 새 페이지로 이동하면 OS 별 JDK 리스트를 볼 수 있을텐데 본인 OS에 맞는 JDK를 설치하자. 나는 Ubuntu 16.04 64bit 버젼을 사용하므로 Linux x64(tar.gz)를 다운받았다. 윈도우 사용자들은 Window x32, x64를 윈도우 버젼에 맞게 설치하면 된다. 윈도우 사용자들은 설치파일을 단순히 실행하면 설치가 가능하고, linux 사용자들은 아래와 같이 설치하면 된다.


#파일 다운로드가 완료된 디렉토리로 이동 후 ~
#파일 압축해제
user@user-desktop:~/Downloads$ tar -xvf jdk-8u112-linux-x64.tar.gz
#파일 이름변경
user@user-desktop:~/Downloads$ mv jdk1.8.0_112 jdk1.8
#opt 폴더 내 java 디렉토리 생성
user@user-desktop:~/Downloads$ sudo mkdir /opt/java
#jdk1.8 폴더를 /opt/java 로 이동
user@user-desktop:~/Downloads$ sudo mv jdk1.8 /opt/java

이렇게 하면 다운받은 JDK가 /opt/java 폴더 내로 이동된다. 이후에 리눅스 사용자들은 jdk1.8/bin 디렉토리를 executable path에 추가해 주어야 한다. 윈도우 사용자들도 설치된 jdk를 환경변수에 등록해주어야 한다.


user@user-desktop:~$ sudo vi .profile
#.profile 파일을 열어 export PATH=/opt/java/jdk1.8/bin:$PATH 구문을 추가해주자

그리고 로그아웃 후 다시 로그인 하면 아래와 같이 자바가 설치되었음을 알 수 있을것이다.


user@user-desktop:~$ java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

2016년 9월 17일 토요일

[Linux] chown(소유권 변경) vs chmod(파일권한 변경) 명령어

Linux 기반 OS를 사용면서, 특히 Software Center에 없는 어플리케이션들을 설치할 때 자주 사용하게 되는 명령어가 있다. 주로 폴더, 또는 파일 이동 후 소유권과 파일권한을 변경할 때 사용하게 되는 명령어인 chownchmod이다.

우선 두 명령어의 차이부터 말하자면, chown은 "change owner", 즉 파일, 또는 폴더의 소유권을 변경하는 명령어이고, chmod는 "change mode", 파일이나 폴더의 권한(읽기, 쓰기, 실행)를 변경한다. "change mode"인 이유는 UNIX 시스템에서 이러한 권한들을 mode라 부르기 때문이다.

파일, 폴더(디렉토리)의 권한과 소유권 보기

간단하다. ls 명령어에 1개의 flag만 추가해주면 된다.

user@user_group:~/exp$ ls -l
drwxrwxr-x  2 user user_group 4096 Sep 17 06:39 dir1
drwxrwxr-x  2 user user_group 4096 Sep 17 06:39 dir2
-rw-rw-r--  1 user user_group    0 Sep 17 06:39 file1

l flag는 long listing format을 뜻하고, 사용시 디렉토리와 파일에 대한 자세한 정보를 보여준다.
보면 실제 표는 아니지만 표와같은 형식을 띄고 있는데,
첫번째 블락이 권한 문자열(Permission string),
두번째 블락이 해당 디렉토리 내부의 파일과 디렉토리 갯수,
세번째 블락이 소유주,
네번째가 소유주가 속한 그룹,
다섯번째가 크기,
6,7,8번째는 마지막으로 파일/디렉토리에 접근한 시각,
아홉번째가 파일/디렉토리의 이름을 의미한다.
dir1을 예로 들면 drwxrwxr-xdir1에대한 permission이다.
형식은 언제나 똑같다. 첫번째 글자는 해당 파일이나 디렉토리가 디렉토리(d), 일반파일(-), 특수파일(s)인지를 뜻한다.
보면 알겠지만 dir1, dir2d가 첫글자이니 디렉토리이고, file1-가 첫글자이니 일반파일이다.
그리고 그 뒤의 3글자, dir1의 경우에는 rwx인 3글자는, r->read, w->write, x->execute 해당 소유주의 읽기, 쓰기, 실행 권한을 의미하고, -로 표시된것은 그 권한이 없다는것을 뜻한다.
그 다음의 3글자는 소유주그룹의 권한, 마지막 3글자는 위의 2그룹에 포함되지 않는 다른 모든유저(All other users)의 권한을 가르쳐준다.
dir1을 보면, 디렉토리이고 user계정에서 읽고,쓰고,실행 할 수 있으며, user_group그룹에서도 읽고, 쓰고, 실행하며, 그 이외의 계정들에서는 읽고, 실행만 가능한것을 알 수 있다.

chown

파일이나 디렉토리의 소유주를 바꾸는 명령어이다.
"chown user:group /file/path" 형식으로 명령을 실행하면 된다. dir1의 소유주를 root 그룹의 root로 바꾸려면

user@user_group:~/exp$ sudo chown root:root dir1
user@user_group:~/exp$ ls -l
drwxrwxr-x 2 root root 4096 Sep 17 06:39 dir1
drwxrwxr-x 2 user user 4096 Sep 17 06:39 dir2
-rw-rw-r-- 1 user user    0 Sep 17 06:39 file1

chmod

파일이나 디렉토리의 권한을 바꾸는 명령어이다. 문자로 사용할수도 있고, 8진수형식(Octal Format)으로도 사용이 가능한다.

chmod 명령어 문자 옵션
문자권한
rRead(읽기)
wWrite(쓰기)
xExecute(실행, 디렉토리일경우 검색)
XExecute(디렉토리일경우에만 실행, 검색)
s소유주와 같은 권한으로 파일 실행 가능(setuid bit)
t쓰기권한에 관계 없이 소유주만 삭제 가능(sticky bit)
u현재 파일을 소유한 사용자(user)
g소유한 사용자의 그룹 멤버들
ou 와 g에 속하지 않는 모든 사용자들

권한을 추가하는데는 +, 제거하는데는 -를 사용한다 예를들면 다른 모든 사용자들에게 dir1의 쓰기(wirte)권한을 주고 실행(x)권한을 제거하기 위해서는 아래와 같은 명령을 사용하면 된다

#권한 변경전
user@user_group:~/exp$ ls -l
drwxrwxr-x 2 root root 4096 Sep 17 06:39 dir1
drwxrwxr-x 2 user user 4096 Sep 17 06:39 dir2
-rw-rw-r-- 1 user user    0 Sep 17 06:39 file1

#권한변경 명령
user@user_group:~/exp$ sudo chmod o+w-x dir1

#권한변경 후
user@user_group:~/exp$ ls -l
drwxrwxrw- 2 root root 4096 Sep 17 06:39 dir1
drwxrwxr-x 2 user user 4096 Sep 17 06:39 dir2
-rw-rw-r-- 1 user user    0 Sep 17 06:39 file1

dir1 디렉토리의 마지막 3문자, 현 사용자, 사용자 그룹을 제외한 다른 모든 사용자들의 권한을 의미하는 3자리가 변경된게 보인다.

chmod 8진수형식(Octal Format)
8진수 값읽기(Read)쓰기(Write)실행(Execute)
7OOO
6OO-
5O-O
4O--
3-OO
2-O-
1--O
0---

8진수 형식은 권한을 8진수로 표시하게 된다. 실행은 8진수 1, 쓰기는 2, 읽기는 4, 이 3 숫자의 합으로 3가지 권한의 모든 조합을 표시할 수 있다. 또 8진수형식 chmod를 사용할 때는 사용자를 따로 지목하지 않고, 3자리 8진수로 모든 권한을 표시한다.

예를들면 3자리 8진수의 각 숫자들은 위에서 말했던 권한문자열에서 사용자, 사용자그룹, 다른 모든 사용자들을 의미한다.

8진수 777은 사용자, 사용자그룹, 다른모든 사용자들이 rwx권한을 가지게 되므로, rwxrwxrwx 권한 문자열을 의미하게 된다.

#권한 변경전
user@user_group:~/exp$ ls -l
drwxrwxrw- 2 root root 4096 Sep 17 06:39 dir1
drwxrwxr-x 2 user user 4096 Sep 17 06:39 dir2
-rw-rw-r-- 1 user user    0 Sep 17 06:39 file1

#권한변경 명령
user@user_group:~/exp$ sudo chmod 777 dir1 
#777 = rwxrwxrwx
user@user_group:~/exp$ sudo chmod 750 dir2 
#750 = rwxr-x---
user@user_group:~/exp$ sudo chmod 700 file1
#700 = rwx------

#권한변경 후
user@user_group:~/exp$ ls -l
drwxrwxrwx 2 root root 4096 Sep 17 06:39 dir1
drwxr-x--- 2 user user 4096 Sep 17 06:39 dir2
-rwx------ 1 user user    0 Sep 17 06:39 file1

2015년 10월 9일 금요일

우분투(Ubuntu) 마우스 커서 이동 속도 조절하기

Ubuntu System Setting - Mouse & Touchpad 창

우분투만 쓸때는 몰랐는데 윈도우를 깔고 듀얼부트 상태로 쓰니 마우스 속도가 다른게 확 느껴진다. 윈도우에서는 적당히 빨랐는데 우분투에서는 너무 답답하다. System Setting 에서 바꾸려 했는데 마우스 이동속도 설정은 찾아볼수가 없다.

더블클릭 속도, 주-사용버튼 밖에 수정이 불가능하다. 그래서 찾아보니 command-line 에서 1가지 프로퍼티 수정만하면 쉽게 속도를 조정할수가 있었다.
우선 "xinput" 명령을 이용해 모든 input 장차의 리스트를 가져오자.

user@desktop:~$ xinput --list --short
⎡ Virtual core pointer                     id=2 [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer               id=4 [slave  pointer  (2)]
⎜   ↳ Logitech USB Receiver                    id=10 [slave  pointer  (2)]
⎣ Virtual core keyboard                    id=3 [master keyboard (2)]
    ↳ Virtual core XTEST keyboard              id=5 [slave  keyboard (3)]
    ↳ Power Button                             id=6 [slave  keyboard (3)]
    ↳ Video Bus                                id=7 [slave  keyboard (3)]
    ↳ Power Button                             id=8 [slave  keyboard (3)]
    ↳ Logitech USB Receiver                    id=9 [slave  keyboard (3)]

나 같은 경우는 Logitech 사에서 나온 무선 키보드 마우스 세트인 mk270r 모델을 사용중인데 그 때문에 pointer나 keyboard에 둘다 Logitech US Receiver라고 나온다. 우선 세팅을 수정할건 마우스니 해당 장치의 id인 10을 기억해두자.
그리고 다시 xinput 명령을 이용해 장치의 프로퍼티 세팅을 가져온다.

user@desktop:~$ xinput list-props 10
Device 'Logitech USB Receiver':
 Device Enabled (133): 1
 Coordinate Transformation Matrix (135): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
 Device Accel Profile (263): 0
 Device Accel Constant Deceleration (264): 1.000000
 Device Accel Adaptive Deceleration (265): 1.000000
 Device Accel Velocity Scaling (266): 10.000000
 Device Product ID (250): 1133, 50484
 Device Node (251): "/dev/input/event3"
 Evdev Axis Inversion (267): 0, 0
 Evdev Axes Swap (269): 0
 Axis Labels (270): "Rel X" (143), "Rel Y" (144), "Rel Horiz Wheel" (260), "Rel Dial" (261), "Rel Vert Wheel" (262)
 Button Labels (271): "Button Left" (136), "Button Middle" (137), "Button Right" (138), "Button Wheel Up" (139), "Button Wheel Down" (140), "Button Horiz Wheel Left" (141), "Button Horiz Wheel Right" (142), "Button Side" (255), "Button Extra" (256), "Button Forward" (257), "Button Back" (258), "Button Task" (259), "Button Unknown" (253), "Button Unknown" (253), "Button Unknown" (253), "Button Unknown" (253), "Button Unknown" (253), "Button Unknown" (253), "Button Unknown" (253), "Button Unknown" (253), "Button Unknown" (253), "Button Unknown" (253), "Button Unknown" (253), "Button Unknown" (253)
 Evdev Scrolling Distance (272): 1, 1, 1
 Evdev Middle Button Emulation (273): 0
 Evdev Middle Button Timeout (274): 50
 Evdev Third Button Emulation (275): 0
 Evdev Third Button Emulation Timeout (276): 1000
 Evdev Third Button Emulation Button (277): 3
 Evdev Third Button Emulation Threshold (278): 20
 Evdev Wheel Emulation (279): 0
 Evdev Wheel Emulation Axes (280): 0, 0, 4, 5
 Evdev Wheel Emulation Inertia (281): 10
 Evdev Wheel Emulation Timeout (282): 200
 Evdev Wheel Emulation Button (283): 4
 Evdev Drag Lock Buttons (284): 0

엄청 길게 나온다... 사실 이 명령어는 장치 id 대신 장치 이름으로 실행해도 되는데,나같은 경우에는 키보드와 마우스의 장치 이름이 같아 id로 실행했다.
어쨋든 다른 프로퍼티들은 다 무시하고 마우스 이동속도를 위해 수정해야되는건
Device Accel Constant Deceleration
프로퍼티 이다.

해당 프로퍼티는 정해진 꼐수만큼 마우스의 속도를 감속시킨다. 그러니 반대로 마우스의 속도를 올리기 위해서는 해당 계수를 낮춰줘야한다. 속도를 현재에서 2배로 올릴려면 0.5로 수정, 1.33배로 올릴려면 0.75로 수정해주자. 난 0.5로 설정해놓으니 조금 빠른거 같아 0.66, 1.5배로 속도를 올리기로 했다.

user@desktop:~$ xinput -set-prop 10 'Device Accel Constant Deceleration' 0.66

위의 명령을 실행하면 바로 마우스가 빨라진다. 하지만 재부팅할경우 기본값으로 리셋되기 때문에 해당 명령을 startup application에 넣어줘야한다.




추가

부팅할때마다 계속 명령을 실행해줘야는게 찝찝해 조금 더 찾아봤더니 dconf 데이터를 수정해서 마우스 이동속도를 조절할 수 있었다.
dconf 데이터 수정은 dconf-editor 를 이용해 간단하게 할 수 있다.

우리가 수정해야할 key 들은 org.gnome.settings-damon.peripherals.mouse 스키마에 존재한다.

dconf-editor 창

마우스 이동속도는 motion-acceleration 키를 수정하면 된다. motion-acceleration는 마우스가 기본 이동속도의 몇배로 움직이는지를 설정하는 계수이다. -1이 시스템 기본설성이며, 이렇게 설정하면 기본 이동속도의 1배로 움직인다. 2, 3, 4 등의 계수를 집어넣으면 그만큼 속도가 빨라지니 편한대로 설정하자.

motion-threshold 키는 몇 픽셀을 이동후 마우스 이동속도가 적용될지 설정하는 키이다. 이것도 편의에 따라 설정해주면 된다.

만약 dconf-editor가 설치되지 않았다면 아래 명령어를 이용해 설치후 수정하면 된다.

user@desktop:~$ sudo apt-get install dconf-editor

dconf-editor 설치를 원하지 않는다면 CLI dconf 수정 툴인 gsettings 를 이용해 수정할 수 있다.


#mouse 관련 스키마 보기
user@desktop:~$ gsettings list-schemas | grep 'mouse'
org.gnome.desktop.a11y.mouse
org.gnome.mousetweaks
org.gnome.settings-daemon.plugins.mouse
org.gnome.settings-daemon.peripherals.mouse

#org.gnome.settings-daemon-peripherals.mouse 스키마에 저장된 키 보기
user@desktop:~$ gsettings list-keys org.gnome.settings-daemon.peripherals.mouse
drag-threshold
motion-threshold
middle-button-enabled
motion-acceleration
double-click
left-handed
locate-pointer

#원하는 키의 현재값 가져오기
user@desktop:~$ gsettings get 'org.gnome.settings-daemon.peripherals.mouse' 'motion-acceleration'
-1.0

#원하는 값으로 키 수정하기
user@desktop:~$ gsettings set 'org.gnome.settings-daemon.peripherals.mouse' 'motion-acceleration' 3.0

이제 진짜 끝~. 이렇게하면 부팅할때마다 명령어를 실행해줘야할 필요가 없어진다~

2015년 10월 6일 화요일

[JavaScript] 문서 객체 모델(DOM, Document Object Model)

문서 객체 모델(DOM, Document Object Model)은 HTML과 XML 문서에 사용되는 API(Application Programming Interface)이다. DOM은 주어진 문서를 노드(node)를로 이루어진 계층구조의 트리(hierarchical tree)로 나타내며, 원하는 노드를 추가, 제거, 그리고 수정할 수 있게 한다. 이런 DOM의 가장 초기 버젼인 DOM Level 1은 1998년 W3C에 처음 표준으로 도입되었으며 현재 거의 모든 웹브라우져들, Chrome, Firefox, Safari, Internet Explorer, Microsoft Edge, Opera 등에 사용된다.

DOM Tree의 Node

각각의 태그들로 구성된 HTML 문서와 XML 문서를 Tree 형태로 표현하기 위해서 Node 들은 각각의 태그들을 구성하게 된다. 이 때문에 각각의 태그들은 그에 알맞는 Type을 가진 Node 행태로 저장되며, 서로 다른 Type의 Node 들은 그만의 특징, 데이터, 메소드, 다른 노드들과의 관계를 가지게 된다.

Document Node 와 Node Type

Document Node는 모든 Node들의 최상위에 위치하는 Root 노드이다.


<!DOCTYPE html>
<html>
 <head>
  <title>DOM Example</title>
 </head>
<body>
 <p>This is HTML Example</p>
</body>
</html>


예를들어 위의 html 코드를 DOM Tree 형식으로 표현한다면 아래와 같은 형태를 띄게된다.


Document Node 가 최상위에 위치하며 그 바로 아래 HTML Element Node 가 위치한다. Document Node는 최상위 Node로 문서내 모든 Node들의 ownerDocument 프로퍼티가 가리키는 node이다.
HTML Element Node는 Document Element 라 불리기도 하며, 다른 Element Node들의 최 상위에 위치하는 Element Node이다. 그렇기 때문에 Document Node는 단 1개의 Document Element를 자기 child 로 가지며, Document Element는 다른 element 들을 자기 children으로 가지게 된다.

HTML문서의 경우에는 html 태그가 Document Element이며, 이렇게, 모든 markup들은 Node로 Tree에 저장된다. 대부분의 markup 들은 Element Node 가 되며, attribute 들은 attribute node, markup에 감싸진 텍스트 들은 text node, 주석들은 comment node가 된다. 이렇게 총 12개 타입의 노드들이 존재한다.

  • Node.ELEMENT_NODE - 1
  • Node.ATTRIBUTE_NODE - 2
  • Node.TEXT_NODE - 3
  • Node.CDATA_SECTION_NODE - 4
  • Node.ENTITY_REFERENCE_NODE - 5
  • Node.ENTITY_NODE - 6
  • Node.PROCESSING_INSTRUCTION_NODE - 7
  • Node.COMMENT_NODE - 8
  • Node.DOCUMENT_NODE - 9
  • Node.DOCUMENT_TYPE_NODE - 10
  • Node.DOCUMENT_FRAGMENT_NODE - 11
  • Node.NOTATION_NODE - 12
각각의 타입은 숫자로 표현될 수 있다. 모든 Node 들은 nodeType 프로퍼티를 가지므로 위의 numeric constant로 비교가 가능하다.


if(node.nodeType == Node.ELEMENT_NODE){
 console.log("This is Element Node");
}


nodeType 프로퍼티가 node의 타입을 가르쳐 준다면, nodeName 프로퍼티는 해당 node의 태그이름을 저장하는 값이다.
nodeName 값과 nodeType 값은 node의 타입에 관계없이 모든 node가 가지고 있는 프로퍼티이다.


document.images[0].nodeName
//"IMG"
document.images[0].nodeType
//1


DOM(Document Object Model) 수정하기

모든 tree 구조가 그렇듯, 각각의 node 들은 다른 node 들과 특정 관계(Parent-Child, Siblings, First Child, Last Child)에 있다. 이러한 관계를 통해 개발자는 문서 객체 모델을 조금 더 쉽게 수정 가능하다.
우선 모든 Node 들은 자신의 프로퍼티로 childNodes라는 프로퍼티를 가지는데 이는 자신의 자식 node들의 리스트를 저장하는 프로퍼티 이다.childNodes 프로퍼티는 자식 노드들을 NodeList 타입의 자료구조로 저장한다. NodeList는 Array와 매우 비슷한 자료 구조로, Array와 마찬가지로 괄호([])를 이용해 내부 데이터에 접근이 가능한 구조이다. 하지만 Array Constructor를 통해 생성된 인스턴스는 아님을 염두에 두자. NodeList 객체는 실시간으로 DOM 스트럭쳐와 반응하며, 이때문에 NodeList에 생기는 변화는 곧바로 DOM 구조, 웹문서와 직결된다. NodeList 타입은 Array와 마찬가지로 []를 사용할 수도 있고, item 메소드를 이용해 접근할수도 있다.


node.childNodes[0];
node.childNodes.item(1);
node.childNodes.length;
node.firstChild == node.childNodes[0];//true
node.lastChild == node.childNodes[node.childNodes.length];//true


firstChild, lastChild 프로퍼티를 이용해 NodeList의 처음과 마지막 node에 접근이 가능하다.
또한 childNodes 프로퍼티와 마찬가지로 parentNode는 해당 Node의 상위 Node를 가르키는 포인터 역할을 한다. childNodes 리스트에 속한 Node들은 서로와 sibling 관계에 있으며 nextSibling, previousSibling 프로퍼티를 이용해 전 node, 다음 node로 접근이 가능하다.


node.childNodes[0].previousSibling;//null
node.childNodes[0].nextSibling;// == node.childNodes[1]
node.childNodes[node.childNodes.length-1].nextSibling;//null


리스트의 처음과 끝에 있는 node들은 previousSibling, nextSibling 프로퍼티로 null 값을 가지게 된다. 이런 포인터들은 모두 read-only 값을 가진 프로퍼티이기 때문에 위 프로퍼티들을 통해 직접적은 node 수정은 불가능하다.
그 때문에 수정시에는 DOM 수정을 위핸 메소드들을 이용해야한다.

Node 추가, 수정, 제거하기

appendChild() 메소드는 해당 노드의 childNodes 리스트의 마지막에 새로운 Node를 추가하고 추가된 node를 반환하는 메소드이다.


var newlyAddedNode = node.appendChild(newNode);
newlyAddedNode == newNode//true
node.lastChild == newNode//true


insertBefore() 메소드는 원하는 노드의 앞에 새로운 노드르 삽입하는 메소드이다. 새로 추가하는 노드, 삽입 위치의 뒤에있는 노드, 이렇게 2개의 argument를 가지며 새로 삽입된 노드를 반환한다.


var newlyAddedNode = node.insertBefore(newNode,node.childNodes[0]);
newlyAddedNode == newNode//true
node.firstChild == newNode//true
//만약 두번째 argument가 주어지지 않거나 null이 되면 nodeList의 마지막에 삽입된다.


replaceNode() 메소드는 원하는 노드를 새로운 노드로 교체하는 메소드 이다. 새로 교체할 노드, 교체될 노드, 이렇게 2개의 argument를 받으며 교체된 노드가 반환된다.


var oldNode = node.replaceNode(newNode,node.childNodes[0]);


removeNode() 메소드는 원하는 노드를 제거하는 노드이다. argument로는 제거할 노드를 가리키는 포인터를 받으며, 제거된 노드가 반환된다. 이렇게 제거된 node들은 제거된 이후에도 document에 의해 소유된다. 하지만 HTML Element 하위 트리에 속해있지 않기 때문에 사용자에게 보여지지 않는다.


var removed = node.removeNode(node.childNodes[0]);


Node 복사하기

문서 객체 모델 구조의 특성상 1개의 노드는 2개의 위치에 존재할 수 없다. 만약 그렇다면 이는 해당 노드의 포인터 프로퍼티가 2개의 값을 가지고 있음을 뜻하며 현실적으로 불가능한 일이다. 그렇기 때문에 이미 문서에 추가된 노드를 다른 위치에 삽입하려 시도하게 되면 원래 추가되었던 노드가 제거되는 일이 발생한다.


var oldNode = node.childNodes[0];
node.appendChild(oldNode);
node.childNodes[0] == oldNode;// false
node.lastChild == oldNode;// true


이러한 이유 때문에 이미 추가된 node를 문서의 다른 위치에 추가하기 위해서는 같은 프로퍼티를 가진 새로운 node 인스턴스를 생성해야할 필요가 있다. cloneNode() 메소드는 이러한 작업을 충실하게 수행하는 메소드이다. 이 메소드는 boolean 값 1개만을 argument로 받으며 이 boolean 값은 node의 하위 sub-tree까지 모두 포함하여 복사할지(true), 아니면 해당 node만 복사할지(false)를 정하는 argument 이다.


var clone1 = node.cloneNode(true);
var clone2 = node.cloneNode(false);


normalize() 메소드

normalize() 메소드는 메소드가 실행된 노드의 sub-tree에서 empty text node를 제거하는 메소드이다.normalize 메소드는 이런 empty text node를 제거하고, 여러개의 text node가 sibling 관계로 존재할시 해당 node들을 병합(merge)하는 메소드 이다.


<!DOCTYPE html>
<html>
 <head>
  <title>DOM Example</title>
 </head>
<body>
 <p id = "paragraph">
  This is HTML Example.
 </p>
</body>
</html>


위의 html 코드에서 p태그에 새로운 text를 추가한후에 childNodes 리스트를 보게되면 2개의 text node가 sibling 관계로 존재하는걸 알 수 있다.이를 normalize 메소드를 이용해 합쳐주자


document.getElementById("paragraph").appendChild(document.createTextNode("NewLine"));
document.getElementById("paragraph").childNodes;//["This is HTML Example.", "NewLine"]
//이를 normalize 메소드를 이용해 합쳐주자
document.getElementById("paragraph").normalize();
document.getElementById("paragraph").childNodes;//["This is HTML Example.NewLine"]

2015년 9월 29일 화요일

[JavaScript] 브라우져 객체 모델(BOM, Browser Object Model) - history 객체

history 객체는 현재 웹페이지를 표시하는 브라우져 윈도우의 방문기록을 저장하는 객체이다. history 객체는 window 객체의 프로퍼티 중 하나이기 때문에 다른 윈도우의 방문기록에는 접근하지 못한다. 또한 보안상의 이유로 history 객체에 저장된 url들에도 접근이 불가능하기 때문에, 오직 웹페이지 이동만이 가능하다.

history 객체는 length 프로퍼티를 가지는데 length 값은 history 스택의 길이이다. 즉 history.length 가 0이라면 이는 history 스택이 empty 상태란것을 말하게 된다.

history 객체의 go 메소드를 이용해 방문기록으로 이동이 가능하다.
go 메소드는 1개의 argument 를 받는다. 해당 argument 는 숫자 또는 문자열이 될 수 있으며 argument 의 타입에 따라 다른 결과를 낳는다.


//숫자를 argument로 전달할시
history.go(-1)//바로 전 페이지로 이동
history.go(-2)//전전 페이지로 이동
history.go(0)//현재페이지를 리로딩
history.go(1)//앞페이지로 이동

//문자(url)을 argument로 전달할시
history.go("google.com")//가장 최근의 google.com 페이지로 이동한다
history.go("naver.com")//가장 최근의 naver.com 페이지로 이동한다

go 메소드처럼 forward, back 메소드를 이용, 앞페이지, 전페이지로 이동이 가능하다.


history.back();
history.forward();