Day15 __ JavaScripts-example-4

KSGMN·2023년 10월 20일
0

JavaScripts-Examples

목록 보기
4/6

📒 Examples

📌 Carousel(캐러셀)

  • 옆으로 넘기는 컨테이너

터치이벤트 확인할때는 모바일 개발자도구로 확인

  • touchstart : 터치 시작 이벤트
  • touchmove : 터치 중 이벤트
  • touchend : 터치 끝 이벤트
  • 터치 시작, 중일때의 x좌표로 효과준다.
  • 손가락따라 움직이게 만들 때는 container.style.transform에 값 주기
<h1>Carousel</h1>

<style>
    /* frame */
    #frame{
        width : 200px;
        height: 200px;
        position: relative;
        overflow-x: hidden;
    }

    /* container and images */
    #container{
        display : flex;
        width : 600px;
        transition: transform 0.2s;
    }

    .image{
        width : 200px;
        height : 200px;
        font-size : 2rem;
        background-image: linear-gradient(to right, #333, #222);
        display : flex;
        justify-content: center;
        align-items: center;
        color : #fff;
    }

    /* button */
    #prev, #next{
        position : absolute;
        top : 0;
        height: 100%;
        background-color: transparent;
        border : none; font-size: 2rem;
        color : rgba(255 255 255 / 0.5);
        cursor: pointer;
    }

    #prev{
        left : 0;
    }
    #next{
        right : 0;
    }

    /* indicator */
    .indicator{
        position: absolute;
        bottom : 12px;
        width : 100%; display: flex; justify-content: center;
    }

    .dot{
        display : block;
        width : 8px; height : 8px;
        background-color: #fff;
        border-radius: 99px;
        margin : 0 2px; opacity : 0.5;
    }

    /* toggle class */
    .hidden{
        display : none;
    }
    
    .active{
        opacity : 1;
    }
</style>


<div id="frame">
    <div id="container">
        <div class="image">1</div>
        <div class="image">2</div>
        <div class="image">3</div>
    </div>

    <button id="prev" class="hidden" onclick="turnover(-1)">&#10094;</button>
    <button id="next" onclick="turnover(1)">&#10095;</button>

    <div class="indicator">
        <span class="dot active"></span>
        <span class="dot"></span>
        <span class="dot"></span>
    </div>
</div>


<script>
    // container and images
    var frame = document.getElementById("frame");
    var container = document.getElementById("container");
    var images = document.getElementsByClassName("image");
    var imageWidth = 200;

    // buttons
    var prev = document.getElementById("prev");
    var next = document.getElementById("next");
    // indicator
    var dots = document.getElementsByClassName("dot");
    // index and left
    var index = 0;
    var firstIndex = 0;
    var lastIndex = images.length - 1 ;
    var previousIndex = 0;
    var left = 0;
    // 터치 관련 변수
    var x1, x2 = 0;
    var turnoverPoint = 50;

    function turnover(data){
        index += data;
        console.log(index);
        left = -(index * imageWidth);

        console.log(left);

        // 다음 이미지로 이동
        container.style.transform = `translate(${left}px)`;

        // 이전버튼
        if(index === firstIndex){ // 첫번째 이미지인 경우
            prev.classList.add('hidden');
        }else{
            prev.classList.remove('hidden');
        }
        // 다음버튼 
        if(index === lastIndex){ // 마지막 이미지인 경우
            next.classList.add('hidden');
        }else{
            next.classList.remove('hidden');
        }


        // indicator
        dots[previousIndex].classList.remove('active');
        dots[index].classList.add('active');
        previousIndex = index;
    }

    // 터치 이벤트

    // touchstart : 터치 시작 이벤트
    frame.addEventListener("touchstart", touchStartHandler);
    // touchmove : 터치 중 이벤트
    frame.addEventListener("touchmove", touchMoveHandler);
    // touchend : 터치 끝 이벤트
    frame.addEventListener("touchend", touchEndHandler);

    function touchStartHandler(e){
        console.log("터치 시작")

        // 터치 시작지점의 x좌표
        x1 = e.touches[0].clientX;
    };

    function touchMoveHandler(e){
        console.log("터치 중")

        // 터치 중인 지점의 x좌표
        x2 = e.touches[0].clientX;

        console.log(x2 - x1);

        // 오른쪽으로 움직이는지 확인
        var movingToright = x2 - x1 > 0;

        // 왼쪽으로 움직이는지 확인
        var movingToleft = x2 - x1 < 0;
        
        // 첫번째 사진일 때 오른쪽으로 움직일 수 없게 한다.
        if(index === firstIndex && movingToright) return;
        // 마지막 사진일 때 왼쪽으로 움직일 수 없게 한다.
        if(index === lastIndex && movingToleft) return;

        // 손가락 따라 움직이게 만든다.
        container.style.transform = `translateX(${left + (x2 - x1)}px)`;
    };

    function touchEndHandler(){
        console.log("터치 끝")

        // 터치 무브 이벤트가 발생하지 않은 경우(드래그 안했을 때)
        if(!x2) return;

        // 다음 이미지로 이동하기 위해 충분히 당겼을 때
        var drawEnoughToNext = -(x2 - x1) > turnoverPoint;
        // 이전 이미지로 이동하기 위해 충분히 당겼을 때
        var drawEnoughToPrev = (x2 - x1) > turnoverPoint;

        // 이전 이미지로 이동
        if(index > firstIndex && drawEnoughToPrev){
            turnover(-1)
        }
        // 다음 이미지로 이동
        if(index < lastIndex && drawEnoughToNext){
            turnover(1)
        }

        // 충분히 움직이지 않은 경우 원래의 이미지로 돌아온다.
        container.style.transform = `translateX(${left}px)`;

        // 터치중인 지점의 x좌표(x2)를 초기화 한다.
        x2 = 0;
    };

</script>


📌 실시간 유효성 검사

  • "keyup"이벤트 : 키에서 손을 땠을 때 (input칸에 한 글자 입력했을 때로 알고있자)`
  • 정규식(Regular expression) : 문자열을 검색하기 위한 패턴
    var lowerCaseLetters = /[a-z]/ : a~z까지의 소문자
  • .match() : 문자열 매치 메서드

코드 : "keyup"이벤트이기 때문에 input값에 입력할때마다 입력값이 대문자인지 소문자인지 숫자인지 8글자가 넘었는지 try-catch안의 if문으로 검사하고 아닐시 throw로 지정한 오류메시지를 던져서 message에 .innerHTML로 문자열값 저장한뒤 catch에서 출력.

<style>
    label{
        display : block;
        margin-bottom : 0.25rem;
    }

    #input{
        width: 20rem;
        box-sizing: border-box;
        padding: 0.5rem;
    }

    .success{
        color : #0a0;
    }

    .warning{
        color : #f00;
    }
</style>


<label for="input">Password</label>
<input type="password" id="input">

<p id="message"></p>


<script>
    var input = document.getElementById("input");
    var message = document.getElementById("message");

    // keyup 이벤트 : 키에서 손을 뗐을 때
    input.addEventListener("keyup", function(){
        try{
            var password = this.value;

            console.log(password);

            /*
                정규식(Regular expression)
                문자열을 검색하기 위한 패턴

                * 사용방법
                /패턴/
            */

            var lowerCaseLetters = /[a-z]/
            var upperCaseLetters = /[A-Z]/
            var numbers = /[0-9]/

            if(!password){
                throw "비밀번호는 필수입니다.";
            }

            if(!password.match(lowerCaseLetters)){
                throw "비밀번호는 최소 한개 이상의 알파벳 소문자를 포합해야 합니다";
            }
            
            if(!password.match(upperCaseLetters)){
                throw "비밀번호는 최소 한개 이상의 알파벳 대문자를 포합해야 합니다";
            }

            if(!password.match(numbers)){
                throw "비밀번호는 숫자를 포함해야 합니다.";
            }

            if(password.length < 8){
                throw "비밀번호는 8글자 이상이어야 합니다.";
            }

            console.log("사용가능한 비밀번호입니다.");

            message.innerHTML = `<span class="success">사용가능합니다.</span>`

        }catch(error){
            message.innerHTML = `<span class="warning">${error}</span>`;
            console.error(error);
        }
    })
</script>


📌 Q. 실시간 검색

  • indexOf() 메서드는 문자열에서 값이 처음 나타나는 위치를 반환하는데 값을 찾을 수 없으면 -1을 반환한다.

코드 :

  • 내가 입력한 값을 var q = this.value;로 q로 받는다. 그리고 list 요소들의 문자열을 itemName에 넣고 q와 비교하여 있는지 찾는다. 비교하여 없으면 hidden으로 없애고 있다면 hidden삭제하여 유지(애초에 없지만 삭제).
  • 그 후 대문자 소문자 상관없이 찾고싶기 때문에 q와 itemName에 .toLowerCase()붙여주면서 둘다 소문자로 변환한다.
<style>
    #input{
        width : 400px; padding : 0.5rem;
        box-sizing: border-box;
        font-size: 1rem;
    }

    ul{
        list-style: none;
        padding: 0; margin: 0;
    }

    .item{
        padding : 0.5rem;
    }

    .hidden{
        display: none;
    }
</style>

<input type="text" name="" id="input" placeholder="Search">

<ul>
    <li class="item">Guiness</li>
    <li class="item">Heineken</li>
    <li class="item">Budwiser</li>
    <li class="item">Kloud</li>
    <li class="item">Asahi</li>
</ul>


<script>
    var input = document.getElementById("input");
    var items = document.getElementsByClassName("item");

    input.addEventListener("keyup", function(){
        // 검색어에 접근 뒤 소문자로 변환
        var q = this.value.toLowerCase();

        console.log("검색어 : ", q);

        for(var i=0; i<items.length; i++){

            // 아이템에 접근 뒤 소문자로 변환
            var itemName = items[i].textContent.toLowerCase();

            if(itemName.indexOf(q) > -1){ // 아이템이 검색어를 포함한 경우
                items[i].classList.remove("hidden");
            }else{ // 검색어를 포함하지 않은 경우
                items[i].classList.add("hidden");
            }
        }
    })

</script>


📌 Newsletter

  • "submit" : 폼 제출 이벤트
  • e.preventDefault(); : 이벤트의 기본값을 실행하지 않는다.
  • form.elements[접근할 input의 name] : name으로 form에 속한 input에 접근할 수 있다.
  • .trim() : 빈칸(공백)없이 텍스트를 붙인다.

코드 :

  • server가 없기 때문에 e.preventDefault();로 오류 막는다.
  • var email = form.elements["email"].value;로 name="email"을 가진 form의 input값을 받고 그 값을 .trim()으로 공백없이 만든다.
  • if(!email.trim()) : 공백이라면 error에 "이메일을 입력하세요" 문자열입력. 값 있다면 form숨기고 감사메시지 띄운다.
<Style>
    .container{
        display: flex;
    }

    input{
        padding : 0.5rem;
        flex-grow: 1;
    }

    .warning{
        color : #f00;
    }

    .hidden{
        display : none;
    }
</Style>
<form action="/server" id="form">
    <div class="container">
        <input type="text" name="email" placeholder="JohnDoe@example.com">
        <button class="btn">Subscribe</button>
    </div>
    <p id="error" class="warning"></p>
</form>

<p id="done" class="hidden">
    Thank you for subscribing us!
</p>

<script>
    var form = document.getElementById("form");
    var done = document.getElementById("done");
    var error = document.getElementById("error");

    // submit : 폼 제출 이벤트
    form.addEventListener("submit",function(e){
        // 이벤트의 기본값을 실행하지 않는다.
        e.preventDefault();
        // console.log("폼 제출 방지됨")

        // form.elements[접근할 input의 name]
        // name으로 form에 속한 input에 접근할 수 있다.
        var email = form.elements["email"].value;

        if(!email.trim()) {
            error.textContent = "이메일을 입력하세요";
            return;
        }
 
        // AJAX 요청..
        // 새로고침 없이 서버에 요청하는 기술

        // 폼을 숨긴다.
        form.classList.add("hidden");
        // 땡큐메시지를 사용자에게 보여준다.
        done.classList.remove("hidden");
    })
</script>


profile
ming

0개의 댓글