250x250
Notice
Recent Posts
Recent Comments
«   2024/09   »
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 28
29 30
Tags more
Archives
Today
Total
관리 메뉴

개린이 개발노트

국비지원 JAVA(자바) 프로그래밍 본문

국비지원(국비교육) 웹 개발자 과정

국비지원 JAVA(자바) 프로그래밍

개린이9999 2022. 12. 29. 21:16
728x90

스크롤(scroll) 이벤트

회원가입  

약관

  <input id='chk' type="checkbox"><label>약관에 동의합니다</label>

위 코드일 때는 체크박스를 정확하게 체크해야만 체크가 되지만

  <input id='chk' type="checkbox"><label for="chk">약관에 동의합니다</label>

위 코드처럼 하면 글자만 눌러도 체크가 가능 

<label for="chk">
<input id='chk' type="checkbox" disabled>
 
 
 disable 하면 비활성화됨

    약관에 동의합니다 표시가 현재 너무 진함. check 박스가 표시 될떄 안될 때 마다 색깔을 다르게 변경해주고싶음

*따로 색깔을 바꿔버리면 체크 박스의 유무에 따라 글자색깔이 달라지지 않음 

  css에서

#chk:disabled + label {
  color: lightgray
}

위 코드처럼 바꿔줘야 가능 #(선택자)chk: disabled 

 


 회원약관을 다 읽어야만 약관에 동의합니다 라는 체크박스가 활성화 되게 하려면?

 1. 총높이== box창의 높이 + 이동거리

-> 오차범위가 생길수 있으므로 총높이-5<= box창의 높이 + 이동거리

 2. 총높이-box창의 높이 == 이동거리

-> 오차범위가 생길수 있으므로 총높이-box창의 높이-5 <= 이동거리

 

내용을 다 읽으면 -> alert('다읽음') 이라고 나타나게 만들기

let box = document.querySelector('.box');

let boxHeight = box.scrollHeight - box.clientHeight -5;

box.addEventListener('scroll', function() { 
  
  if(box.scrollTop >= boxHeight) {
	alert('다읽음');
    }
 });

 회원약관 만들기- SCOLL 기능 사용해서 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>회원약관만들기</title>
    <link rel="stylesheet" href="회원약관만들기.css">
</head>
<body>
  <div class="container">
    <div class="box">
      회원약관<br>
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Nam vel ullam sit iste repellendus quis dolorum tempore commodi itaque nisi! Consectetur, aliquam atque! Veritatis atque qui aut nesciunt rerum dignissimos?
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Nam vel ullam sit iste repellendus quis dolorum tempore commodi itaque nisi! Consectetur, aliquam atque! Veritatis atque qui aut nesciunt rerum dignissimos?
    </div>
    <input id="chk" type="checkbox" disabled><label for="chk">약관에 동의합니다.</label>
  </div>

    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.2.min.js" integrity="sha256-2krYZKh//PcchRtd+H+VyyQoZ/e3EcrkxhM8ycwASPA=" crossorigin="anonymous"></script>
    <script src="회원약관만들기.js"></script>
</body>
</html>

 

.box {
  border: 1px solid black;
  width: 200px;
  height: 200px;
  overflow: scroll;
  margin:auto;
}


.container {
text-align: center;
}

#chk:disabled + label {
  color: lightgray
}
let box = document.querySelector('.box');

//.scrollHeight 전체 영역안에 있는 총높이 확인 (내용에 따라 길이 달라짐)
// console.log(box.scrollHeight);

// .clientHeight 박스 내부 영역안에 있는 총높이 확인
// console.log(box.clientHeight);


let boxHeight = box.scrollHeight - box.clientHeight -5;

let isDisable = true;/*약관에 동의합니다가 비활성화중이다라는 것을 알리기위해*/


box.addEventListener('scroll', function() { 
  
  //.scrollTo 위에서 부터 아래까지 얼마나 스크롤을 했는지 보여준다.
  // console.log(box.scrollTop);

  //총높이 -5 <= box 창의 높이 + 이동거리
  //총높이 - 창의 높이 -5 <= 이동거리

  // == 이것보다는 오차범위를 염두에 둔다면 <= 이런 방식이 좋다.
  //환경에 따라서 오차가 존재하다 보니 여유값도 필요하다

  if(isDisable && (box.scrollTop >= boxHeight)) {

    // alert('다읽음'); 확인용

    document.querySelector('#chk').disabled = false;

    //한번 동작 후 false로 변경하면서 if문에서 isDisable이 만족을 못하여 한번만 실행된다.
    isDisable = false;
  }

});


프로그래스바 활용하기 

 

window.addEventListener('scroll', function(){

  console.log(window.scrollY);
});

콘솔로 스크롤 했을 때 값 알려줌, 몇픽셀 만큼 내려가는지

console.log(window.innerHeight);

윈도우(브라우저창)의 높이를  알려줌 

 

브라우저창의 높이를 구하고

웹페이지의 전체 높이를 구하고

스크롤 할 때마다 스크롤한 만큼의 높이(스크롤 할 때마다 바뀜)

-> 전체에서 스크롤을 얼마만큼 내린지 %로 계산할 수 있음 

 

막대기 너비가 스크롤 한만큼 늘어나야함 ( 처음 너비는0)

늘어나는 단위는 px보다 %단위로 하는 것이 좋음

 

스크롤 한만큼의 높이 / (전체높이 -브라우저 창의 높이) *100  

 

console.log(window.innerHeight);
console.log(document.querySelector('body').clientHeight);
let hei=document.querySelector('body').clientHeight-window.innerHeight;

window.addEventListener('scroll', function(){

  console.log(window.scrollY/hei*100);
});

위 코드로 확인 

 

너비 지정할때 .style.width로 지정

선택자.style.color='red'; 빨강으로 지정하는 것 처럼 너비 지정하기

  let a= console.log(window.scrollY/hei*100);

  document.querySelector('.status-bar').style.width =`${a}`;

 


정규식(정규표현식) (Regular Expression)

 

정규식은 일반적으로

const 상수 선언하는경우가 대부분 

const regex const regexp  

const regexid constregexpw

 

const regex=/정규식/;      /정규식시작      / 정규식끝

const regexp = new RegExp('정규식');

위같은 방식으로 정규식 만듦 

 

/패턴/플래그/

 

test 메서드 문자열이 정규식에 매칭되는게 있으면 true, 아니면 false 리턴 

예제 ↓

const regex = /abc/;

let result;

// 정규식 메서드(함수)

result = regex.test('가나다 abc 123');

console.log(result);

 

const regex = /abc/;

let result;
let text = '가나다 abc 123'
// 정규식 메서드(함수)

result = regex.test(text);

console.log(result);

플래그란? 

-> 정규식에 대한 검색옵션(정규식으로 안되는 것들을 보완해줌)

 

i: 대소문자 구별 안한다는 뜻 

g: 문자열에 대한 모든 패턴을 찾음(검색) 

m: 줄바꿈이 되도 검색 계속 함 (여러줄로 입력된 데이터들) 

 

정규식을 만족하는 것을 표시해주는 사이트

RegExr: Learn, Build, & Test RegEx

 

RegExr: Learn, Build, & Test RegEx

RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).

regexr.com

패턴

a-z(소문자, - 으로 범위지정)  A-Z 

[]:안에 넣어주는 건 or

 

ㄱ-ㅎ 가-힣 (한글검색)

0-9 (숫자검색)

. 은 모든 문자 다 검색( 공백이나 특수문자 모두 포함)

/d (숫자만) 슬래시로 표현

\D(숫자만 빼고)  역 슬래시로 표현

\w [A-Za-z0-9_] 와 똑같음 

\s 띄어쓰기한 것만 찾기(space)

\S 스페이바 누른 것만 뺴고, 공백만 빼고 다찾기

\!\@\#\$\& 특수문자 찾기

[^a] a빼고 a 제외하고 찾기

[^a-z] a부터z까지 제외하고 찾기 

 ^R  R로 시작하는 문자찾기

^[a-z] a부터z로 시작하는 문자찾기

c? c포함된 문자찾기

apple? apple포함된 문자찾기 

[a-z] {3,} a부터z까지 시작하는것중에 3개이상 

[a-b] {1,2} a가 하나인거나  b가 하나인거나 a,b 두글자연속으로 이루어진것 찾기 a,b 1개부터 두개까지 찾기

\d{2,3}-\d{3,4}-\d{4} -> 핸드폰,일반전화번호 찾는법



미리 만들어진 형식 활용해서 찾아보기 가능! 


정규식 이용해서 회원가입 만들기 

 

알바펫 대소문자, 숫자 ,특수문자 8~20자

 

회원가입 구현하기 (리팩토링 전 코드)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <link rel="stylesheet" href="회원가입.css">
    <title>회원 가입</title>
</head>
<body>
    <h1>회원 가입</h1>
    <form>
        <div class="id_input_box">
            <input id="id_txt" type="text" placeholder="아이디를 입력하세요.">
            <p class="id_input_check"></p>
            <button class="input_confirm_btn" id="id_confirm">확인</button>
        </div>
        
        <div class="pw_input_box">
            <input id="pw_txt" type="password" placeholder="비밀번호를 입력 하세요.">
            <p class="pw_input_check"></p>
            <button class="input_confirm_btn" id="pw_confirm">확인</button>
        </div>
        <div class="email_input_box">
            <input id="email_txt" type="email" placeholder="이메일을 입력 하세요.">
            <p class="email_input_check"></p>
            <button class="input_confirm_btn" id="email_confirm">확인</button>
        </div>
        <div class="phone_input_box">
            <input id="phone_txt" type="tel" placeholder="전화번호를 입력 하세요.">
            <p class="phone_input_check"></p>
            <button class="input_confirm_btn" id="phone_confirm">확인</button>
        </div>
        <button class="reg_req_btn">가입 요청</button>
    </form>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
        crossorigin="anonymous"></script>
    <script src="회원가입.js"></script>
</body>
</html>
* {
  box-sizing: border-box;
}
body {
  width: 500px;
  margin: 20px auto;
}
h1 {
  font-size: 2em;
  margin-bottom: 20px;
}

input {
  width: 300px;
  height: 50px;
  border-radius: 10px;
  padding-left: 20px;
}

.input_confirm_btn {
  width: 100px;
  height: 50px;
  border-radius: 10px;
  margin-bottom: 24px;
  background-color: royalblue;
  color: white;
  border: none;
  border: 1px solid blue;
}
.input_confirm_btn:active {
  position: relative;
  left: 2px;
  top: 2px;
}

.id_input_box {
  position: relative;
}

.id_input_check {
  position: absolute;
  top : 52px;
  right: 200px;
}
.pw_input_box {
  position: relative;
}
.pw_input_check {
  position: absolute;
  top: 52px;
  right: 200px;
}
.email_input_box {
  position: relative;
}
.email_input_check {
  position: absolute;
  top: 52px;
  right: 200px;
}
.phone_input_box {
  position: relative;
}
.phone_input_check {
  position: absolute;
  top: 52px;
  right: 200px;
}

.reg_req_btn {
  margin-top: 30px;
  font-size: 1.2em;
  width: 404px;
  height: 50px;
  border-radius: 10px;
  margin-bottom: 24px;
  background-color: darkgray;
  color: white;
  border: none;
  border: 1px solid darkgray;
}

.reg_req_btn:active {
  position: relative;
  top: 2px;
  left: 2px;
}
// 정규식 조건
const regexId = /^\w{8,20}$/;
const regexPw = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,20}$/;
const regexMail = /^([a-z]+\d*)+(\.?\w+)+@\w+(\.\w{2,3})+$/;
const regexPhone = /^\d{2,3}-\d{3,4}-\d{4}$/;

// 올바르게 입력했는 지 저장해주는 변수들
let isId = false;
let isPw = false;
let isEmail = false;
let isPhone = false;

// 로그인 버튼 클릭시
const idBtn = document.querySelector('#id_confirm');
const pwBtn = document.querySelector('#pw_confirm');
const emailBtn = document.querySelector('#email_confirm');
const phoneBtn = document.querySelector('#phone_confirm');
// 유효성 검사 후 결과 표시해주는 p태그들 
let idCheck = document.querySelector('.id_input_check');
let pwCheck = document.querySelector('.pw_input_check');
let emailCheck = document.querySelector('.email_input_check');
let phoneCheck = document.querySelector('.phone_input_check');

 idBtn.addEventListener('click', function(e){
    e.preventDefault(); 
  let val = document.querySelector('#id_txt').value;
  // console.log(document.querySelector('#id_txt').value);

  if(regexId.test(val)) {
    isId = true;
    idCheck.textContent = '사용가능 한 id입니다';
    /*idCheck.innerHTML = '입력되었습니다.';*/
    idCheck.style.color = 'green';
  } else {
    isId = false;
    idCheck.textContent = '사용불가능 한 아이디입니다.';
    /*idCheck.innerHTML = '입력되지 않았습니다.';*/
    idCheck.style.color ='red';
  }
  isOk(); 
});

pwBtn.addEventListener('click', function(e){
  e.preventDefault();
  let val = document.querySelector('#pw_txt').value; 

  if(regexPw.test(val)) {
    isPw = true;
    pwCheck.textContent = '사용가능 한 비밀번호입니다.'
    /*pwCheck.innerHTML = '입력되었습니다.';*/
    pwCheck.style.color = 'green';

  } else {
    isPw = false;
    pwCheck.textContent = '사용불가능 한 비밀번입니다.'
    /*pwCheck.innerHTML = '입력되지 않았습니다.';*/
    pwCheck.style.color ='red'; 
  }
  isOk(); 
});

emailBtn.addEventListener('click', function(e){
  e.preventDefault();
  let val = document.querySelector('#email_txt').value;
  if(regexMail.test(val)) {
    isEmail = true;
    emailCheck.textContent = '사용가능 한 이메일입니다.';
    /*emailCheck.innerHTML = '입력되었습니다.';*/
    emailCheck.style.color = 'green';
    
  } else {
    isEmail = false;
    emailCheck.textContent = '사용불가능 한 이메일입니다.'
    /*emailCheck.innerHTML = '입력되지 않았습니다.';*/
    emailCheck.style.color ='red';
  }
  isOk(); 
});

phoneBtn.addEventListener('click', function(e){
  e.preventDefault();
  let val = document.querySelector('#phone_txt').value;
  if(regexPhone.test(val)) {
    isPhone = true;
    phoneCheck.textContent = '사용가능 한 전화번호입니다.';
    /*phoneCheck.innerHTML = '입력되었습니다.';*/
    phoneCheck.style.color = 'green';

  } else {
    isPhone = false;
    phoneCheck.textContent = '사용불가능 한 전화번호입니다.';
    /*phoneCheck.innerHTML = '입력되지 않았습니다.';*/
    phoneCheck.style.color ='red';
  }
    isOk(); 
});


function isOk() {
  if(isId && isPw && isEmail && isPhone) {
   document.querySelector('.reg_req_btn').style.background = 'blue';
    }
  }

리팩토링 후!!  자바스크립트만

// 정규식 조건
const regexId = /^\w{8,20}$/;
const regexPw = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,20}$/;
const regexMail = /^([a-z]+\d*)+(\.?\w+)+@\w+(\.\w{2,3})+$/;
const regexPhone = /^\d{2,3}-\d{3,4}-\d{4}$/;

// 올바르게 입력했는 지 저장해주는 변수들
let isId = false;
let isPw = false;
let isEmail = false;
let isPhone = false;

// 로그인 버튼 클릭시
const idBtn = document.querySelector('#id_confirm');
const pwBtn = document.querySelector('#pw_confirm');
const emailBtn = document.querySelector('#email_confirm');
const phoneBtn = document.querySelector('#phone_confirm');
// 유효성 검사 후 결과 표시해주는 p태그들 
let idCheck = document.querySelector('.id_input_check');
let pwCheck = document.querySelector('.pw_input_check');
let emailCheck = document.querySelector('.email_input_check');
let phoneCheck = document.querySelector('.phone_input_check');

 idBtn.addEventListener('click', function(e){
    e.preventDefault(); 
  let val = document.querySelector('#id_txt').value;
  // console.log(document.querySelector('#id_txt').value);

  isId = regexId.test(val);
  showMsg(isId,idCheck);
  
  // if(regexId.test(val)) {
  //   isId = true;
  //   idCheck.textContent = '사용가능 한 id입니다';
  //   /*idCheck.innerHTML = '입력되었습니다.';*/
  //   idCheck.style.color = 'green';
  // } else {
  //   isId = false;
  //   idCheck.textContent = '사용불가능 한 아이디입니다.';
  //   /*idCheck.innerHTML = '입력되지 않았습니다.';*/
  //   idCheck.style.color ='red';
  // }
  // isOk(); 
});

pwBtn.addEventListener('click', function(e){
  e.preventDefault();
  let val = document.querySelector('#pw_txt').value; 

  isPw = regexPw.test(val);
  showMsg(isPw,pwCheck);
  
  // if(regexPw.test(val)) {
  //   isPw = true;
  //   pwCheck.textContent = '사용가능 한 비밀번호입니다.'
  //   /*pwCheck.innerHTML = '입력되었습니다.';*/
  //   pwCheck.style.color = 'green';

  // } else {
  //   isPw = false;
  //   pwCheck.textContent = '사용불가능 한 비밀번입니다.'
  //   /*pwCheck.innerHTML = '입력되지 않았습니다.';*/
  //   pwCheck.style.color ='red'; 
  // }
  // isOk(); 
});

emailBtn.addEventListener('click', function(e){
  e.preventDefault();
  let val = document.querySelector('#email_txt').value;
 
  isEmail = regexMail.test(val);
  showMsg(isEmail,emailCheck);
  
  // if(regexMail.test(val)) {
  //   isEmail = true;
  //   emailCheck.textContent = '사용가능 한 이메일입니다.';
  //   /*emailCheck.innerHTML = '입력되었습니다.';*/
  //   emailCheck.style.color = 'green';
    
  // } else {
  //   isEmail = false;
  //   emailCheck.textContent = '사용불가능 한 이메일입니다.'
  //   /*emailCheck.innerHTML = '입력되지 않았습니다.';*/
  //   emailCheck.style.color ='red';
  // }
  // isOk(); 
});

phoneBtn.addEventListener('click', function(e){
  e.preventDefault();
 
  let val = document.querySelector('#phone_txt').value;

  isPhone = regexPhone.test(val);
  showMsg(isPhone,phoneCheck);
 
 
  // if(regexPhone.test(val)) {
  //   isPhone = true;
  //   phoneCheck.textContent = '사용가능 한 전화번호입니다.';
  //   /*phoneCheck.innerHTML = '입력되었습니다.';*/
  //   phoneCheck.style.color = 'green';

  // } else {
  //   isPhone = false;
  //   phoneCheck.textContent = '사용불가능 한 전화번호입니다.';
  //   /*phoneCheck.innerHTML = '입력되지 않았습니다.';*/
  //   phoneCheck.style.color ='red';
  // }
    // isOk(); 
});

function showMsg(isX, XCheck){
  if(isX) {
    XCheck.textContent = '사용가능';
    XCheck.style.color = 'green';
  } else {
    XCheck.textContent = '사용불가능';
    XCheck.style.color ='red';
  }
  isOk();
}
function isOk() {
  if(isId && isPw && isEmail && isPhone) {
   document.querySelector('.reg_req_btn').style.background = 'blue';
    }
  }

open API 

OpenWeather 이용하기

 

navigator.geolocation.getCurrentPosition = (허용했을때 함수, 허용(연결)안했을 때 함수)

Current weather data - OpenWeatherMap

 

Current weather data - OpenWeatherMap

Access current weather data for any location on Earth including over 200,000 cities! We collect and process weather data from different sources such as global and local weather models, satellites, radars and a vast network of weather stations. Data is avai

openweathermap.org

https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}

어떻게 날씨 api 뽑아오는지 알려주는 사이트 ↑

 

json 데이터 크롬에서 좀더 편리하게 읽고싶으면

https://chrome.google.com/webstore/detail/jsonvue/chklaanhfefbnpoihckbnefhakgolnmc/related?hl=ko 

 

JSONVue

Validate and view JSON documents

chrome.google.com

위의 확장프로그램 사용 

 

비동기 처리때문에 then을 사용함 

const API_KEY = '6e7b0fc7305c68ca15b1f04322064051';
let name= document.querySelector(`#name`);
let main= document.querySelector(`#main`);
let temp= document.querySelector(`#temp`);


function connect(position) {  
  const lat =position.coords.latitude;
  const lon =position.coords.longitude;
  console.log(`위도:${lat}, 경도:${lon}`);
  const URL = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`
  fetch(URL).then((response) => response.json())
            .then((data)=> {
              console.log(data.name); //지역이름
              console.log(data.weather[0].main); // 날씨
              console.log(data.main.temp); // 온도

              name.textContent = data.name;
              main.textContent = data.weather[0].main;
              temp.textContent = data.main.temp+`℃`;//ㄹ한자
            
            });
}

function errorConn()
 {
  alert('위치연결 실패');
 }
navigator.geolocation.getCurrentPosition(connect, errorConn);
728x90