[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)    ]



+ Recent posts