📒 Examples
📌 Note 만들기
Array.splice(인덱스, 갯수)
: 특정 인덱스의 아이템을 삭제
.prepend()
메서드는 선택한 요소의 시작 부분에 지정된 내용을 삽입 (끝에 추가하려면 .add()
)
<style>
*{
box-sizing: border-box;
}
#container{
display : grid;
grid-template-columns: repeat(2,minmax(0, 1fr));
gap : 1rem;
}
textarea{
width : 100%; height : 12rem; padding : 1rem; border : none;
box-shadow: 0 0 10px #888; outline : none; resize : none;
}
#add-btn{
background-color: #333; color : #fff; border : none;
padding : 0.5rem 0.75rem; margin : 1rem 0; font-size: 1rem;
cursor: pointer;
}
#add-btn:hover{
background-color: #222;;
}
</style>
<button id="add-btn">New Note + </button>
<div id="container"></div>
<script>
var container = document.getElementById("container");
var addBtn = document.getElementById("add-btn");
var notes = [];
function saveData(notes){
localStorage.setItem("noteStorage", JSON.stringify(notes));
}
function seedData(){
var seed = [{ id : "n0", content : "첫번째 메모"}];
saveData(seed);
}
if(!localStorage.getItem("noteStorage")){
seedData();
}
document.addEventListener("DOMContentLoaded", getNotes);
addBtn.addEventListener("click", addNote);
function getNotes(){
notes = JSON.parse(localStorage.getItem("noteStorage"));
console.log(notes);
for(var i = 0; i<notes.length; i++){
createNoteElement(notes[i].id, notes[i].content);
}
}
function addNote(){
var newNote = { id : "n" + Date.now(), content : ""};
notes.push(newNote);
saveData(notes);
createNoteElement(newNote.id, newNote.content);
}
function editNote(id, content){
for(var i = 0; i<notes.length; i++){
if(notes[i].id === id){
notes[i].content = content;
}
}
}
function deleteNote(id, noteElement){
for(var i = 0; i<notes.length; i++){
if(notes[i].id === id){
notes.splice(i, 1);
}
}
saveData(notes);
noteElement.remove();
}
function createNoteElement(id, content){
var noteElement = document.createElement("textarea");
noteElement.value = content;
noteElement.addEventListener("change", function(){
editNote(id, this.value);
});
noteElement.addEventListener("dblclick", function(){
deleteNote(id, this);
})
container.prepend(noteElement);
}
</script>
📌 JS Image Editor
- canvas(캔버스), ctx(펜)이라고 생각
"load"
: 이미지를 로드하는 이벤트
.naturalWidth;
, .naturalHeight;
: 원본 너비, 높이
.drawImage(이미지엘리먼트, x, y)
: 캔버스에 이미지를 배치한다.
.nextElementSibling
: 이 속성은 동일한 트리 수준의 다음 요소를 반환한다.
다음 코드의 element.nextElementSibling.textContent = value;
에서는 <p>
엘리먼트가 된다.(그래서 수치 조정할때 value값 계속 바뀜)
<style>
*{
box-sizing: border-box;
margin : 0; padding : 0;
}
nav {
position : fixed;
padding : 0 1rem;
top : 0; left : 0;
width : 250px; height: 100vh;
}
.title{
display : flex;
flex-direction: column;
height: 8rem;
justify-content: center;
}
.filter-group{
margin : 1rem 0;
}
label{
display : block;
font-weight: 600;
}
.filter-input{
width : 100%;
}
main {
margin-left : 250px;
padding : 4rem;
height: 100vh;
background-color: #333;
overflow : auto;
}
</style>
<nav>
<h1 class=" title">JS Image Editor 🎨</h1>
<div class="filter-group">
<label for="brightness">Brightness</label>
<input type="range"name = "brightness" class="filter-input"
min ="0" max="200" value="100" oninput="setFilter(this)">
<p class="filter-value">100</p>
</div>
<div class="filter-group">
<label for="saturate">Saturate</label>
<input type="range" name="saturate" class="filter-input"
min="0" max="200" value="100" oninput ="setFilter(this)">
<p class="filter-value">100</p>
</div>
<div class="filter-group">
<label for="invert">Invert</label>
<input type="range" name="invert" class="filter-input"
min="0" max="100" value="0" oninput="setFilter(this)">
<p class="filter-value">0</p>
</div>
<div class="filter-group">
<label for="blur">Blur</label>
<input type="range" name="blur" class="filter-input"
min="0" max="10" value = "0" oninput="setFilter(this)">
<p class="filter-value">0</p>
</div>
</nav>
<main>
<canvas id="canvas"></canvas>
</main>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var UNIT = {
brightness : "%",
saturate : "%",
invert : "%",
blur : "px",
}
var filter = {};
var imgElement = new Image();
imgElement.src = "cat.jpg"
imgElement.addEventListener("load", function(){
canvas.width = imgElement.naturalWidth;
canvas.height = imgElement.naturalHeight;
render();
});
function render(){
ctx.drawImage(imgElement, 0, 0);
}
function setFilter(element){
var name = element.name;
var value = element.value;
filter[name] = value + UNIT[name];
console.log(filter);
var filterInString = "";
for(var key in filter){
filterInString += `${key}(${filter[key]}) `;
}
console.log(filterInString);
ctx.filter = filterInString.trim();
render();
element.nextElementSibling.textContent = value;
}
</script>
📌 URL(path, query)
1 SPA (Single Page Application)의 구조
자바스크립트를 사용하여 화면을 업데이트한다
속도가 빠르고 화면 전환이 부드럽다.
2 URL (Uniform Resource Locator)
웹사이트/서버의 주소
예) https://google.com/news/sports/?page=1
- URL 구조 분석
1) 경로
리소스의 경로
예) https://google.com/news/sports
2) 쿼리 parameter
url안에 작은 데이터를 전송할 때 사용한다
path?key=value의 형태
예) news/sports/?page=1
3) location hash
웹페이지에서 특정한 지점을 찾을 때 사용한다.
url#hash
예) news/sports/?page=1#lastArticle
3 Router
요청 URL과 적절한 리소스를 연결한다.
<style>
a{
color : #000;
}
</style>
<nav>
<ul>
<li>
<a href="#/">Home</a>
</li>
<li>
<a href="#/posts">Posts</a>
</li>
<li>
<a href="#/contact">Contact</a>
</li>
</ul>
</nav>
<div id="root"></div>
<script>
var root = document.getElementById("root");
function parseUrl(url){
var hasQuery = url.indexOf("?") > -1;
var path, query;
if(hasQuery){
path = url.substring(url.indexOf("?"), -1),
query = url.substring(url.indexOf("?"))
} else {
path = url;
query = null;
}
return{ url, path, query } ;
}
document.addEventListener("DOMContentLoaded", hashRouter);
window.addEventListener("hashchange", hashRouter);
function hashRouter(){
var url = location.hash.substring(1);
console.log("원본 URL : ", url);
var urlData = parseUrl(url);
console.log("URL 파싱 결과 : \n", urlData);
var routes = [
{ path : "/", element : Home },
{ path : "/posts", element : Posts },
{path : "/post", element : Post },
{ path : "/contact", element : Contact },
]
for(var i=0; i<routes.length; i++){
if(routes[i].path === urlData.path){
root.innerHTML = routes[i].element(urlData.query);
}
}
}
function Home(){
return(`
<h1>Home</h1>
<p>Welcome to my blog.</p>
`);
}
function Posts(){
return(`
<h1>Posts</h1>
<ul>
<li>
<a href="#/post?postId=p1">Second post</a>
</li>
<li>
<a href=#/post?postId=p0">First post</a>
</li>
</ul>`)
}
function Post(query){
return(`
<h1>Post</h1>
<p>${query}</p>
`)
}
function Contact(){
return(`
<h1>Contact</h1>
<p>john@example.com</p>
`)
}
</script>