-
[js] 함수/ 이벤트html, css, js 2023. 2. 22. 01:07
함수 알아보기
함수란? 여러 동작을 묶은덩어리이다.
js프로그램은 단순히 동작 하나로 실행되는것이아닌, 여러 동작이 연결된다. 이렇게 동작해야 할 목적대로 묶은 명령을 함수라고한다.
예로 이전 게시물에 사용했던, alert()문은 괄호안에 내용을 입력하면 웹 브라우저에 알림창을 표시하는 함수이다.
함수 선언 및 호출
함수 선언
function 함수명() { 명령 }
웹 브라우저에서 자바스크립트 소스를 해석할때는 함수 선언 부분을 가장 먼저 해석한다. 따라서 개발자가 어디든 아무곳에나 함수를 선언해놓기만 하면 선언한 위치와 상관없이 함수를 호출할수있다. 함수선언 위치는 프로그램 흐름에 영향을 주지 않는다. 보통 스크립트 소스의 앞부분이나 뒷부분에 함수 선언 부분을 모아 놓고 필요할때마다 함수를 호출해서 사용한다.
함수 호출
함수명() 또는 함수명(변수)
var 예약어를 사용한 변수의 특징
- 자바스크립트에서 변수를 선언하고 선용할때 변수가 적용되는 범위를 스코프라고 한다.
- var예약어는 함수범위(지역변수, 전역변수 개념)의 스코프를 갖는다.
- 한 함수 안에서만 사용할 수 있는 변수를 지역변수(로컬변수), 스크립트 소스 전체에서 사용할 수 있는 변수를 전역변수(글로벌변수)라고 한다.
1. 함수범위의 스코프를 가짐
지역 변수
- var예약어를 사용한다.
- 지역 변수는 함수 안에서만 선언하고, 사용 가능하다.
전역 변수
- var예약어를 빼고 선언한다.
- 적용 범위를 제한하지 않고 쓸 수 있다.
function addNumber(){ var num = 30; //지역변수 multi = 100; //전역변수 } console.log(num);// 오류발생! 지역변수는 함수내에서만 사용 가능 console.log(100);// 출력!
2. 호이스팅
호이스팅이란 '끌어올린다'를 뜻한다. 상황에 따라 변수의 선언과 할당을 분리해서 선언 부분을 스코프의 가장 위쪽으로 끌어올리는것이다. 끌어올린다고 해서 실제로 소스 코드를 끌어올리는것은 아니고 그런 식으로 해석한다는 의미이다.
예를들어 실제 코드가 이렇다고 가정해보자
var x =10; function displayNumber() { console.log(x) console.log(y) var y = 20; } displayNumber()
var예약어를 쓰는 자바스크립트는 이렇게 호이스팅한다,
var x =10; function displayNumber() { var y; console.log(x) console.log(y) y = 20; } displayNumber()
그래서 실제로 함수를 실행해보면 x = 10, y는 선언하지 않았는데도 undefined로 출력된다.
3. 재선언과 재할당
var를 사용한 변수는 이전 코드에서 사용한 변수를 기억하지 못하고, 다시 재선언할 수 있다.
예시로 알아보자
<script> function addNumber(num1, num2) { return num1 + num2; } var sum = addNumber(10, 20); console.log(sum); //30출력 sum = 50; //재할당 console.log(sum); //50출력 var sum = 100; //재선언! console.log(sum); //100출력 </script>
var예약어는 함수 영역의 스코프를 가지고, 재할당과 재선언을 할 수 있다. 그래서 자칫 잘못사용하면 예상치 못한 오류를 발생시킬수있다. 그래서 ES6부터는 var을 보완한 let, const예약어가 등장한다.
let예약어를 사용한 변수의 특징
1. 함수 영역의 스코프가 아닌 블록 영역의 스코프를 갖는다.
let예약어로 선언한 변수는 변수를 선언한 블록({ } 로 묶은 부분) 에서만 유효하고 블록을 벗어나면 사용할 수 없다.
<script> function calcSum(n) { let sum = 0; for(let i = 1; i < n + 1; i++) { sum += i; // 반복문에서만 i 유효함 } console.log(sum); //함수 내에서만 sum 유효함, 55출력 } calcSum(10); </script>
만약 전역 변수로 선언하고 싶다면 let 예약어를 쓰지 않고 변수이름만으로 선언하면된다.
2. 재할당은 가능, 재선언은 불가능
let예약어로 선언한 변수는 재할당은 가능하지만, 재선언은 불가능하다. 그러니 var예약어 처럼 같은 변수의 이름을 사용할 걱정이 없다.
3. 호이스팅이 없음
var예약어를 사용한 변수는 선언하기 전에 실행하더라도 undefined라는 값을 가질수있다. (호이스팅)
하지만 let예약어를 사용하는 변수를 선언하기 전에 사용할 경우 오류메세지가 나타난다.
const예약어를 사용한 변수의 특징
- 상수변수이다. 상수는 프로그램 내에서 변하지 않는 값이다.
- const로 할당한 변수는 재선언하거나 재할당할수없으며, 블록레벨의 스코프를 갖는다.
- 값이 자주 바뀌는 변수라면 let예약어를, 재할당이 없는 변수라면 const예약어를 사용하는것이 좋다.
자바스크립트 변수 사용 가이드
1. 전역 변수는 최소한으로 사용한다.
2. var 변수는 함수의 시작 부분에서 선언한다. ->호이스팅 방지
3. for문에서 바로 카운터 변수를 사용할떄는 var변수를 사용하지 않는다. -> for( var i= 1; ..)라고 선언한다고 i가 블록변수가 되는것은 아님, 블록 밖에서 선언하거나, let으로 선언하는것이 좋음
4. var보다는 let을 사용하는것이 좋다.
재사용할 수 있는 함수 만들기
함수는 입력을 바꿀떄 마다 그에 맞게 여러번 사용할 수 있는 재사용성이라는 성질을 갖는다. 그리고 이런 재사용성을 지닌 함수를 만들어야한다.
매개변수, 인수, return
함수를 재사용 하게 하기 위해서는 매개변수를 사용하여 함수를 선언해야한다.
매개변수는 선언된 함수 내에서만 사용가능하며, 매개변수를 여러 개 사용할때는 매개변수 이름 사이에 쉼표를 찍어 나열한다.
fuction addNumber(num1, num2){ //num1, num2 매개변수 return num1 + num2; //결과값을 함수를 실행한 위치로 돌려보내주는 return예약어 } var result = addNumber(2,3); //2 ,3 인수
매개변수 기본값 정하기
매개변수 인수값을 넘겨받지 못했을때, 기본적으로 사용하는 값이다.
function multiple(a, b=5, c=10){ //b=5, c=10 매개변수 기본값 return a+b+c; } multiple(5,10,20) //35 multiple(10,20) // 10 + 20+ 10(기본값) = 40
1부터 n까지 숫자를 더하는 함수
<script> function calcSum(n){ let sum =0; let i; for(i=1;i<= n;i++){ sum += i; } document.write(sum); } var userNumber = prompt("얼마까지 더할까요?"); if(userNumber !== null){ calcSum(parseInt(userNumber)); } </script>
함수 표현식
익명 함수
이름이 없는 함수를 말한다.
함수 자체가 식이므로 함수를 변수에 할당할 수도있고, 다른 함수의 매개변수로도 사용할수있다.
var sum = function(a,b) { //이름이없는 익명 함수를 sum변수에 할당하는 모습 return a+b; } document.write(sum(10,20)) // 익명함수 실행
즉시 실행 함수
일반적으로 함수는 선언하고 필요할때마다 호출해서 실행하는 방법을 많이 사용하는데, 한번만 실행하는 함수라면 함수를 정의하면서 동시에 실행할 수 있다.
(function() { 명령 }()); 또는 (function(매개변수) { 명령 }(인수));
사용자에게 이름을 받아 인사말을 표시하는 함수이다. 따로 호출하지 않았지만 바로 실행된다.
<script> (funtion() { var userName = prompt("이름을 입력하세요."); document.write("안녕하세요? <span class='accent'>" +userName + "</span>님!"); }()); </script>
화살표 함수
익명 함수에서만 사용할수 있다.
(매개변수) => {함수 내용}
//매개변수가 없는 경우 익명함수 const hi = function(){ return "안녕하세요" } //화살표함수로 표현 const hi = () => {"안녕하세요"}; const hi = () => "안녕하세요"; //함수 내용이 한줄뿐이라면 중괄호 생략 가능 //매개변수가 1개인 경우 익명함수 let hi = function(user){ document.write(user + "님 , 안녕하세요?"); } //화살표함수로 표현 let hi = user => {document.write(user + "님, 안녕하세요?); } //매개변수가 2개인 경우 익명함수 let sum = function(a,b){ return a+b; } //화살표함수로 표현 let sum = (a,b) => a+b;
이벤트와 이벤트 처리기
메인 메뉴를 클릭하면 서브메뉴가 자연스럽게 펼쳐지는 것은 기본이고, 페이지 로딩이 끝나면 배경 화면이 움직이기도 하는 효과 들을 이벤트개념이 도입되면서 구현된것이다.
- 이벤트는 웹 브라우저나 사용자가 행하는 어떤 동작을 말한다.
- 웹 문서 영역 안에서 이루어지는 동작만을 말하며, 웹 문서 영역을 벗어나는 클릭이나 행위는 이벤트가 아니다.
- 주로 마우스나 키보드를 사용할때, 웹 문서를 불러올때, 폼에 내용을 입력할때 발생한다.
마우스 이벤트
click 사용자가 HTML요소를 클릭할때 dblclick 사용자가 HTML요소를 더블 클릭할떄 mousedown 사용자가 요소 위에서 마우스 버튼을 눌렀을때 mousemove 사용자가 요소 위에서 마우스 포인터를 움직일때 mouseover 마우스 포인터가 요소 위로 옮겨질때 mouseout 마우스 포인터가 요소를 벗어날때 mouseup 사용자가 요소 위에 놓인 마우스 버튼에서 손을 뗄 때
키보드 이벤트
keydown 사용자가 키를 누르는 동안 keypress 사용자가 키를 눌렀을 때 keyup 사용자가 키에서 손을 뗄 때
문서 로딩 이벤트
abort 문서가 완전히 로딩되기 전에 블러오기를 멈췄을때 error 문서자 정확히 로딩되지 않았을떄 load 문서 로딩이 끝나면 resize 문서 화면 크기가 바뀌었을때 scroll 문서 화면이 스크롤되었을때 unload 문서에서 벗어날때
폼이벤트
폼은 로그인, 검색, 게시판, 설문 조사 처럼 사용자가 입력하는 모든 요소를 가르킨다.
blur 폼요소에 포커스를 잃었을 때 change 목록이나 체크 상태 등이 변경될때 <input> , <select>, <textarea>에서 사용 focus 폼 요소에 포커스가 놓였을때 <label>, <select>, <textarea>,<button> 에서 사용 reset 폼이 리셋되었을떄 submit submit버튼을 클릭했을때
이벤트 처리기
- 이벤트가 발생하면 처리하는 함수를 이벤트 처리기라고 한다.
- 예를들어 이미지를 클릭하면 크게 바꿔주는 이벤트가 있다고 할때, 작은 이미지 클릭(이벤트) -> 큰 이미지 표시(이벤트 처리기)
- 이벤트를 처리하는 가장 기본적인 방법은 이벤트가 발생한 HTML 태그에 이벤트 처리기를 연결하는 것이다.
<태그 on이벤트명 = "함수명">
다음은 목록에서 각 버튼을 클릭하면 알림 창을 표시하는 예제이다. 마우스로 클릭했을때의 이벤트 이름은 click이다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>자바스크립트 이벤트</title> <link rel="stylesheet" href="css/function.css"> </head> <body> <ul> <li><a href="#" onclick="alert('버튼을 클릭했습니다.')">Green</a></li> <li><a href="#" onclick="alert('버튼을 클릭했습니다.')">Orange</a></li> <li><a href="#" onclick="alert('버튼을 클릭했습니다.')">Purple</a></li> </ul> <div id="result"></div> </body> </html>
이벤트 발생 후 여러가지 명령을 실행해야한다면, 그 명령을 묶어 하나의 자바스크립트 함수로 만드는 것이 좋다.
다음은 웹 요소의 배경색을 바꾸는 changeBt(color)함수를 미리 만들어서 실행하는 예제이다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>자바스크립트 이벤트</title> <link rel="stylesheet" href="./structure.css"> </head> <body> <ul> <li><a href="#" onclick="changeBg('green')">Green</a></li> <li><a href="#" onclick="changeBg('orange')">Orange</a></li> <li><a href="#" onclick="changeBg('purple')">Purple</a></li> </ul> <div id="result"></div> <script> function changeBg(color) { var result = document.querySelector('#result'); result.style.backgroundColor = color; } </script> </body> </html>
a:link, a:visited { color:black; text-decoration: none; } ul { list-style: none; width:500px; margin:10px auto; padding:0; } li { display:inline-block; width:120px; border:1px solid #ccc; padding:10px 15px; font-size:16px; text-align:center; } #result { width:500px; height:300px; margin:30px auto; border:2px solid #ccc; border-radius:15px; } p { width:80%; padding:10px; line-height: 2em; }
버튼을 클릭해서 상세 설명 표시하거나 닫기
[상세설명보기]버튼을 클릭하면 상세 설명 글을 표시하고, [ 상세 설명 닫기] 버튼을 클릭하면 표시된 설명 글을 사라지게 하는 프로그램
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>자바스크립트 이벤트</title> <link rel="stylesheet" href="./structure.css"> </head> <body> <div id="item"> <img src="./apple.png" alt=""> <button class="over" id="open" onclick="showDetail()">상세 설명 보기</button> <!-- 상세 설명 보기 단추--> <div id="desc" class="detail"> <!-- 상세 설명 부분 --> <h4>등심붓꽃</h4> <p>북아메리카 원산으로 각지에서 관상초로 흔히 심고 있는 귀화식물이다. 길가나 잔디밭에서 흔히 볼 수 있다. 아주 작은 씨앗을 무수히 많이 가지고 있는데 바람을 이용해 씨앗들을 날려보내거나, 뿌리줄기를 통해 동일한 개체들을 많이 만들어 냄으로써 번식한다. </p> <button id="close" onclick="hideDetail()">상세 설명 닫기</button> <!-- 상세 설명 닫기 단추 --> </div> </div> <script> function showDetail() { document.querySelector('#desc').style.display = "block"; // 상세 설명 부분을 화면에 표시 document.querySelector('#open').style.display = "none"; // '상세 설명 보기' 단추를 화면에서 감춤 } function hideDetail() { document.querySelector('#desc').style.display = "none"; // 상세 설명 부분을 화면에서 감춤 document.querySelector('#open').style.display = "block"; // '상세 설명 보기' 단추를 화면에 표시 } </script> </body> </html>
#item { position:relative; width:500px; height:auto; padding:15px 20px; margin:auto; } button { background-color:rgba(255,255,255,0.7);; padding:5px; border:1px solid #ccc; font-size:0.8em; } .over { position:absolute; left:30px; bottom:30px; } .detail { width:400px; text-align:left; line-height:1.8; display:none; }
DOM을 이용한 이벤트 처리기
지금까지 이벤트 처리기를 지정하는 방법은 HTML이 주인이 되어 자바스크립트 함수를 불러와서 사용했다. 즉 HTML 코드안에 js 코드가 들어가는 형태이다.
하지만 DOM을 사용하면 자바스크립트가 주인이 되어 HTML 요소를 가져와서 이벤트 처리기를 연결한다. HTML코드와 js 코드를 분리할수있다.
웹 요소를 클릭했을때 실행할 함수를 연결하려면 다음과 같이
웹 요소.onclick = 함수;
querySelector() : 자바 스크립트에서 웹 요소를 가져오는 방법이다. 괄호 안에는 클래스 이름이나 id이름 또는 다양한 선택자를 넣을 수 있다.
다음은 id="change"인 버튼을 클릭했을때 글자색을 바꾸는 예제이다.
- quearSelector를 통해 버튼 요소를 가져오고 변수 changeBttn에 저장한다.
- 그리고 changBttn에 onclick을 사용해 changeColor()함수를 연결한다.
- 이떄 주의할 점은 함수의 이름만 사용하고 괄호는 붙이지 않는다.
<body> <button id="change">글자색 바꾸기</button> <p>Reprehenderit tempor do quis sunt eu et exercitation deserunt. Laboris adipisicing est sint aliquip nulla pariatur velit irure elit qui id. Dolore aliquip dolore eu ut irure sint Lorem reprehenderit velit. Duis veniam irure cillum anim excepteur culpa pariatur sunt esse. Eu nulla commodo velit ex id dolore incididunt mollit incididunt nisi labore culpa qui ea. Commodo veniam veniam in ipsum ad minim occaecat qui pariatur adipisicing laborum quis.</p> <script> // 방법 1 : 웹 요소를 변수로 지정 & 미리 만든 함수 사용 var changeBttn = document.querySelector("#change"); changeBttn.onclick = changeColor; function changeColor() { document.querySelector("p").style.color = "#f00"; } </script>
웹 요소를 프로그램 안에서 여러번 사용하지 않는다면 다음과 같이 변수에 할당하지 않고 직접 사용해도 된다.
// 방법 2 : 웹 요소를 따로 변수로 만들지 않고 사용 <script> document.querySelector("#change").onclick = changeColor; function changeColor() { document.querySelector("p").style.color = "#f00"; } </script>
함수를 딱 한번만 사용한다면 위 코드에서 changeColor라는 함수 이름이 들어갔던 자리에 직접 함수를 선언해도된다.
// 방법 3 : 직접 함수를 선언 <script> document.querySelector("#change").onclick = function() { document.querySelector("p").style.color = "#f00"; }; </script>
DOM 이벤트 처리 방식으로 '버튼을 클릭해서 상세 설명 표시하거나 닫기' 예제 수정해보았음.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>자바스크립트 이벤트</title> <link rel="stylesheet" href="css/event.css"> </head> <body> <div id="item"> <img src="images/flower.jpg" alt=""> <button class="over" id="open">상세 설명 보기</button> <div id="desc" class="detail"> <h4>등심붓꽃</h4> <p>북아메리카 원산으로 각지에서 관상초로 흔히 심고 있는 귀화식물이다. 길가나 잔디밭에서 흔히 볼 수 있다. 아주 작은 씨앗을 무수히 많이 가지고 있는데 바람을 이용해 씨앗들을 날려보내거나, 뿌리줄기를 통해 동일한 개체들을 많이 만들어 냄으로써 번식한다. </p> <button id="close">상세 설명 닫기</button> </div> </div> <script> document.querySelector('#open').onclick = function() { document.querySelector('#desc').style.display = "block"; // 상세 설명 부분을 화면에 표시 document.querySelector('#open').style.display = "none"; // '상세 설명 보기' 단추를 화면에서 감춤 } document.querySelector('#close').onclick = function() { document.querySelector('#desc').style.display = "none"; // 상세 설명 부분을 화면에서 감춤 document.querySelector('#open').style.display = "block"; // '상세 설명 보기' 단추를 화면에 표시 } </script> </body> </html>
마무리문제 1
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>자바스크립트 이벤트</title> <link rel="stylesheet" href="css/event.css"> </head> <body> <script> function sumMulti(x,y){ if(x === y){ console.log( x*y); }else console.log(x+y); } var x = parseInt(prompt("첫번째 값을 입력하세요")); var y = parseInt(prompt("두번째 값을 입력하세요")); sumMulti(x,y); </script> </body> </html>
마무리문제 2
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>자바스크립트 이벤트</title> <link rel="stylesheet" href="css/event.css"> </head> <body> <script> function compare_ab(x,y){ if(x !== y){ if(x > y){ alert(x+"가 더 큽니다."); } else{ alert(y+"가 더 큽니다."); } }else alert("같습니다."); } var num1 = parseInt(prompt("첫번째 값을 입력하세요")); var num2 = parseInt(prompt("두번째 값을 입력하세요")); compare_ab(num1,num2); </script> </body> </html>
참고 서적 http://easyspub.co.kr/20_Menu/BookView/PUB/421/PUB
'html, css, js' 카테고리의 다른 글
문서 객체 모델 (DOM) (0) 2023.03.01 [js] 객체, 프로퍼티, 메소드 (0) 2023.02.27 [js] 자바 스크립트 기본 문법(변수/ 자료형/연산자/조건문/반복문) (0) 2023.02.21 [js] 기본입출력, 스타일 가이드 (0) 2023.02.20 [js] js 사용방법 (0) 2023.02.20