비트교육센터/웹

[비트교육센터] 웹 28일차 Javascript, 마우스 핸들링, 윈도우와 브라우저 객체

달의요정루나 2023. 7. 7. 18:24

1. 마우스 핸들링

1) onclick과 ondblclick

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>onclick</title>
    <script>
        function calculate() {
            let exp = document.getElementById("exp");
            let result = document.getElementById("result");
            result.value = eval(exp.value);
        }
    </script>
</head>

<body>
    <h3> onclick, 계산기 만들기</h3>
    <hr>
    계산하고자 하는 수식을
    입력하고 계산 버튼을 눌러봐요.
    <br>
    <br>
    <form>
        식 <input type="text" id="exp" value=""><br>
        값 <input type="text" id="result">
        <input type="button" value=" 계산  " onclick="calculate()">
    </form>
</body>

</html>

- onclick: 사용자가 HTML 태그를 클릭했을때, ondbclick은 더블클릭했을때 실행하는 이벤트 리스너이다.

- 해당 코드는 계산 버튼을 누르면 입력받은 수식을 계산해 출력하는 간단한 계산기 페이지이다.

--> 결과

2) 마우스와 관련된 이벤트 리스너

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>마우스 관련 리스너</title>
    <script>
        let width = 1; // 테두리 두께
        function down(obj) {
            obj.style.fontStyle = "italic";
        }
        function up(obj) {
            obj.style.fontStyle = "normal";
        }
        function over(obj) {
            obj.style.borderColor = "violet";
            // 테두리 폭이 0일 때 색은 보이지 않는다.
        }
        function out(obj) {
            obj.style.borderColor = "lightgray";
        }
        function wheel(e, obj) { // e는 이벤트 객체
            if (e.wheelDelta < 0) { // 휠을 아래로 굴릴 때
                width--; // 폭 1 감소
                if (width < 0) width = 0; // 폭이 0보다 작아지지 않게
            }
            else // 휠을 위로 굴릴 때
                width++; // 폭 1 증가
            obj.style.borderStyle = "ridge";
            obj.style.borderWidth = width + "px";
        }
    </script>
</head>

<body>
    <h3>마우스 관련 이벤트 리스너</h3>
    <hr>
    <div>마우스 관련
        <span onmousedown="down(this)" onmouseup="up(this)" onmouseover="over(this)" onmouseout="out(this)"
            onwheel="wheel(event, this)" style="display:inline-block">이벤트
        </span>가 발생합니다.
    </div>
</body>

</html>

- onmousedown: HTML 태그에 마우스 버튼을 누르는 순간

- onmouseup: 눌러진 마우스 버튼이 놓여지는 순간

- onmouseover: 마우스가 HTML 태그 위로 올라오는 순간. 자식 영역 포함

- onmouseout: 마우스가 HTML 태그를 벗어나는 순간. 자식 영역 포함

- onmouseenter: 마우스가 HTML 태그 위로 올라오는 순간. 이벤트 버블 단계 없음

- onmouseleave: 마우스가 HTML 태그를 벗어나는 순간. 이벤트 버블 단계 없음

- onwheel: HTML 태그에 마우스 휠이 구르는 동안 계속호출

--> 결과

초기화면

- 마우스휠을 위로 굴릴때 두께가 두꺼워짐(onwheel), 마우스를 올릴때 violet 색이 나타난다.(onmouseover)

- 마우스를 내릴 때 회색으로 변한다.(onmouseout)

- 마우스로 눌렀을때 italic서체로 바뀐다.(onmousedown)

 

3) 마우스와 관련된 이벤트 리스너2

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>마우스 이벤트 객체의 프로퍼티</title>
    <style>
        div {
            background: skyblue;
            width: 250px;
        }
    </style>
</head>

<body>
    <h3>마우스 이벤트 객체의 프로퍼티와 onmousemove</h3>
    <hr>
    이미지 위에 마우스를 움직일 때 onmousemove 리스너가 실행되고,
    마우스의 위치를 보여줍니다.<br><br>
    <img src="media/beach.png" onmousemove="where(event)"><br><br>
    <div id="div"></div>
    <script>
        let div = document.getElementById("div");
        function where(e) {
            let text = "버튼=" + e.button + "<br>";
            text += "(screenX, screenY)=" + e.screenX + "," + e.screenY + "<br>";
            text += "(clientX, clientY)=" + e.clientX + "," + e.clientY + "<br>";
            text += "(offsetX, offsetY)=" + e.offsetX + "," + e.offsetY + "<br>";
            text += "(x, y)=" + e.x + "," + e.y + "\n";
            div.innerHTML = text;
        }
    </script>
</body>

</html>

- onmousemove리스너는 마우스가 움직이는 동안 계속 호출된다.

- 위의 코드는 <img>태그의 이미지 위에서 마우스를 움직이면 onmousemove리스너에서 마우스 포인터의 좌표를 <div>태그에 출력한다.

사진위에 마우스 포인터를 대면 좌표가 나타난다.

4) 마우스와 관련된 이벤트 리스너3

- oncontextmenu

1) 컨텍스트 메뉴(context menu)는 html 태그 위에 마우스 오른쪽 버튼을 클릭시 출력되는 메뉴이다.

2) 컨텍스트 메뉴가 출력되기 전 oncontextmenu 리스너가 먼저 호출된다.

3) 이 리스너가 false를 리턴시 컨텍스트 메뉴가 출력되는 디폴트 행동을 취소해 소스 보기나 이미지 다운로드를 할 수 없게 된다.

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>oncontextmenu</title>
    <script>
        function hideMenu() {
            alert("오른쪽 클릭<컨텍스트 메뉴>금지");
            return false;
        }
        document.oncontextmenu = hideMenu;
    </script>
</head>

<body>
    <h3>oncontextmenu에서 컨텍스트 메뉴 금지</h3>
    <hr>
    마우스 오른쪽 클릭은 금지됩니다. 아무곳이나
    클릭해도 컨텍스트 메뉴를 볼 수 없습니다.<br>
    <img src="media/beach2.png" alt="miami">
</body>

</html>

- document 객체의 oncontextmenu리스너에 hidemenu() 함수를 등록해 브라우저의 아무 위치에 마우스 오른쪽 버튼을 클릭해도 hidemenu()가 실행되게 한다. hidemenu()함수는 경고창을 출력하고 false를 리턴해 컨텍스트 메뉴가 출력되지 않도록 한다.

--> 결과

5) 라디오 버튼

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>선택된 라디오버튼 알아내기</title>
    <script>
        function findChecked() {
            let found = null;
            // let kcity = document.getElementsByName("city");
            // for (let i = 0; i < kcity.length; i++) {
            //     if (kcity[i].checked == true)
            //         found = kcity[i];
            // }
            let kcity = document.querySelectorAll('[name="city"]');
            for (let city of kcity) {
                if (city.checked == true) {
                    found=city
                }
            }
            if (found != null)
                alert(found.value + "이 선택되었음");
            else
                alert("선택된 것이 없음");
        }
    </script>
</head>

<body>
    <h3>버튼을 클릭하면 선택된 라디오 버튼의 value를 출력합니다.</h3>
    <hr>
    <form>
        <input type="radio" name="city" value="seoul" checked>서울
        <input type="radio" name="city" value="busan">부산
        <input type="radio" name="city" value="chunchen">춘천
        <input type="button" value="find checked" onclick="findChecked()">
    </form>
</body>

</html>

- 태그의 name 속성이 동일한 radio 객체들이 하나의 그룹을 이루기 때문에 name 속성 값으로 radio 객체를 찾는 것이다.

--> 결과

초기화면
라디오 버튼 중 하나를 클릭하고 find checked를 누르면 위 사진처럼 출력된다.

6) 체크박스

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>선택된 물품 계산하기</title>
    <script>
        let sum = 0;
        function calc(cBox) {
            if (cBox.checked)
                sum += parseInt(cBox.value);
            else
                sum -= parseInt(cBox.value);
            document.getElementById("sumtext").value = sum;
        }
    </script>
</head>

<body>
    <h3>물품을 선택하면 금액이 자동 계산됩니다</h3>
    <hr>
    <form>
        <input type="checkbox" name="hap" value="10000" onclick="calc(this)">모자 1만원
        <input type="checkbox" name="shose" value="30000" onclick="calc(this)">구두 3만원
        <input type="checkbox" name="bag" value="80000" onclick="calc(this)">명품가방 8만원<br>
        지불하실 금액 <input type="text" id="sumtext" value="0">
    </form>
</body>

</html>

- checkbox 객체들은 radio객체들과 달리 그룹을 형성하지 않기 때문에 name 속성(프로퍼티)이 모두 다르다.

- 위의 코드는 구입 물품을 나타내는 3개의 체크박스를 두고, 체크박스를 선택시 바로 물품 전체 가격을 계산하는 사례를 보여준다.

--> 결과

체크박스를 클릭시 해당금액이 더해진다.

7) Select 객체와 onchange

- select 객체는 <select>태그에 의해 만들어진 콤보박스를 나타내며, option 개체는 <option>태그로 표현되는 옵션 아이템을 나타낸다.

- selectedIndex: 선택된 옵션은 select 객체의 selectedIndex로 알아낼 수 있다.

- onchange 리스너: select객체에 다른 옵션이 선택되면 select 객체의 onchange 리스너가 호출된다. 

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>select 객체에서 선택한 과일출력</title>
    <script>
        function drawImage() {
            let sel = document.getElementById("fruits");
            let img = document.getElementById("fruitimage");
            console.log(sel.selectedIndex);
            img.src = sel.options[sel.selectedIndex].value;
        }
    </script>
</head>

<body onload="drawImage()">
    <h3>select 객체에서 선택한 과일 출력</h3>
    <hr>
    과일을 선택하면 이미지가 출력됩니다.<p>
    <form>
        <select id="fruits" onchange="drawImage()">
            <option value="media/strawberry.png">딸기
            <option value="media/banana.png" selected>바나나
            <option value="media/apple.png">사과
        </select>
        <img id="fruitimage" src="media/banana.gif" alt="">
    </form>
</body>

</html>

- onchange리스너를 이용해 <select>태그에서 옵션을 선택할 때마다 해당 이미지를 출력하게 한다.

- <body> 태그에 onload="drawImage()"를 작성하는 이유는 웹 페이지가 로드된 직후 처음부터 <select>태그에 작성된 <option> 중 선택상태(selected) 인 것을 찾아 그 이미지를 출력하기 위함이다.

--> 결과

select태그에서 선택하는 option에 따라 사진이 변한다.

8) 상하좌우 키로 셀 이동

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>키 이벤트 응용</title>
    <style>
        td {
            width: 50px;
            height: 50px;
            border: 1px solid orchid;
        }
    </style>
    <script>
        let tds;
        let prevIndex = 0, index = 0;
        window.onload = function () { // 웹 페이지의 로딩 완료시 실행
            tds = document.getElementsByTagName("td");
            tds[index].style.backgroundColor = "orchid";
        }
        window.onkeydown = function (e) {
            switch (e.key) {
                case "ArrowDown":
                    if (index / 3 >= 2) return; // 맨 위 셀의 경우
                    index += 3;
                    break;
                case "ArrowUp":
                    if (index / 3 < 1) return; // 맨 아래 셀의 경우
                    index -= 3;
                    break;
                case "ArrowLeft":
                    if (index % 3 == 0) return; // 맨 왼쪽 셀의 경우
                    index--;
                    break;
                case "ArrowRight":
                    if (index % 3 == 2) return; // 맨 오른쪽 셀의 경우
                    index++;
                    break;
            }
            tds[index].style.backgroundColor = "orchid";
            tds[prevIndex].style.backgroundColor = "white";
            prevIndex = index;
        }
    </script>
</head>

<body>
    <h3>상하좌우 키로 셀 이동하기</h3>
    <hr>
    <table>
        <tr>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </table>
</body>

</html>

- 3*3 표를 만들고 상하좌우 키를 이용해 셀의 배경색을 바꾸면서 표의 셀 사이를 이동하는 코드문이다.

--> 결과

키보드 화살표를 통해 이동할 수 있다.

2. 윈도우와 브라우저 객체

1) setInterval()로 텍스트 회전

- setInterval(): 타임아웃 시간 주기로 타임아웃 코드를 무한 반복 실행하도록 타이머를 설정한다.

- clearInterval(): setInterval()에 의해 설정된 타이머를 해제시킨다.

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>setInterval()로 텍스트 회전</title>
</head>

<body>
    <h3>텍스트가 자동 회전하며, 마우스로 클릭하면 중단합니다.</h3>
    <hr>
    <div><span id="span" style="background-color:yellow">
            자동 회전하는 텍스트입니다.</span>
    </div>
    <script>
        let span = document.getElementById("span");
        let timerID = setInterval("doRotate()", 200); // 200밀리초 주기로 doRotate() 호출

        span.onclick = function (e) { // 마우스 클릭 이벤트 리스너
            clearInterval(timerID); // 타이머 해제. 문자열 회전 중단
        }

        function doRotate() {
            let str = span.innerHTML;
            let firstChar = str.substr(0, 1);
            let remains = str.substr(1, str.length - 1);
            str = remains + firstChar;
            span.innerHTML = str; // str 텍스트를 span 객체에 출력
        }
    </script>
</body>

</html>

- setInterval()을 이용해 텍스트를 옆으로 반복회전하는 코드이다.

- 마우스를 클릭하면 회전이 중단된다.

--> 결과

2) 웹 페이지 프린트

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>웹 페이지 프린트</title>
</head>

<body>
    <h3>웹 페이지 프린트</h3>
    <hr>
    <p>window 객체의 print() 메소드를 호출하면
        window 객체에 담겨 있는 웹 페이지가 프린트 됩니다.
    <p>
        <a href="javascript:window.print()">이곳을 누르면 프린트 됩니다.</a>
    <p>
        <input type="button" value="프린트" onclick="window.print()">
</body>

</html>

- window.print(); 또는 print(); 코드는 현재 윈도우에 로드된 웹 페이지를 프린트한다.

--> 결과

초기화면
버튼이나 <a>태그를 클릭시 웹페이지 프린트가 나타난다.

3) onbeforeprint()와 onafterprint()

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>onbeforeprint와 onafterprint</title>
    <style>
        #logoDiv {
            display: none;
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            z-index: -1;
            /* 로고 이미지를 문서의 밑바닥에 배치 */
        }
    </style>
    <script>
        window.onbeforeprint = function (e) {
            let logoDiv = document.getElementById("logoDiv");
            logoDiv.style.display = "block"; // block으로 변경. 로고가 화면에 나타나게 함
        }
        window.onafterprint = hideLogo;
        function hideLogo() {
            let logoDiv = document.getElementById("logoDiv");
            logoDiv.style.display = "none"; // 로고를 보이지 않게 함
        } 
    </script>
</head>

<body>
    <h3>onbeforeprint, onafterprint 이벤트 예</h3>
    <hr>
    <div id="logoDiv">
        <img src="media/logo.png" alt="이미지 없습니다.">
    </div>
    <p>안녕하세요. 브라우저 윈도우에서는 보이지 않지만, 프린트시에는 회사 로고가 출력되는 예제를
        보입니다. 마우스 오른쪽 버튼을 눌러 인쇄 미리보기 메뉴를 선택해 보세요.</p>
</body>

</html>

- onbeforeprint리스너에서 회사 로고 이미지가 프린트 되게하고, 프린트가 끝나면 onafterprint 리스너에서 다시 이미지를 숨긴다.

--> 결과

초기화면
인쇄창을 띄었을때