안녕하세요 VanillaJS를 통해서 특정 작업을 하기전에 페이지 관련 내용들을 작성하여야 합니다.


(포스팅이 조금 늦은감이 있지만 ㅜ 주말까지 일을 하다보니.... )


index.html 이죠!!  제작되고있는 


전체 코드는  아래에 있습니다. (github) 에 올려놓고 있죠 후훗 


reactStudy/myVaniilaJS 에 있습니다.


VanillaJS 개요


https://ipex.tistory.com/224


그래서 오늘은 페이지의 메인이 되는 


index.html 을 작성하려고 합니다.


index.html


우선 해당 메인 페이지 의 작성은 프론트엔드 체크리스트 라는 사이트를 통해서 작성 하였습니다.


해당은 선언문입니다.


<!doctype html>

자칫 태그로 잘못 아실수 있지만 태그는 아니고 해당 HTML 이 몇 버전으로 작성되었다! 라고 브라우저가 알수 있도록 선언해주는 선언문 입니다.  doctype은 문서의 가장 첫번째 에 오게 됩니다.


MDN 에서는 doctype을 이와같이 설명합니다.


" HTML 에서 문서 타입은  '필수' 이며 **preamble 이다.해당 선언은 브라우저가 렌더링시 **"쿼크 모드(quirks mode)" 로 전환하는 것을 방지한다.  즉 <!DOCTYPE html> 은 일부 사양과 호환되지 않는 다른 렌더링 모드를 사용하는 대신 브라우저가 관련 사양을 따르는데 최선을 다한다."


또한 브라우저에서는 doctype을 확인할수 있도록 API 로 지원 하고있습니다.


doctype = document.doctype;
  • doctype is a read-only property.

[IE 11 에서의 document.doctype]

[Chrome 에서의 document.doctype]




doctype에 따라서 html 버전을 다르게 갈수있습니다. doctype에 대해서는 

해당 블로그에 설명이 너무 잘되어있어 링크로 대체 하도록 하겠습니다~

http://aboooks.tistory.com/40


HTML 버전 종류 



HTML 2.0 (RFC1866 규격) - 1995년 11월 24일 

HTML 3.2 (W3C 권고안)   - 1997년 1월

HTML 4.0  (W3C 권고안)  - 1997년 12월

HTML 4.0  (W3C 권고안)  - 1998년 4월

HTML 4.01 (W3C 권고안)  - 1999년 12월


XHTML 1.0 (W3C 권고안)  - 2000년 1월 26일

XHTML 1.1 (W3C 권고안)  - 2000년 1월 26일

XHTML 2.0 (W3C 권고안)  - 2000년 1월 26일 (사라짐)


HTML 5   - 2012 발표

HTML 5   - 2014년 10월 28일 표준안 확정

HTML 5.1 - 2016년 11월 01일 표준안 확정

HTML 5.2 - 2017년 12월 14일 표준안 확정

HTML 5.3 - 현재 진행 중


현재 모두는 HTML5로 해야되다보니 HTML5는 따로 조사해보시면 될 것 같습니다!


**preamble

preamble (프리앰블) : 비트 동기 또는 프레임 동기 등을 위하여 프레임 단위에서 각 프레임의 맨 앞에  붙이는 영역 (HTML에선 어떤식의 렌더링이 될지 알려주고 약속 하는 작업을 뜻하는 것으로 보입니다.)



 **"쿼크 모드(quirks mode)" 



<!DOCTYPE html>을 선언하는 이유 중 브라우저가 쿼크모드가 되지 않기 위해서라고 되어있는데요 

quirks mode (비표준 모드) : 


우선 왜 있을 까 ?? 라는 생각부터 하게 되었는데요 현재의 브라우저(HTML5)에서는 W3C 웹표준을 많이 따르기 위해 많은 브라우저들이 노력하고 있습니다. 그렇기 때문에 HTML5을 기준으로 돌아갈수 있도록 doctype을 지원하고 개발자들 역시 그에 맞게 화면을 구성하고있는데


"오래된 페이지" 와의 호환성을 제공하기 위해 모든 브라우저는 이 "quirks Mode"를 지원하게 됩니다. 

(이또한 IE에서 많이 발생합니다. 이슈가)


현재라면 HTML5와 CSS3을 기준으로  계속 작성해 나가시면 될 것 으로 보입니다.


참고 하였던 사이트 ( 정말 유용 했습니다. )


1. Front-End-Checklist 

프론트엔드 개발자들이 가져야할 체크리스트를 해주는 사이트입니다.

정말 유용해서 두번 놀랐네요 (아직 모르는게 많다는 것도 깨닫게 해줬습니다.)


2. Free favicon web Site

파비콘을 무료로 제공하는 사이트입니다 (유료도 구매가 가능합니다.)

https://www.iconfinder.com/icon-sets/featured/free/5


3. favicon Convert Web Site 

2번에서 제공된 파비콘을 파비콘 아이콘으로 변경해주는 사이트입니다.

https://converticon.com/


> 설정은 16 x 16 에서 256 x 256 까지 전부 체크하시고  Save As 하시면 됩니다.




이제 index.html 의 !doctype html  선언이 끝났습니다.



■ html 태그 속성 지정 ( lang , dir )



<!-- 페이지 내의 언어 속성 부여 -->
<!-- 페이지 내의 글자 방향 속성 부여 -->
<!-- rtl : right to left-->
<html lang="ko" dir="ltr">


rtl  ltr 인데요 페이지 내에서의  글자 방향 속성 부여인데요 


접속자가 다른 지역 일 경우 글자 방향이 다르게 나타날수 있기 때문에 이에 대한 명시를 html 태그에 직접 해주셔야 합니다.!




■ meta 태그 



Describe metadata within an HTML document


HTML 문서 내의 메타 데이터를 설명 한다 라고 W3School 에는 명시되어있습니다. 


맞습니다. 제가 작성한 페이지 (HTML DOM) 에 있는 메타데이터를 설명하기 위한 태그입니다.


charset = 'utf-8'


<!-- 문자집합 선언 -->
<meta charset="utf-8"/>


제가 사용하는 페이지의 문자 집합은 utf-8 으로 지정합니다.


http-equiv , content 


<!-- Internet Explorer에게 최신의 렌더링 엔진을 사용 지시 -->
<meta http-equiv="x-ua-compatible" content="ie=edge"/>


IE 8 브라우저 부터 나타났던 호환성 보기에 대한 내용인데요  IE브라우저가 최신의 렌더링을 사용할수 있도록 지시합니다.


http-equiv의 경우 : HTTP 헤더의 이름을 값으로 가질수 있으며  같이 가질수 있는 content의 종류는


"content-security-policy"  ,"content-type" , "refresh", "set-cookie" 등이 있습니다. 자세한 사항은 MDN 참조


MDN : https://developer.mozilla.org/ko/docs/Web/HTML/Element/meta


name 


<!-- Meta Description -->
<meta name="author" content="jaeuk_lee"/>
<meta name="description" content="깍돌이 스터디 페이지입니다."/>
<meta name="front-end-study" content="front-QA "/>


문서 레벨의 메타데이터의 이름을 정의 하는 속성이 있습니다. 해당 속성은 content 에 담긴 값과 연관이 지어집니다.


author  : 해당 문서의 작성자 


description : 페이지의 내용에 대한 짧고 정확한 요약을 담음 (FireFox나 오페라 의 경우 이를 즐겨찾기 페이지의 기본 설명으로 사용)


application-name : 웹 페이지 내에서 실행될 어플리케이션의 이름을 지정합니다. 


generator  : 페이지를 생성한 소프트웨어의 식별자


keyword : 콤마(',') 로 구분된 페이지의 내용과 관련된 단어를 담음


referrer : 문서에서 전송된 요청에 첨부된 HTTP 헤더의 참조를 제어 ( 해당 내용은 MDN 참조 )


** 해당 내용중 name="referrer"의 경우 document.wirte 또는 appendChild로 동적 삽입시 참조자의  작동을 예측 불가능 (no-referer 적용)


// 메타 데이터를 담는 다른 요소들도 있습니다.

** base head link style title 


css 로딩 (JS보다 항상 우선적으로 로딩이 될수 있도록 합니다.)


<!-- css는 무조건 js보다 먼저 로딩이 되어야 한다. -->
<link rel="stylesheet" type="text/css" href="./lib/css/normalize.css"/>
<link rel="stylesheet" type="text/css" href="./lib/css/index.css"/>


CSS 는 JS보다 먼저 로딩 되어야 한다 !!


해당 문구를 보고 아 그냥 CSS가 JS보다 먼저 로딩이 되어야 한다 라는 생각을 가지고 쓰는거보다


왜? CSS가 JS보다 먼저 로딩이 되어야 하는가에 대해 알고 작성하게되면


페이지를 작성하게 되었을 때 여러 가지 도움이 됩니다. ( 성능 적인 이슈 등 등 )


이거에 대해 도움이 되었던 페이지를 링크 합니다.


// Naver D2 브라우저는 어떻게 동작 하는가?

https://d2.naver.com/helloworld/59361


가장 무난한 WebKit 브라우저에 동작 과정을 보자면 








HTML 파서를 통해서 HTML 을 파싱 후 -> DOM 트리 


CSS파서를 통해 CSS을 파싱 후 -> CSS 규칙을 생성 


두 작업이 끝나야 렌더트리를 구축하고 화면을 그리기 시작 하게됩니다.


하지만 해당 도중 에 script 태그를 만난 다면?






DOM 파싱됐고 CSS 파서가 작동하게 되는데 여기서 멈춰버리는 현상이 발생합니다.  모든 파싱이 끝나게 되면 지연(async) 모드의 스크립트 에 대한 파싱을 하게 되며

문서 상태는 "완료" 후 "로드" 이벤트 (ex : window.onload) 가 발생하게 됩니다. 


HTML5에서는 해당 의 작업을 위해서 비동기 Script 로딩을 위해서 defer 와 async 라는 속성을 제공합니다. (이외에도 여러가지가있습니다. )


https://developer.mozilla.org/ko/docs/Web/HTML/Element/script  -> Script 태그 


간단하게 알아 보자면 


async :  해당 스크립트를 비동기적으로 실행 

defer :  브라우저의 ㅣDOMContnetLoaded 이벤트 발생전에 작동되어야 하는 스크립트 


** 하지만 2개의 경우는 inline 으로 작성시에는 동작하지 않습니다. 예를 들면 <script aysnc > -> XXX 동작 안됩니다.  JS로 사용시에만 해당됩니다.


그렇기 때문에 Inline으로 태그를 직접 작성하는 경우는 script 태그가 head 상단에 오면 안됩니다.

JS 예 

var fullPath = 'fullPath';
var _script = document.createElement('script');
_script.setAttribute('src',fullPath);
_script.async = true;

document.body.appendChild(_script);
// or
document.body.insertBefore(_script,document.body.lastChild);


해당과 같이 async 에 true를 주었을 때 비동기로 로딩이 되게됩니다. (이에 대해서는 따로 포스팅)


위의 내용을 정리하자면


CSS의 위치는???


문서를 파싱해서 DOM Tree을 만들 때 CSS가 없으면 렌더링을 할수가 없기 때문에  CSS를 가장 빨리 읽을수 있게 합니다. 그렇기 때문에 적합한 위치는


head 태그 사이에 위에 놓는 것입니다.  브라우저 인터프리터에서는 html 파일을 위에서 아래로 읽기 때문입니다.


그럼 CSS를  head 의 가장 맨앞에 놓고 Script 태그를 놓아서 JS를 로딩 시켜도 되지않을까?? -> 위에도 설명 이 되어있지만 Link 태그와 다르게 Script 태그의 경우 파싱 도중 만나게 


되면 파싱 작업을 멈추고 JS를 로드하게 됩니다. 그렇기 때문에 JS파일이 커진다면 사용자 입장에선 로딩 되는 형태로 보여지기 때문에 좋지 않은 결과를 (UX UI )를 


가져올수 있게 됩니다.


혹은 JS가 먼저 실행되어 적용이 되지 않는 형태가 될수도있습니다.( Ex: body 를 그리지 않았는데 DOM 컨트롤을 할 경우 -> undefined 에러 발생 ) 


그렇기 때문에 JS를 로드하는 Script의 경우는


body의 맨 마지막에 위치합니다.


<body>

<!-- do Something -->
<script src="./myLogic.js"></script>
</body>


이렇게 된다면 head태그에 있는 css들이 우선 로딩 된 후 파서들이 바디를 다 그린 후에 -> script 태그를 만나면서


해당 스크립트를 로딩하게 됩니다.


필요한 스크립트들은 해당 스크립트안에서 전부 로딩 시켜주는 형태로 작성을 할려고 합니다.


현재까지 만들어진 페이지의 코드를 보시면


<footer>
<div>
<span class="pages_desc">
ⓒ Gdl Blog Page
</span>
</div>
</footer>
</div><!-- app-root-->
<script src="./lib/gdl.js"> </script>
</body>

</html>



최하단에 gdl.js를 로딩 합니다.


해당 gdl.js에서는


function initialize(){
document.addEventListener("DOMContentLoaded", function() {
console.warn('Windows DOM ContentedLoaded');
gdlUtilModuleLoading();
setTimeout(function(){
gdlOtherModuleLoading();
},100);
// gdlOtherModuleLoading();
});
return{
}
}


보시는 것처럼 UtilModule을 로딩 후


다른 모듈을 로딩합니다.

function gdlOtherModuleLoading(){
var arr = ['gdlAjax','tempEvent'];
// 나머지 모듈 비동기로드
// arr.reduce(function(prev,curr,index,arr){
// Util.include(curr+'.js');
// },0);

// 현재는 동기로드
arr.reduce(function(prev,curr,index,arr){
Util.include({
path:curr+'.js',
jsfileName:curr,
async:false,
onload : function(){
console.warn('임시 테스트 코드 온로드 확인 ',tt);
}
});
},0);


}


보시면 Util.include라는 API(?) 를 사용하였는데요 이거는 제가 따로 함수로 빼놓았습니다.


Util.include는 


Util.include = function(path,configs){
try{
if(typeof path==='object' && typeof configs ==='undefined'){
var configs = path;
path = configs.path;
if(typeof path==='undefined')
throw new Error('path is Undefined');
}

var async =configs!==undefined ?
(configs.async!==undefined ?
configs.async : true) : true;
var pathArr = path.replace(/\.js/gi,'').split('/');
var fullPath = Util.basePath+pathArr.join('/')+'.js';
var jsfileName = configs!==undefined?
(configs.jsfileName !==undefined ?
configs.jsfileName : path) :
path;
var scriptTags = document.createElement('script');
scriptTags.setAttribute('src',fullPath);
scriptTags.async = async;

var onload = configs!==undefined?
configs.onload :
'undefined';
if(typeof onload==='function'){
scriptTags.onload = function (){
onload(fullPath);
}
}
else {
scriptTags.onload = function(){
console.log('onLoad Script >> '+ fullPath);
}
};
document.body.insertBefore(scriptTags,document.body.lastChild);
}
catch(err){
console.error(err);
}
}


lib 형태를 만들고 싶어서 기본 base Path 에 include 할 js들은 gdl.js에서  지정하고 include 합니다.


현재는 동기적으로 하기 위해서 위에 initialize 에서 보시면  async:fale를 지정하였습니다.


해당 index.html 을 console.log에서 확인해보면




위의 코드에서 gdlAjax.js 와 tempEvent.js를  로딩합니다. 


async:false로 지정하였기 때문에 100번을 새로고침해도 같은 형태로 로딩이 됩니다.


테스트 해본결과 async:true 로 하게되면 5번에 1~2번 정도는 순서가 바뀝니다.(비동기 이기 때문)


다음시간에는 해당 페이지를 조금 꾸미고


Button 먼저 만들어 보도록 하겠습니다.


긴글 읽어주셔서 감사합니다!


+ Recent posts