FE 공부

jangky000·2020년 9월 11일
0

day1

DOM API이란?

브라우저에서는 HTML코드를 DOM(Document Object Model)이라는 객체형태의 모델로 저장합니다.

그렇게 저장된 정보를 DOM Tree 라고 함. 결국 HTML element는 Tree형태로 저장됩니다.

DOM API 조작

https://velog.io/@seokzin/JavaScript-자주-사용하는-DOM-API-정리

var input2 = document.querySelector("input[name='input2']");
input2.addEventListener("focusout", e=>{ e.target.value }); -> e.target.value는 input2의 값

var message = document.querySelector(".message");
message.innerHTML = "";

// 직접 css 값을 변경하는 것보다는 classList(DOM API)를 사용해서 클래스를 변경시켜주는 방법이 좋다.
addClass, removeClass

// 노드 탐색 방법
// 요소 접근
document.getElementById()
document.querySelector()
document.querySelectorAll()
// 자식 접근
div.firstChild -> 줄바꿈이 있다면 #text로 공백 텍스트를 찾게 됨
div.firstElementChild -> 공백(#text)이 아닌 요소를 찾아줌
ul.childNodes -> 리스트 형태로 자식 요소를 보여줌
firstLi.nextSibling -> 공백 #text
firstLi.nextElementSibling -> <li>...</li>

// 노드 타입의 이해
document.body.tagName -> "body", "div", "table" 등
document.querySelector("li:nth-child(3)")
div1.nodeType -> elementNode: 1, textNode: 3
div1.textContent -> 태그 내에 있는 모든 텍스트 노드를 출력

// 노드의 생성과 추가
var div = document.createElement("div")
var str = document.createTextNode("hello world")
div.appendChild(str)

insertBefore(div, base) -> base 앞에 div를 집어 넣음, 많이 사용하는 기법
// base는 3번째 열, div는 

innnerText -> 안에 있는 모든 텍스트 가져옴
innerHtml -> getter의 역할
.innerHtml() -> setter의 역할, createElement 등의 작업을 생략하고, 
// "<p>...</p>"의 형태로 추가하면 훨씬 작업이 쉽고 편리하고 빠르다.

레이아웃을 실시간으로 테스트 할 수 있는 사이트

jsbin.com

웹 프론트를 작업할 때

  • 컴포넌트 중심으로 개발하는 경우가 많다.(react나 vue 프레임워크를 사용)
  • 각 페이지에 해당하는 html, css, js를 같이 개발하는 방식

브라우저 렌더링 과정

스크립트의 성능

네이버 D2, 데뷰를 참조한 것이 좋다.

네이버 whale? 크롬을 기반으로 extend한 브라우저 → 발표자료나 성능, 렌더링에 대한 것을 알 수 있어 성능이 좋은 코드를 짤 수 있다.

https://tv.naver.com/v/4578425

semantic한 태그를 사용해라

  • 제목이 아닌데, bold 효과를 위해서 h 태그를 사용하는 경우 → x
  • 내용적으로 강조가 필요한데 bold 효과를 css로 주는 경우 → x, strong 태그 등을 사용
  • 리스트 형식의 데이터가 아닌데, 리스트의 디자인이 마음에 들어서 사용하는 경우 → x

Cascading

  • 부모 태그의 속성을 자식 태그 속성에도 적용함
  • 우선순위에 의해서 반영

Specificity : 특성

/* first selector */
.btn{
  font-size: 20px;
  color: #ff23a1;
  background-color: white;
}  

/* second selector */
nav#nav div.pull-right .btn{
  background-color: blue;
}

/* third selector */
a{
  background-color: green;
}

/* forth selector */
#nav a.btn:hover{
  background-color: orange;
}

인라인 태그(태그에 직접 적용) 확인 → id 확인 → 클래스 개수가 높은 거 → selector 개수가 많은 거 선택해서 적용

css 클래스 이름이나, 자바스크립트를 난독화 함으로 얻는 이득

  • 코드가 읽기 어려워지고(△)
  • 코드의 용량이 줄어든다.(○)

flex

https://heropy.blog/2018/11/24/css-flexible-box/

https://www.youtube.com/watch?v=pgFyqS4oCIc

// container
display: flex;
flex-direction: row;
flex-flow: column wrap

// item
flex-grow: 2; // 여백의 비율을 조절함
justfy-content: flex-end
justfy-content: space-around ?? 

// modal
position: fixed;
top: 0;
right: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center; // 가로 정렬, 주축 정렬
align-items: center; // 세로 정렬, 교차축 정렬
z-index: 50;

flex와 grid의 차이는?

px, em/rem

  • em(element를 기준으로)보다는 rem을 권장(root를 기준으로)
  • 반응형 웹과 관련이 있음

DDD: debug driven development

  • debugger in chrome 등 사이트 참조

특정 영역을 제외한 영역을 클릭하면 창이 닫히게 하기

document.querySelector("body").addEventListener('click', close_user_nav_menu);

const menu = document.getElementById('user_nav_menu');
    const btn = document.getElementById('btn_user_nav');
    if(!(menu.contains(e.target) || btn.contains(e.target))&&!menu.classList.contains('hidden')){
        // document.getElementById('user_nav_menu').classList.toggle('show');
        menu.classList.toggle('hidden');
    }

너비(width)에 패딩(padding)도 포함이 되나요?

https://endorphin0710.tistory.com/75

본인이 너비를 지정해놓았음에도 패딩과 보더값에 의해서 너비가 변경되어 불편하시다면 현재 content-box가 적용되어 있는 겁니다.

border-box로 변경하고 싶으시다면 아래와 같이 브라우저별로 적용해주시면 됩니다.

* {
	box-sizing: border-box; /* 오페라(Opera) */
	-moz-box-sizing: border-box; /* 파이어폭스(Firefox)*/
	-webkit-box-sizing: border-box; /* 웹킷(Webkit) & 크롬(Chrome) */
}

day2

mixin

https://velog.io/@rohkorea86/NodeJS-pug에서-mixin-사용하는-법-hejr0qd09g

http://blog.naver.com/PostView.nhn?blogId=dydals56789&logNo=221885815994&categoryNo=49&parentCategoryNo=0&viewDate=¤tPage=1&postListTopCurrentPage=1&from=postView

  • 웹사이트에서 계속 반복되는 코드를 복사+붙여넣기 하지 않고 재활용하는 방법
  • 각각 다른 정보를 가지지만 같은 구조를 가지는 템플릿에서 사용
  1. mixin 형태

함수 라고 생각하면 쉽다. 우선 (함수)이름이 있고, 인자 "()"를 받는다. 함수는 어떤 로직을 덩어리로 묶어 둔 주머니와 같다.

  1. mixin 예시
  • 인자를 받지 않는 경우

    우선 mixin 이라고 적고, 그 다음에 (함수)이름을 적는다.mixin을 사용할 경우 "+" 을 넣어준다.

// videoBlock.pug
mixin videoBlock(video= {})
	div.videoBlock
		video.videoBlock__thumbnail(src=video.videoFile,controls=true)
		h4.videoBlock__title = video.title
		h6.videoBlock__view=video.views
// home.pug
include mixins/videoBlock

each object in videos
	+videoBlock({
		title: object.title,
		description: object.description
	})

insertAdjecentHTML

beforeend

object-fit

사진 크기 맞추기

#main .rooms_img img{
    width: 300px;
    height: 200px;
    object-fit: cover;
}

정규식

https://hee-kkk.tistory.com/22

바닐라스크립트 자식 검색

parent.childNodes -> '#text' 포함한 결과

parent.children -> 'element'만 포함한 결과
parent.firstchild -> 'element'만

day3

이벤트 위임

e.target

e.currenttarget

지금 모든 .day 요소에 반복을 하여 이벤트 리스너를 부여하고 있는데요, 나중에 다시 달력을 그릴 때 마다 계속 이벤트를 걸어줘야되고, 비슷한 이벤트를 매번 30여번 부여하는 등의 '낭비'가 발생할 수 있습니다. 이를 해결하는 방법은 이벤트 위임(Event delegation)을 통하여 최상위의 하나의 엘리먼트에 이벤트를 걸어주고, 이벤트 객체에서 발생한 엘리먼트를 특정하여 이벤트를 발생하는 패턴입니다. https://ko.javascript.info/event-delegation 등을 참고해주세요!

flex 강의

https://tv.naver.com/v/5012344

프론트엔드 로드맵 + 학습 키워드 제공

https://roadmap.sh/frontend

성능

https://stackoverflow.com/questions/26848289/javascript-queryselector-vs-getelementbyid

querySelector is the newer feature.

getElementById is better supported than querySelector.

querySelector is better supported than getElementsByClassName.

querySelector lets you find elements with rules that can't be expressed with getElementById and getElementsByClassName

가상요소 before를 통한 transform 밑줄 효과

.tab_menu::before {
    background-color: black;
    position: absolute;
    height: 2px;
    bottom: 0px;
    margin-left: -9px;
    left: 50%;
    content: "";
    width: 18px;
    transform: scaleX(0);
    transition: 0.2s -ms-transform cubic-bezier(0, 0, 0.1, 1),0.2s -webkit-transform cubic-bezier(0, 0, 0.1, 1),0.2s transform cubic-bezier(0, 0, 0.1, 1);
}

/* 탭 기능 */
.tab_selected:before{
    transform: scaleX(1);
}

디버깅 팁

mouseover
mouseout

var el = document.getElementById("outside");
el.addEventListener("click", function(evt){
 console.log(evt.target);
 console.log(evt.target.nodeName);
	debugger // break point를 걸어줌 -> F12의 source 탭에서 확인 가능
}, false);

Thymeleaf 템플릿?

SPAs

싱글페이지 어플리케이션

다양한 templating 전략

UX가 중요하다

서버 사이드 렌더링

리액트의 첫 화면이 늦게 뜨는 것에 대한 해결방법 → 여러가지

(첫 화면 뜨고, API 요청하고, 템플릿 만들고.. 등등)

SSR : serverside rendering

리액트에서 첫 화면을 만들 때, 서버에서 렌더링을 하는 것

그냥 서버에서 렌더링해서 보내는 것을 의미하는 것과는 요즘 다르게 쓰이고 있음

유틸(utils) 함수를 만들기

document.querySelector() → _el(selector, baseNode=document ) 등으로

default parameter 사용

리액트는 돔 조작을 도와주는 라이브러리

스크립트 모듈: 싱글 페이지에서 유리한 방법

<script type="module" src="js/module.js">
// module.js
export {}
// main.js
import {} from 'module.js'
// index.html
<script type="module" src="main.js">

e.target.closest('') → 가장 가까운 걸 찾음

el.dataset.data1

이벤트리스너에 함수 이름 끝에 Handler를 붙여서 사용

핸들러 함수로 묶어서 init 함수로 실행

모듈 구조를 참고할 것

이벤트 델리게이션으로 이벤트를 for문으로 호출하지 않아도 된다

자식 노드에 접근할 때 [1] 등으로 접근하지 않는 것이 좋다 → 대신 querySelector로 자식 선택 가능

달력 만들기

https://im-developer.tistory.com/115 참고

day4

https://developer.mozilla.org/ko/docs/Web/CSS/Using_CSS_custom_properties

https://ko.javascript.info/modules-intro

e.stopPropagation();

  • 상위 태그로의 이벤트 전파를 막음
  • 달력의 날짜를 클릭했을때, body 태그에서 발생하는 이벤트를 막음

https://programmingsummaries.tistory.com/313

코드 리뷰

  • flex-direction: 의 default 값은 row
  • CSSOM에 대해서 공부해보기

CSS 애니메이션 효과, keyframes

https://pro-self-studier.tistory.com/108

.modal_content{
    position: relative;
    border-radius: 10px;
    background-color: #ffffff;
    width: 30%;
    height: 500px;
    overflow-y: auto;
    padding:15px 15px;
    animation: modalShowUp 4s ease-in-out
}

@keyframes modalShowUp{
    from{
        opacity: 0;
        transform: translateY(200px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

transition 사용

#search{
    margin: 0 auto;
    width: 100%;
    transition: all 0.1s ease-in;
}

#search.scroll{
    margin: 0 auto;
    width: 0;
    height: 0;
    transform: translateY(-100px);
    opacity: 0;
}

스크롤 이벤트

// 스크롤 이벤트
window.addEventListener('scroll', scrollHandler);

function scrollHandler(){
    if(window.scrollY >= 10 && !$('#header').classList.contains('scroll'))
        $('#header').classList.add('scroll');
    else if(window.scrollY < 10 && $('#header').classList.contains('scroll'))
        $('#header').classList.remove('scroll');
}
function computePageButton(totalLength, curPage, pageLength, url, query){
    
    const page = []; // 페이징 정보를 담은 배열
    const numOfButton = 5; // 페이지 버튼 개수
    const maxPageNum = Math.ceil(totalLength/pageLength); // 최대 페이지
    let rurl = `${url.split('?')[0]}?location=${query.location}&checkin=${query.checkin}&checkout=${query.checkout}&guests=${query.guests}&page=`;
    
    curPage = parseInt(curPage);
    let startIndex; // 시작 페이지
    if( curPage < Math.ceil(numOfButton/2)){
        startIndex = 1;
    } else if(curPage > maxPageNum - Math.ceil(numOfButton/2)){
        startIndex = maxPageNum - numOfButton + 1;
    } else{
        startIndex = curPage-2;
    }
    const endIndex = (startIndex+numOfButton) > maxPageNum ? maxPageNum : (startIndex+numOfButton);

    if(curPage > 1) page.push({name:'<', href:rurl+(curPage-1)});
    for(let i=startIndex-1; i<endIndex; i++){
        if(i === curPage-1) page.push({name:i+1, href:rurl+(i+1), curPage:true});
        else page.push({name:i+1, href:rurl+(i+1)});
    }
    if(curPage < maxPageNum) page.push({name:'>', href:rurl+(curPage+1)});
    return [...page];
}
profile
예비 웹 FE 개발자

0개의 댓글