<구글 로그인>
<html>
<body>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<div
id="g_id_onload"
data-client_id=""
data-callback="handleCredentialResponse"
></div>
<div class="g_id_signin" data-type="icon" data-shape="circle"></div>
<script>
function handleCredentialResponse(response) {
// decodeJwtResponse() is a custom function defined by you
// to decode the credential response.
const responsePayload = parseJwt(response.credential);
console.log("ID: " + responsePayload.sub);
console.log("Full Name: " + responsePayload.name);
console.log("Given Name: " + responsePayload.given_name);
console.log("Family Name: " + responsePayload.family_name);
console.log("Image URL: " + responsePayload.picture);
console.log("Email: " + responsePayload.email);
}
function parseJwt(token) {
var base64Url = token.split(".")[1];
var base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
var jsonPayload = decodeURIComponent(
atob(base64)
.split("")
.map(function (c) {
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
})
.join("")
);
return JSON.parse(jsonPayload);
}
</script>
</body>
</html>
<!--
http://localhost:5500/google/googleLogin.html 로 테스트하면 됨
주의 localhost대신 127.0.0.1은 절대 안됨
-->
<!DOCTYPE html>
<html lang="ko">
<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>구글로그인 - [모듈화 사용: type = "module"]</title>
</head>
<body>
<!--
type = text/javascript를 사용하는 경우와 module을 사용하는 경우 호환이 안 되는 부분 발생
ECMAScript6기준으로 작업하는가? WWW CommonJS기준으로 작업하는가? -> 차이있음
-->
<script type="module">
import { firebaseApp } from "../service/firebase.js";
import AuthLogic from "../service/authLogic.js";
console.log(firebaseApp);
const authLogic = new AuthLogic();
console.log(authLogic);
const btnGoogle = document.querySelector("#btnGoogle");
btnGoogle.addEventListener("click", (e) => {
/*
button태그 사용시에 디폴트 타입이 submit이어서 폼 전송이 일어나게되며
이럴 경우 해당 페이지에 리프레쉬 발생함에 따라 이상동작이 발생하므로
반드시 button태그로 click이벤트 처리시에는 주의할 것!
*/
e.preventDefault(); // submit 방지 용으로 추가 할 것!!(이벤트 버블링 방지)
// console.log(e.target + e.currentTarget);
authLogic.login("Google").then((snapshot) => {
console.log(snapshot);
});
});
</script>
<button id="btnGoogle">구글로그인</button>
</body>
</html>
// Import the functions you need from the SDKs you need
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.17.1/firebase-app.js";
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
};
// Initialize Firebase
export const firebaseApp = initializeApp(firebaseConfig);
import {
getAuth,
signInWithPopup,
GithubAuthProvider,
GoogleAuthProvider,
} from "https://www.gstatic.com/firebasejs/9.17.1/firebase-auth.js";
class AuthLogic {
constructor() {
this.firebaseAuth = getAuth();
this.googleProvider = new GoogleAuthProvider();
this.githubProvider = new GithubAuthProvider();
}
login(providerName) {
// console.log("providerName : " + providerName);
const authProvider = this.getProvider(providerName);
// console.log("authProvider : " + authProvider);
// console.log("this.firebaseAuth : " + this.firebaseAuth);
//return signInWithPopup(this.firebaseAuth, authProvider);
return signInWithPopup(this.firebaseAuth, authProvider);
}
logout() {
this.firebaseAuth.signOut();
}
onAuthChange(onUserChanged) {
this.firebaseAuth.onAuthStateChanged((user) => {
onUserChanged(user);
});
}
getProvider(providerName) {
switch (providerName) {
case "Google":
return this.googleProvider;
case "Github":
return this.githubProvider;
default:
throw new Error(`not supported provider: ${providerName}`);
}
}
}
export default AuthLogic;
선언함수
이름이 있는 함수
따로 변수에 넣어주지 않고 선언할 때 붙여준 이름으로 호출함
function funcName () {
// 실행코드 작성
}
funcName();
익명함수
이름이 없는 함수
익명함수를 선언하고 사용하기 위해선 변수에 넣어서 사용해야 함
const funcName = function () {
alert('Hello');
};
funcName();
대입함수
js에서 함수는 객체이다
사이드 컨벤션
1. 일급함수
함수를 다른 변수와 동일하게 다룸(변수에 할당, 파라미터로 제공, 함수 반환)
2. 고차함수
함수를 반환하는 함수
// 1. 변수에 함수 할당
const foo = function() {
console.log("foobar");
}
// 변수를 사용해 호출
foo();
// 2. 함수를 인자로 전달
// 다른 함수에 인자로 전달된 함수를 콜백 함수라고 함
function sayHello() {
return "Hello, ";
}
function greeting(helloMessage, name) {
console.log(helloMessage() + name);
}
// `sayHello`를 `greeting` 함수에 인자로 전달
// sayHello는 콜백함수!
greeting(sayHello, "JavaScript!");
// 3. 함수 반환
// 함수를 반환하는 함수를 고차 함수라고 함
function sayHello() {
return function() {
console.log("Hello!");
}
}
즉시실행함수
정의되자마자 즉시 실행되는 함수
const result = (function () {
const name = "Barry";
return name;
})();
// 즉시 결과를 생성한다.
result; // "Barry"
<보드 판매량>
<!DOCTYPE html>
<html lang="ko">
<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>Document</title>
<!--
외부 자바스크립트 파일 참조하기
이럴 경우 시점의 문제 발생하니 주의
해결 방법: 순서지향적인 처리, DOM 구성이 완료된 후에 html문서의 태그정보를 접근하려면 defer를 붙이기!
이유는 코딩 순서대로 진행되기 때문에
-->
<script defer src="./board.js"></script>
<link rel="stylesheet" href="./board.css" />
<script type="text/javascript">
// 전역변수 선언자리
// 마진 버튼을 클릭했을 때 호출함수
function getBoardSold() {
console.log("getBoardSold");
// createRequest(); 비동기 통신 객체를 생성하기
xhrObject = createRequest(); // 비동기 통신 객체를 리턴값으로 받기
console.log(xhrObject);
const url = "./boardSellAction.html"; // 집계된 보드 판매량 수치
xhrObject.open("GET", url, true); // true-async / false-sync(동기일거면 ajax 필요없음)
xhrObject.onreadystatechange = soldProcess;
xhrObject.send();
}
// 요청에 대한 응답이 다운로드 되었을 때
// 서버로부터 전달된 상태값이 200번일 때
// 호출되는 함수 - 콜백함수(어떤 조건이 만족되면 시스템이 호출해주는 함수)
function soldProcess() {
console.log("soldProcess 호출 => " + xhrObject.readyState);
// 4 -> 다운로드가 완료됐을때(0~4상태값이 바뀔때마다 콜백함수 호출됨)
if (xhrObject.readyState == 4) {
// 200 -> 응답을 성공적으로 받음(응답이 정상처리됨)
if (xhrObject.status == 200) {
// 보드 판매량
const newTotal = xhrObject.responseText; // 새로 받아온 값
console.log(newTotal);
const boardSoldEl = document.querySelector("#boardSold");
replaceText(boardSoldEl, newTotal);
// 구매가
const costEl = document.querySelector("#cost");
let cost = getText(costEl);
// 소비자가
const priceEl = document.querySelector("#price");
let price = getText(priceEl);
// 보드 1개당 마진 금액
let cashPerBoard = price - cost;
let cash = cashPerBoard * newTotal;
console.log("마진금액은 " + cash);
// 마진 금액 붙일 곳
const cashEl = document.querySelector("#cash");
replaceText(cashEl, cash);
}
}
}
</script>
</head>
<body>
<!-- type을 생략하면 text/javascript -->
<script>
window.addEventListener("load", function (event) {
const btnMargin = document.querySelector("#btnMargin");
btnMargin.addEventListener("click", (event) => {
event.preventDefault(); // submit으로인한 전송처리로 페이지가 새로고침 방지
getBoardSold();
});
});
</script>
<h2>보드 판매량</h2>
<table width="300px" height="80px">
<tr>
<th width="120px">보드 판매량</th>
<td width="180px"><span id="boardSold">10</span></td>
</tr>
<!--
소비자가-구매가=보드 한개당 마진 금액
한개당 마진 금액*판매량=마진금액계산
-->
<tr>
<th>구매가</th>
<td><span id="cost">100</span>원</td>
</tr>
<tr>
<th>소비자가</th>
<td><span id="price">120</span>원</td>
</tr>
</table>
<h2>마진금액 : <span id="cash">0</span>원</h2>
<button type="submit" id="btnMargin">마진은?</button>
</body>
</html>
30
body {
font-family: sans-serif;
text-align: center;
}
table {
margin-left: auto;
margin-right: auto;
border: 1px solid black;
}
td,
th {
border: 1px dotted gray;
text-align: center;
}
th {
background-color: #ffaaaa;
}
// 비동기 통신 객체 생성해서 담을 변수 선언
let xhrObject = null; // 선언
// 비동기 통신 객체 생성하는 함수 구현 - 리턴 예약어가 있어야 반환받을 수 있음
function createRequest() {
// 자바스크립트에서도 예외처리가 가능하다
try {
xhrObject = new XMLHttpRequest(); // constructor, 생성자
} catch (trymicrosoft) {
try {
// MS의 IE사용자 위한 객체 생성
xhrObject = new XMLHttpRequest("Msxml2.XMLHTTP");
} catch (error) {
xhrObject = null;
}
}
if (xhrObject == null) {
alert("비동기 통신 객체 생성 에러");
}
return xhrObject;
} // end of createRequest
// span태그가 가지고 있는 텍스트 노드값을 읽어오기
// <td>100</td> -> 태그 이름이 없다, 속성을 정의 못한다, 아이디나 클래스를 정의하지 못함, 접근불가
// 해결방법 - 그래서 텍스트노드를 span으로 감싸고 id를 준다
// document.querySelector("#id")
// document.querySelector(".class")
// document.querySelector("태그이름")
// const costEl = document.querySelector("#cost"); 구매가
// const priceEl = document.querySelector("#price"); 소비자가
function getText(el) {
let text = ""; // ES6 -> ECMAScript2015 - 적용안되는 브라우저이면 babel이 필요(js컴파일러) 또는 번들러(parcel)
if (el != null) {
// el이 null, undefuned, "", NaN이 아닌 경우 true여서 아래 if문 들어감
if (el.childNodes) {
// costEl, priceEl
console.log(el + "," + el.childNodes.length); // 길이 1
for (let i = 0; i < el.childNodes.length; i++) {
let childNode = el.childNodes[i];
//너 텍스트 노드니?
if (childNode.nodeValue != null) {
text = text + childNode.nodeValue;
}
}
}
}
return text;
}
// 기존 TextNode의 값을 다른 문자열로 바꾸기
/***********************************************
param1 :document.getElementById("boardSold")
param1 :document.querySelector("#boardSold")
param2 :xhrObject.
************************************************/
// el -> boardSoldEl(보드판매량), cashEl(마진계산) -> span태그
function replaceText(el, value) {
// 여기 들어오는 el은 span
if (el != null) {
clearText(el); // 기존에 있던 10을 지우기
// 새로운 텍스트 노드 value(파라미터로 받은 수)를 생성하기
var newNode = document.createTextNode(value);
// 위에서 생성한 텍스트 노드 값을 el에 붙이는 함수 호출하기
el.appendChild(newNode); // <span>10</span> -> <span></span> -> <span>20</span>
}
}
// 기존 태그안에 문자열 지우는 함수 구현
function clearText(el) {
if (el != null) {
// 자바스크립트에서는 0이 아닌 건 모두 참이다
if (el.childNodes) {
for (let i = 0; i < el.childNodes.length; i++) {
let childNode = el.childNodes[i];
el.removeChild(childNode); // 해당 el 삭제하기 - DOM API -> 직관적이지 않다, 유지보수 어렵다
}
}
}
}
'국비학원 > 수업기록' 카테고리의 다른 글
국비 지원 개발자 과정_Day51 (0) | 2023.02.09 |
---|---|
국비 지원 개발자 과정_Day50 (0) | 2023.02.08 |
국비 지원 개발자 과정_Day48 (0) | 2023.02.04 |
국비 지원 개발자 과정_Day47 (1) | 2023.02.02 |
국비 지원 개발자 과정_Day46 (0) | 2023.02.01 |
댓글