JavaScript

Park sang woo·2023년 4월 17일
0
post-thumbnail

무조건 백엔드로만 가지 않고 풀스택을 위해 도전한다.

내가 공부한 기본 Javascript 사이트
https://poiemaweb.com/ (기본은 쭉쭉 사이트 보면서 넘어감.)
그리고 인프런의 생활코딩(활용) 익숙하지 않은 부분부터 기록.
환경은 Visual Studio Code
https://duwjdtn11.tistory.com/65






📖 DOM 제어대상 찾기

DOM이란 : XML이나 HTML 문서에 접근하기 위한 일종의 인터페이스.

getElementsByTagName : 현재 이 파일의 전체(document)에서 태그의 이름이 ' '인 요소들을 가져온다.

<!DOCTYPE html>
<body>
    <ul>
        <li>HTML</li>
        <li>CSS</li>
        <li>JavaScript</li>
    </ul>
    <script>
        var lis = document.getElementsByTagName('li');
        for(var i=0; i<lis.length; i++){
            lis[i].style.color='red';
        }
    </script>
</body>
</html>

아까처럼 document.getElementsByTagName('li')를 사용하면 ul태그든 ol태그든 내부의 모든 li태그 태그들을 모두 빨간색으로 바꾼다. 그래서 조회의 대상을 한정시키기 위해 ul태그를 가진 요소들을 배열로 반환시키고 첫 번째 요소값을 가져와서 ul변수에 저장시킨다.
그리고 ul태그에서 'li'만 조회하도록 lis를 생성한다.

<!DOCTYPE html>
<body>
    <ul>
        <li>HTML</li>
        <li>CSS</li>
        <li>JavaScript</li>
    </ul>
    <ol>
        <li>HTML</li>
        <li>CSS</li>
        <li>JavaScript</li>
    </ol>

    <script>
        var ul = document.getElementsByTagName('ul')[0];
        var lis = ul.getElementsByTagName('li');
        for(var i=0; i<lis.length; i++){
            lis[i].style.color='red';
        }
    </script>
</body>
</html>


getElementsByClassName : 태그 안에 class=""를 지정해서 ClassName에 따라 요소를 조회.

<!DOCTYPE html>
<body>
    <ul>
        <li>HTML</li>
        <li class="active">CSS</li>
        <li class="active">JavaScript</li>
    </ul>

    <script>
        var lis = document.getElementsByClassName('active');
        for(var i=0; lis.length; i++){
            lis[i].style.color='red';
        }
    </script>
</body>
</html>


getElementById : id로 지정한 값으로 요소 하나만을 조회한다.



querySelector(All) : id 뿐만 아니라 class를 비롯해 다양한 css선택자를 사용하여 조건에 맞는 요소 하나만을 조회한다.
요소 하나는 첫 번째로 발견한 것을 조회함. 일치하는 요소가 없으면 null을 반환.

#sections -> sections 아이디를 가진 요소를 찾는다.
.section -> section 클래스명을 가진 요소를 찾는다.

All이 붙으면 해당 선택자에 해당하는 모든 요소를 가져온다.


id, name, class 차이
id는 객체에 이름을 부여할 때 사용하고 중복을 허용하지 않는다. javascript와 css에서 접근하기 용이하다.
name은 id와 다르게 중복 사용이 가능하지만 id나 class같이 CSS에는 접근할 수 없다. 중복 허용하므로 javascript에서 사용할 땐 배열 인덱스값을 필수로 넣어줘야 한다.
class는 중복 사용 가능하고 CSS에서 많이 사용. (재사용 가능.)






📖 jQuery

HTML의 요소들을 쉽게 조작하고 편리하게 사용할 수 있게 만든 자바스크립트 라이브러리.
웹 사이트에 자바스크립트를 더욱 손쉽게 활용할 수 있게 해줌.

$('body') 부분은 태그를 선택.
.prepend('') : 앞에서 선택한 태그 안에 내용을 넣는다.






📖 jQuery 문법

jQuery는 항상 로시작한다.(로 시작한다. (는 함수를 의미)
ex) $('li').css('color', 'red');
CSS 선택자를 전달하면 jQuery 객체를 반환한다.
css는 선택자에 해당하는 객체들의 style을 변경.

DOM에서는 li태그의 모든 색깔을 바꿀 때 이렇게 했다.

<!DOCTYPE html>
<body>
    <ul>
        <li>HTML</li>
        <li class="active">CSS</li>
        <li class="active">JavaScript</li>
    </ul>

    <script>
        var lis = document.getElementsByTagName('li');
        for(var i=0; i<lis.length; i++){
            lis[i].style.color='red';
        }
    </script>
</body>
</html>

하지만 jQuery에서는 더욱 간단하게 이렇게 할 수 있다.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul>
        <li>HTML</li>
        <li class="active">CSS</li>
        <li class="active">JavaScript</li>
    </ul>
    <script>
        $('li').css('color','red');
    </script>
</body>
</html>


또 다른 예시들

<!DOCTYPE html>
<body>
    <ul>
        <li>HTML</li>
        <li class="active">CSS</li>
        <li class="active">JavaScript</li>
    </ul>

    <script>
        var lis = document.getElementsByClassName('active');
        for(var i=0; i<lis.length; i++){
            lis[i].style.color='red';
        }
    </script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul>
        <li>HTML</li>
        <li class="active">CSS</li>
        <li class="active">JavaScript</li>
    </ul>
    <script>
        $('.active').css('color','red');
    </script>
</body>
</html>

active 앞에 .은 클래스명이 active인 요소들을 가리킨다는 의미이다.


<!DOCTYPE html>
<body>
    <ul>
        <li>HTML</li>
        <li id="active">CSS</li>
        <li>JavaScript</li>
    </ul>

    <script>
        var lis = document.getElementById('active');
        lis.style.color='red';
        lis.style.textDecoration='underline';
    </script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul>
        <li>HTML</li>
        <li id="active">CSS</li>
        <li>JavaScript</li>
    </ul>
    <script>
        $('#active').css('color','red').css('textDecoration', 'underline');
    </script>
</body>
</html>

코드의 중복을 줄이는 것을 체이닝이라 한다.
jQuery를 이용하면 체이닝이 가능하다.
중요 : id를 기준으로 어떤 Element를 조회할 때는 #을 사용.






📖 HTMLElement

<ul>
    <li>HTML</li>
    <li>CSS</li>
    <li id="active">JavaScript</li>
</ul>
<script>
    var li = document.getElementById('active');
    console.log(li.constructor.name);
    var lis = document.getElementsByTagName('li');
    console.log(lis.constructor.name);
</script>

실행결과
HTMLELIElement
HTMLColleciton
즉 실행 결과가 하나면 HTMLLIElement, 복수라면 HTMLCollection.



**HTMLAnchorElement** : 하이퍼링크(hyperlink) 기능을 갖는 요소(a 태그)를 다루며 이러한 기능을 위한 특별한 속성과 메소드를 제공하는 인터페이스이다. **HTMLInputElment** : input 태그 요소를 다루는 인터페이스이다.
모든 엘리먼트는 HTMLElement의 자식이다 따라서 HTMLElement의 프로퍼티를 똑같이 가지고 있다. 동시에 엘리먼트의 성격에 따라서 자신만의 프로퍼티를 가지고 있는데 이것은 엘리먼트의 성격에 따라서 달라진다. HTMLElement는 Element의 자식이고 Element는 Node의 자식이고 Node는 Object의 자식이다. 이러한 관계를 DOM Tree라 한다.




📖 jQuery 객체

jQuery 함수의 리턴값으로 jQuery 함수를 이용해서 선택한 엘리먼트들에 대해서 처리할 작업을 프로퍼티로 가지고 있는 객체.

var li = $('li');

li는 jQuery 객체이고 $('li')는 jQuery 함수이다.


출력을 할 때 반드시 $('태그')를 지정해 줘야 한다.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul>
        <li>HTML</li>
        <li>CSS</li>
        <li>JavaScript</li>
    </ul>
    <script>
        var li = $('li');
        for(var i=0; i<li.length; i++){
            console.log($(li[i]).css('color', 'red'));
        }
    </script>
</body>
</html>


🍀 map()

map이라는 메서드가 있는데 map은 함수를 인자로 받도록 되어있다. 내가 선택한 엘리먼트들을 순회하면서 함수를 호출한다.
index는 엘리먼트의 인덱스이고 elem은 각각의 엘리먼트에 대한 DOM 객체(HTMLLIElement)이다.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul>
        <li>HTML</li>
        <li>CSS</li>
        <li>JavaScript</li>
    </ul>
    <script>
        var li = $('li');
        li.map(function(index, elem){
            console.log(index, elem);
            $(elem).css('color', 'red');
        })
    </script>
</body>
</html>

DOM객체는 CSS 명령어를 사용할 수 없기 때문에 객체가 아닌 jQuery 함수 $()로 감싸서 사용해야 한다.


🍀 jQuery 객체 API

https://api.jquery.com/
이곳에 굉장히 많음.






📖 Element 객체

Element 객체는 엘리먼트를 추상화한 객체이다.

주요 기능

❄ 식별자

엘리먼트를 제어하기 위해서는 그 엘리먼트를 조회하기 위한 식별자가 필요. 문서 내에서 특정한 엘리먼트를 식별하기 위한 용도로 사용되는 API.

🧿 Element.tagName

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul>
        <li>HTML</li>
        <li>CSS</li>
        <li id="active", class="important current">JavaScript</li>
    </ul>
    <script>
        console.log(document.getElementById('active').tagName);
    </script>
</body>
</html>

참고 : tagName은 읽기 전용이기 때문에에 수정이 불가능하다.


🧿 Element.id

문서에서 id는 단 하나만 등장할 수 있는 식별자다.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul>
        <li>HTML</li>
        <li>CSS</li>
        <li id="active">JavaScript</li>
    </ul>
    <script>
        var active = document.getElementById('active');
        console.log(active.id);
        active.id = 'deactive';
        console.log(active.id);
    </script>
</body>
</html>

id는 수정이 가능하다.


🧿 Element.className

여러 개의 엘리먼트를 그룹핑할 때 사용. 그러나 사용하기 까다로워 classList를 사용.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul>
        <li>HTML</li>
        <li>CSS</li>
        <li id="active">JavaScript</li>
    </ul>
    <script>
        var active = document.getElementById('active');

        // class 값을 변경할 때는 프로퍼티의 이름으로 className을 사용한다.

        active.className = "important current";
        console.log(active.className);

        // 클래스를 추가할 때는 아래와 같이 문자열의 더한다.
        active.className += " readed"
    </script>
</body>
</html>

🧿 Element.classList

엘리먼트의 클래스 속성의 컬렉션인 활성 DOMTokenList를 반환하는 읽기 전용 프로퍼티.
classList 사용은 공백으로 구분된 문자열인 element.className을 통해 엘리먼트의 클래스 목록에 접근하는 방식을 대체하는 간편한 방법

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul>
        <li>HTML</li>
        <li>CSS</li>
        <li id="active" class="marked current">JavaScript</li>
    </ul>

    <script>
        console.log(active.classList[0]); // marked
        console.log(active.classList[1]); // current
        console.log(active.classList.length); // 2
    </script>
</body>
</html>

메서드로는 add, remove, item, toggle, contains, replace가 있다.

ex)
active.classList.add('important')
active.classList.remove('important')
active.classList.toggle('important')
active.classList.contains('important')
active.classList.replace('important', 'NULL')

toggle은 클래스 값을 토글링한다. 즉, 클래스가 존재한다면 제거하고 false를 반환하며, 존재하지 않으면 클래스를 추가하고 true를 반환한다.
contains는 지정한 클래스 값이 엘리먼트의 class 속성에 존재하는지 확인한다.

❄ 조회 API

🧿 Element.getElementsByClassName

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul>
        <li class="marked">html</li>
        <li>css</li>
        <li id="active">JavaScript
            <ul>
                <li>JavaScript Core</li>
                <li class="marked">DOM</li>
                <li class="marked">BOM</li>
            </ul>
        </li>
    </ul>

    <script>
        var list = document.getElementsByClassName('marked');
        console.group('document');
        for(var i=0; i<list.length; i++){
            console.log(list[i].textContent);
        }
        console.groupEnd();

        console.group('active');
        var active = document.getElementById('active');
        var list = active.getElementsByClassName('marked');
        for(var i=0; i<list.length; i++){
            console.log(list[i]. textContent);
        }
        console.groupEnd();
    </script>
</body>
</html>

.textContent : script 태그나 style 태그에 상관없이 해당 노드가 가지고 있는 텍스트 값을 모두 읽어온다.

console.group(), console.groupEnd() : 메시지 그룹의 시작과 끝을 정해줌.

♦ Element.getElementsByTagName
♦ Element.querySelector
♦ Element.querySelectorAll


❄ 속성

태그명만으로는 부족한 부가적인 정보로 다 표현하는 것이 어려울 때 사용한다.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <a id="target" href="http://naver.com">open</a>

    <script>
        var t = document.getElementById('target');
        console.log(t.getAttribute('href'));
        console.log(t.setAttribute('href', 'http://google.co.kr'));
        
        // 또 다른 속성을 추가하고 싶다면
        t.setAttribute('title', 'opentutorials');
        // 그 속성을 삭제하고 싶다면
        t.removeAttribute('title');

        // 지정한 속성이 있는지 확인
        t.hasAttribute('href');
    </script>
</body>
</html>

Element.getAttribute(name) : 어떤 속성의 값을 가져옴.
Element.setAttribute(name, value) : 속성 값을 name -> value로 수정.
Element.hasAttribute(name) : 속성이 있는지 확인.
Element.removeAttribute(name) : 속성 삭제.



🎩 속성과 프로퍼티

속성은 HTML 요소의 추가적인 정보를 가지고 있는 이름과 값의 한 쌍을 의미.
프로퍼티는 속성을 객체화했을 때의 HTML DOM 트리 내부에서의 값을 가리킴.

프로퍼티는 전체 주소가 리턴되고 속성은 직접 기술한 상대 주소가 출력된다.






📖 jQuery 속성 제어 API

jQuery에는 setAttribute, getAttribute에 대응되는 메소드로 attr과 removeAttr이 있다.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <a id="target" href="http://naver.com">open</a>

    <script>
        var t = $('#target');
        console.log(t.attr('href'));
        t.attr('title', 'opentutorials.org'); //setAttribute와 같은 역할을 수행.
        t.removeAttr('title'); //removeAttribute
    </script>
</body>
</html>


Attribute와 Property

jQuery를 통해서도 attr과 prop으로 구분지을 수 있다.
attr()은 속성 그 자체의 값을 반환하고 prop()은 속성값을 명시적으로 찾아낼 수 있는 방법을 제공한다.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <a id="t1" href="./demo.html">open</a>
    <input id="t2" type="checkbox" checked="checked" />

    <script>
        var t1 = $('#t1');
        console.log(t1.attr('href'));
        console.log(t1.prop('href')); //전체 URL이 나옴

        var t2 = $('#t2');
        console.log(t2.attr('checked')); // 값 그대로 나와서 checked
        console.log(t2.prop('checked')); // true
    </script>
</body>
</html>





📖 jQuery 조회 범위 제한

jQuery로도 Element 객체에서 getElementsBy* 메서드를 실행하면 조회의 범위를 그 객체의 하위 엘리먼트로 제한할 수 있다.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul>
        <li class="marked">html</li>
        <li>css</li>
        <li id="active">JavaScript
            <ul>
                <li>JavaScript Core</li>
                <li class="marked">DOM</li>
                <li class="marked">BOM</li>
            </ul>
        </li>
    </ul>

    <script>
        $("#active .marked").css("background-color", "red");
        //$(".marked", "#active").css("background-color", "red"); //이 3개는 같은 결과임
        //$('#active').find('.marked').css("background-color", "red");
    </script>
</body>
</html>

두 번째 인자로 active라고 있는 엘리먼트를 선택하고 첫 번째 인자로는 두 번째 인자로 정한 엘리먼트 하위의 엘리먼트인 marked를 선택한다.
#은 id 값을 구분, .은 클래스를 구분.

find()
$('#active').find('.marked').css("background-color", "red");
.find() 앞에 있는 jQuery 'active' 객체 하부의 marked 엘리먼트들을 조회한다.

ex)$('#active').css('color', 'blue').find('.marked').css('background-color', 'red');
id가 active인 것들을 모두 글자색 blue로 만들고 class=marked를 찾아서 배경 빨강으로



참고 == 과 === 차이
==는 값만 비교하고 ===는 값과 타입을 같이 비교한다.

console.log(123 == "123"); //true
console.log(123 === "123"); //false
console.log(123 == "abc"); //false
console.log(123 === "abc"); //false
console.log("abc" == "abc") //true
console.log("abc" === "abc") //true





📖 Node 객체

DOM에서 시조와 같은 역할을 한다.
모든 DOM 객체는 Node 객체를 상속받는다. 엘리먼트는 서로 부모, 자식, 혹은 형제자매 관계로 연결되어 각각의 Node가 다른 Node와 연결된 정보를 보여주는 API를 통해서 문서를 프로그래밍적으로 탐색할 수 있다.

📍 Node.childNodes
📍 Node.firstChild 
📍 Node.lastChild 
📍 Node.nextSibling 
📍 Node.previousSibling 
📍 Node.contains() 
📍 Node.hasChildNodes()

각각의 구성요소가 어떤 카테고리에 속하는 것인지를 알려주는 식별자
Node.nodeType, Node.nodeName

Node 객체의 값을 제공하는 API
Node.nodeValue, Node.textContent

Node 객체의 자식을 추가하는 방법에 대한 API
Node.appendChild()
Node.removeChild()






📖 재귀

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<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>

    <script>
        function traverse(target, callback){
            if(target.nodeType === 1){
                callback(target);
                var c = target.childNodes;
                for(var i=0; i<c.length; i++){
                    traverse(c[i], callback);
                }
            }
        }

        traverse(document.getElementById('start'), function(elem){
            if(elem.nodeName === 'A'){ // 대문자로 쓰기
                elem.style.backgroundColor = 'black';
                console.log(elem);
            }
        });
    </script>
</body>
</html>

callback : 각각의 엘리먼트들을 조회할 때마다 그 순번에 해당하는 엘리먼트들을 사용자가 작성한 함수의 인자로 전달하므로 매개변수에 함수가 위치한다.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<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>

    <script>
        function traverse(target, callback){
            if(target.nodeType === 1){
                callback(target);
                var c = target.childNodes;
                for(var i=0; i<c.length; i++){
                    traverse(c[i], callback);
                }
            }
        }

        function traverse(target, callback){
            callback(target);
        }

        traverse(document.getElementById('start'), function(elem){
            console.log(elem);
        });
    </script>
</body>
</html>

결과 -> body#start



<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<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>

    <script>
        function traverse(target, callback){
            if(target.nodeType === Node.ELEMENT_NODE){
                if(target.nodeName === 'A'){ // <a> 링크 노드만을 호출
                    callback(target);
                }
                var c = target.childNodes;
                for(var i=0; i<c.length; i++){
                    traverse(c[i], callback);
                }
            }
        }

        traverse(document.getElementById('start'), function(elem){
            console.log(elem);
        });
    </script>
</body>
</html>





📖 Node 추가, 삭제, 변경

appendChild()와 insertBefore()가 있다.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul id="target">
        <li>HTML</li>
        <li>CSS</li>
    </ul>

    <input type="button" onclick="callAppendChild();" value="appendChild()" />
    <input type="button" onclick="callInsertBefore();" value="callInsertBefore()" />

    <script>
        function callAppendChild(){
            var target = document.getElementById('target');
            var li = document.createElement('li'); //li 엘리먼트 생성하고 내용은 비어있음.
            var text = document.createTextNode('JavaScript'); //createTextNode로 내용을 넣음
            //즉 <li></li>와 내용인 JavaScript를 생성한 것. 하지만 아직 결합은 되어있지 않은 상태.

            li.appendChild(text); // li 객체 자식으로 text를 넣음. 즉 <li>JavaScript</li>를 생성한 것.
            target.appendChild(li); //appendChild는 항상 마지막에 넣어줌. 즉 CSS 뒤에.
        }

        function callInsertBefore(){
            var target = document.getElementById('target');
            var li = document.createElement('li');
            var text = document.createTextNode('jQuery');

            li.appendChild(text);
            target.insertBefore(li, target.firstChild); // 2번째 인자의 앞에 넣어줌.
        }
    </script>
</body>
</html>

Node 제거, 변경
removeChild()

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <ul id="target">
        <li>HTML</li>
        <li>CSS</li>
        <li id="target">JavaScript</li>
    </ul>

    <input type="button" onclick="callRemoveChild();" value="removeChild()" />

    <script>
        function callRemoveChild(){
            var target = document.getElementById('target');
            target.parentNode.removeChild(target);
        }// 모두 삭제가 됨.
    </script>
</body>
</html>

replaceChild()
텍스트였던 JavaScript가 Web browser JavaScript 링크로 변경됨.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <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://google.co.kr');
            a.appendChild(document.createTextNode('Web browser JavaScript'));

            var target = document.getElementById('target');
            target.replaceChild(a, target.firstChild);
        }
    </script>
</body>
</html>





📖 jQuery 노드 변경

.before : 지정한 클래스 이름 앞에 위치
.after : 지정한 클래스 이름 뒤에 위치
.prepend : 지정한 클래스 안에 content 앞에 위치
.append : 지정한 클래스 안에 content 뒤에 위치


결과



노드 삭제

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <div class="target" id="target1">
        target1
    </div>

    <div class="target" id="target2">
        target2
    </div>

    <input type="button" value="remove target 1" id="btn1"/>
    <input type="button" value="empty target 2" id="btn2"/>

    <script>
        $('#btn1').click(function(){
            $('#target1').remove(); // 엘리먼트가 모두 삭제됨.
        })

        $('#btn2').click(function(){
            $('#target2').empty(); // 텍스트는 삭제되지만 태그는 유지됨.
        })
    </script>
</body>
</html>





💭 replaceAll, replaceWith

모두 노드의 내용을 교체하는 API이다. replaceWith는 제어 대상을 먼저 지정하지만 replaceAll은 제어 대상을 인자로 전달한다.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <div class="target" id="target1">
        target1
    </div>

    <div class="target" id="target2">
        target2
    </div>

    <input type="button" value="replaceAll target 1" id="btn1"/>
    <input type="button" value="replaceWith target 2" id="btn2"/>

    <script>
        $('#btn1').click(function(){
            $('<div>replaceAll</div>').replaceAll('#target1');
        })

        $('#btn2').click(function(){
            $('#target2').replaceWith('<div>replaceWith</div>');
        })
    </script>
</body>
</html>





💭 .clone() 과 append()

복사

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <div class="target" id="target1">
        target1
    </div>

    <div class="target" id="target2">
        target2
    </div>

    <div id="source">source</div>

    <input type="button" value="clone replaceAll target 1" id="btn1"/>
    <input type="button" value="clone replaceWith target 2" id="btn2"/>

    <script>
        $('#btn1').click(function(){
            $('#source').clone().replaceAll('#target1');
        }) //$('#source') 를 복사해서 #target1으로.

        $('#btn2').click(function(){
            $('#target2').replaceWith($('#source').clone());
        }) //반대로
    </script>
</body>
</html>

이동 -> append말고도 prepend, after, before도 있음.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <div id="source">source</div>
    
    <div class="target" id="target1">
        target1
    </div>

    <input type="button" value="append" id="btn1"/>

    <script>
        $('#btn1').click(function(){
            $('#target1').append($('#source'));
        })

    </script>
</body>
</html>





📖 InnerHTML, OuterHTML

innerHTML

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <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> 태그로 묶여서 출력된다.
        // 즉 html 형식으로 텍스트가 출력된다.
       }

       function set(){
        var target = document.getElementById('target');
        target.innerHTML = "<li>JavaScript Core</li><li>BOM</li><li>DOM</li>";
        // innerHTML로 지정한 텍스트로 바껴서 출력된다.
       }

    </script>
</body>
</html>

outerHTML

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body>
    <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);
       }

       function set(){
        var target = document.getElementById('target');
        target.outerHTML = "<ol><li>JavaScript Core</li><li>BOM</li><li>DOM</li></ol>"
       }
    </script>
</body>
</html>

innerText : 작성했던 텍스트 그대로 나온다.
outerText : 태그를 포함해서 텍스트를 가져온다.
insertAdjacentHTML('beforebegin', '')
insertAdjacentHTML('afterbegin', '
')
insertAdjacentHTML('beforeend', '')
insertAdjacentHTML('afterend', '
')






📖 Text 객체

값 API - nodeValue, data
텍스트 노드의 값을 가져오는 API

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>

<body id="start">
    <ul>
        <li id="target">html</li>
        <li>css</li>
        <li>JavaScript</li>
    </ul>

    <script>
        var t = document.getElementById('target').firstChild;
        console.log(t.nodeValue); // html
        console.log(t.data); // html
        
        t.nodeValue = '바뀐다';
        console.log(t.nodeValue); // html -> 바뀐다
        
	    t.data = 'hi';
        console.log(t.data); //html -> hi
    </script>
</body>
</html>

조작
appendData(data)
deleteData(st, ed)
insertData(st, data)
replaceData(st, ed, data)
subStringData(st, ed)

<!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="FU11_M00N_test" /></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>
    <!--value는 버튼에 텍스트를 넣기 위함이다.-->

<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>





📖 문서의 기하학적 특성

<!DOCTYPE html>
<html>
<head>
    <style>
        body{
            padding:0;
            margin:0;
        }
        #target{
            width:100px;
            height:100px;
            border:50px solid #1065e6;
            padding:50px;
            margin:50px;
        }
    </style>
</head>
<body>
    <div id="target">
        Coding
    </div>

<script>
    var t = document.getElementById('target');
    console.log(t.getBoundingClientRect());
</script>
</body>
</html>

top : 제일 상단으로부터 엘리먼트가 있는 곳까지의 크기.
left : 제일 왼쪽으로부터 엘리먼트가 있는 곳까지의 크기.
right : 제일 왼쪽 화면이 시작되는 곳터 엘리먼트가 끝나는 지점까지의 크기

t.getBoundingClientRect()를 통해서 화면과 엘리먼트 사이의 크기를 구할 수 있다.

offsetParent : 측정의 기준이 되는 엘리먼트가 어떤 것인지를 알려주는 것.

테두리를 제외한 엘리먼트의 크기를 알고 싶다면 ClientWidth와 ClientHeight를 사용한다.


viewport : 브라우저에서 사용자에게 보여주는 영역.
문서는 화면 전체.

window.pageYOffset : 스크롤을 몇 px 움직였는지 보여주는 것.
getBoundingClientRect : viewport로부터 엘리먼트까지의 거리. viewport의 좌표를 사용한다.

만약 전체 화면인 문서로부터 엘리먼트까지의 거리를 구하고 싶다면 getBoundingClinentRect와 pageYOffset의 값을 더하면 된다.



window.scrollTo(x, y) : x,y 만큼 스크롤을 이동시켜줌.

<!DOCTYPE html>
<html>
<body>
    <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); // 스크롤이 y만큼 이동된다.
        })
    </script>

    <div>
        <div id="target">
            Coding
        </div>
    </div>
</body>
</html>


윈도우 창 크기를 나타내는 window.innerWidth, window.innerHeight, window.outerWidth, window.outerHeight






📖 이벤트

어떤 사건을 의미한다. 브라우저에서 사건ㄴ이란 사용자가 클릭을 했을 때 또는 스크롤을 했을 때, 필드의 내용을 바꾸었을 때와 같은 것을 의미한다.

<!DOCTYPE html>
<html>
<body>
    <style>
        
    </style>
    <!--window.locatoin 현재 URL을 보여줌.-->
    <input type="button" onclick="alert(window.location)" value="href" />
    <!--웹브라우저에서 새창(팝업창)을 열기 위해서 가장 간단히 사용할 수 있는 방법-->
    <input type="button" onclick="window.open('bom.html')" value="open" />

</body>
</html>

어떤 일이 발생했을 대 실행되어야 하는 코드를 등록하고 브라우저는 그 일이 발생했을 때 등록된 코드를 실행하게 되는 방식을 이벤트 프로그래밍이라 한다.

이벤트 target : 이벤트의 대상이 되는 것. 위에서는 button이 target이다.
이벤트 type : 이벤트의 종류로 이벤트가 실행됐을 때를 의미한다. 위에서는 onclick이 이벤트 타입이다.
이벤트 handler : 이벤트가 발생했을 때 동작하는 코드를 의미한다. 위에서는 alert(window.location)이다.






📖 인라인 방식

이벤트를 이벤트 대상의 태그 속성으로 지정하는 것.
ex));"

this를 사용해서 간편하게 참조 가능.

<!DOCTYPE html>
<html>
<body>
    <input type="button" id="target" onclick="alert('Hello, world, ' 
    +document.getElementById('target').value);" value="button"/>
    

	<!--this 사용-->
    <input type="button" onclick="alert('Hello world, '+this.value);" value="button" />
</body>
</html>

하지만 인라인 방식은 HTML 파일의 사이즈를 너무 크게 만들어서, 화면에 웹페이지가 로딩되는 시간을 오래 걸리게 한다. 또한 HTML, CSS가 코드에 뒤섞이게 되어 유지보수를 어렵게 하기도 한다.






📖 프로퍼티

프로퍼티 리스너 방식은 이벤트 대상에 해당하는 객체의 프로퍼티로 이벤트를 등록하는 방식이다.
인라인 방식에 비해 HTML과 JavaScript를 분리할 수는 있지만 addEventListener 방식을 더 추천.

<!DOCTYPE html>
<html>
<body>
    <input type="button" id="target" value="button"/>

    <script>
        var t = document.getElementById('target');
        t.onclick=function(event){
            alert('Hello world, ' +event.target.value);
            console.dir(event);

            // 만약 인자로 전달된 event가 있다면 사용하고 없다면 window.event를 사용한다.
            var event = event || window.event;
            console.log(event.target);

            var target = event.target || event.srcElement;
            console.log(target);
        }
    </script>
</body>
</html>

버튼을 클릭하면 버튼에 해당하는 이벤트 핸들러인 function을 호출되고 첫 번째 안자인 event 객체를 전달한다.
event.target은 이벤트가 호출된 시점에서 그 이벤트가 어디에서 발생한 것인지를 알려주는 프로퍼티이다.

console.dir(event)는 event에 대한 정보를 알려준다.






📖 리스너 - addEventListener()

이벤트를 등록하는 가장 권장되는 방식으로 이 방식을 사용하면 여러 개의 이벤트 핸들러를 사용할 수 있다.
이벤트가 여러 개여도 모두 실행이 된다.
ex) 변수.addEventListener('type', function(){});

<!DOCTYPE html>
<html>
<body>
    <input type="button" id="target" value="button"/>

    <script>
        var t = document.getElementById('target');
        t.addEventListener('click', function(event){
            alert('Hello world, ' + event.target.value);
        });

        t.addEventListener('click', function(event){
            alert(2);
        });
        // 이벤트가 2개 모두 실행됨.
    </script>
</body>
</html>





📖 이벤트 전파(버블링, 캡처링)

버블링 : 자식 요소에서 발생한 이벤트가 바깥 부모 요소로 전파.

캡처링 : 자식 요소에서 발생한 이벤트가 부모 요소부터 시작하여 안쪽 자식 요소까지 도달

<!DOCTYPE html>
<html>
<head>
    <style>
        html{border:5px solid red; padding:30px;}
        body{border:5px solid green; padding:30px;}
        fieldset{border:5px solid blue; padding:30px;}
        input{border:5px solid black; padding:30px;}
    </style>
</head>
<body>
    <fieldset>
        <legend>event propagation</legend>
        <input type="button" id="target" value="target">
    </fieldset>

    <script>
        function handler(event){
            var phases=['capturing', 'target', 'bubbling'];
            console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);
        }

        // 이벤트 전파를 도중에 멈추고 싶을 때
        function stopHandler(event){
            var phases=['capturing', 'target', 'bubbling']
            console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);

            event.stopPropagation(); // 멈추기
        }

        document.getElementById('target').addEventListener('click', handler, false);
        document.querySelector('fieldset').addEventListener('click', handler, false);
        document.querySelector('body').addEventListener('click', stopHandler, false); //body에서 멈춤.
        document.querySelector('html').addEventListener('click', handler, false);
        //버블링이면 3번째 인자가 false.
    </script>
</body>
</html>





📖 기본동작의 취소

체크박스에 체크를 해야 제출이 가능하다.
false를 리턴하게 되면 브라우저는 a태그에 대한 이벤트 동작을 취소한다.

<!DOCTYPE html>
<html>
<body>
    <p>
        <label>prevent event on</label><input id="prevent" type="checkbox" name="eventprevent" value="on" />
    </p>

    <p>
        <a href="http://opentutorials.org" onclick="if(document.getElementById('prevent').checked)
        return false;">opentutorials</a>
    </p>

    <p>
        <form action="http://opentutorials.org" onsubmit="if(document.getElementById('prevent').checked)
        return false;">
        <input type="submit" />
        </form>
    </p>
    <script>

    </script>
</body>
</html>

addEventListener 사용

<!DOCTYPE html>
<html>
<body>
    <p>
        <label>prevent event on</label><input id="prevent" type="checkbox" name="eventprevent" value="on" />
    </p>

    <p>
        <a href="http://opentutorials.org">opentutorials</a>
    </p>

    <p>
        <form action="http://opentutorials.org">
            <input type="submit" />
        </form>
    </p>

    <script>
        document.querySelector('a').addEventListener('click', function(event){
            if(document.getElementById('prevent').checked)
            event.preventDefault();
        });

        document.querySelector('form').addEventListener('submit', function(event){
            if(document.getElementById('prevent').checked)
            event.preventDefault();
        });
    </script>
</body>
</html>

단 ie9 이하 버전에서는 event.returnValue를 false로 설정.






📖 폼

사용자가 입력한 정보를 서버로 전송할 때 사용하는 태그.

<!DOCTYPE html>
<html>
<body>
    <form id="target" action="result.html">
        <label for="name">name</label> <input id="name" type="name" />
        <input type="submit" />
    </form>

    <script>
        var t = document.getElementById('target');
        t.addEventListener('submit', function(event){
            if(document.getElementById('name').value.length === 0){
                alert('Name 필드의 값이 누락되었습니다!!');
                event.preventDefault();
            }
        });
    </script>
</body>
</html>

change : 폼 컨트롤의 값이 변경되었을 때 발생하는 이벤트.

텍스트 입력하고 enter누르면 값이 변경됨.

<!DOCTYPE html>
<html>
<body>
    <p id="result">입력</p>
    <input id="target" type="name" />

    <script>
        var t = document.getElementById('target');
        t.addEventListener('change', function(event){
            document.getElementById('result').innerHTML=event.target.value;
        });
    </script>
</body>
</html>

focus : 입력창이 포커스 받을 경우 작동
blur : 입력창 포커스를 잃으면 작동

입력창을 클릭하면 focus, 다른 곳을 클릭하면 다시 원래대로 돌아오는 blur

<!DOCTYPE html>
<html>
<body>
    <p id="result">입력</p>
    <input id="target" type="name" />

    <script>
        var t = document.getElementById('target');
        t.addEventListener('blur', function(event){
            alert('blur');
        });

        t.addEventListener('blur', function(event){
            alert('focus');
        });
    </script>
</body>
</html>





📖 문서 로딩






📖 마우스






📖jQuery 이벤트






📖 on API 사용법

profile
일상의 인연에 감사하라. 기적은 의외로 가까운 곳에 있을지도 모른다.

0개의 댓글