새로운 북마크 작성 가능, 삭제 가능, 링크 연결,
모달을 활용해서 북마크를 생성한다.
모달을 바로 보여주기.
// 모달 보여주기. 입력에 집중.
function showModal() {
modal.classList.add('show-modal');
websiteNameEl.focus();
}
focus를 활용해 모달의 입력창에 커서가 이미 존재하도록 한다.
focus
모달 이벤트를 줘서 상호작용 활성화.
// 모달 이벤트 추가.
modalShow.addEventListener('click', showModal);
modalClose.addEventListener('click', () => modal.classList.remove('show-modal'));
버튼을 누르면 모달이 뜨고 X를 누르면 창이 없어짐.
거기에 더해 모달창의 바깥을 누르면 자동으로 모달이 없어지며 기본창으로 가길 원한다.
모달의 ID는 show-modal, 바깥은 modal-container show-modal이므로
window.addEventListener('click', (e) => (e.target === modal ? modal.classList.remove('show-modal') : false));
윈도우에서 클릭시 그 부분이 모달이 아닌 바깥이면 거짓이 되어 창이 사라짐.
// 제출 이벤트
bookmarkForm.addEventListener('submit', storeBookmark);
function storeBookmark(e){
e.preventDefault();
const nameValue = websiteNameEl.value;
let urlValue = websiteUrlEl.value;
if(!urlValue.includes('http://','https://')){
//주소코드를 가지고 있지 않을때. 즉 입력받은 값이 정상 사이트 주소가 아니면.
urlValue = `https://${urlValue}`;
//대신 주소 형식을 맞춰준다.
}
}
주소를 검증하기 위해서 정규표현식을 사용.
정규표현식이란?
따라서 정상 주소인지를 확인하는 코드는 다음과 같다.
// 정상 주소인지 확인.
function validate(nameValue, urlValue) {
const expression = /(https)?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/g;
const regex = new RegExp(expression);
if (!nameValue || !urlValue) {
//주소,제목 둘중 하나라도 입력이 안되면.
alert('주소와 제목을 입력해 주세요.');
return false;
}
if (!urlValue.match(regex)) {
//주소가 정규식으로 파악한 정상 주소와 맞지 않으면.
alert('정상적인 주소를 입력해 주세요.');
return false;
}
// 정상.
return true;
}
validate활용.
if(!validate(nameValue, urlValue)){
//적합의 역인 경우이므로 만약 주소값이 적합하지 않으면 거짓 반환.
return false;
}
//북마크 저장하기.
const bookmark = {
name: nameValue,
url: urlValue,
};
//push로 저장.
bookmark.push(bookmark);
//북마크 입력창은 리셋.
bookmarkForm.reset();
//다시 입력창에 커서 포커스
websiteNameEl.focus();
저장.
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
출력.
// Fetch 북마크
function fetchBookmarks() {
// 값이 있으면 북마크를 저장소에서 가져오기.
if (localStorage.getItem('bookmarks')) {
bookmarks = JSON.parse(localStorage.getItem('bookmarks'));
} else {
// 값이 없으면 저장소에 북마크 기본 배열 생성.
bookmarks = [
{
name: 'Jacinto Design',
url: 'http://jacinto.design',
},
];
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
}
buildBookmarks();
}
// 로드 될때 기본으로 fetch 실행해서 기본 북마크 생성.
fetchBookmarks();
// 문서에 북마크 생성.
function buildBookmarks() {
// 일단 북마크 요소들을 청소.
bookmarksContainer.textContent = '';
// Build items
bookmarks.forEach((bookmark) => {
//구조분해 할당.
const { name, url } = bookmark;
// Item 생성
const item = document.createElement('div');
item.classList.add('item');
// Icon 생성
const closeIcon = document.createElement('i');
closeIcon.classList.add('fas', 'fa-times');
closeIcon.setAttribute('title', 'Delete Bookmark');
closeIcon.setAttribute('onclick', `deleteBookmark('${url}')`);
// 파비콘 / 링크 생성
const linkInfo = document.createElement('div');
linkInfo.classList.add('name');
// 파비콘--- 웹상에서 그 창을 간단히 표현하는 아이콘
const favicon = document.createElement('img');
favicon.setAttribute('src', `https://s2.googleusercontent.com/s2/favicons?domain=${url}`);
favicon.setAttribute('alt', 'Favicon');
// 링크
const link = document.createElement('a');
link.setAttribute('href', `${url}`);
link.setAttribute('target', '_blank');
link.textContent = name;
// 북마크 컨테이너에 할당하기.
linkInfo.append(favicon, link);
item.append(closeIcon, linkInfo);
bookmarksContainer.appendChild(item);
});
}
splice사용해 배열의 북마크 삭제.
// 북마크 삭제.
function deleteBookmark(url) {
// 북마크 배열 돌기.
bookmarks.forEach((bookmark, i) => {
if (bookmark.url === url) {
bookmarks.splice(i, 1);
//선택한 북마크 삭제.
}
});
// 로컬 저장소의 북마크 배열 업데이트, DOM 문서 재구성.
localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
fetchBookmarks();
}