재사용성 높이기
검색 기능 만들고 나서
검색 기능을 만들고서 잊고 있던 필수 기능으로
하나의 카드를 클릭하면 카드 데이터인 영화의 Id를 alert로 띄우기를 하려고 했어.
1. 전체 리스트로 처음에 보여줄 때 나타나는 카드를 클릭해도 alert를 띄우고
2. createElement문으로 동적으로 div를 만들어서 구성한 카드를 클릭해서 alert를 띄우려고 했는데
createElement문으로 만들 때 이전 전체 내용을 아예 지우고 새로 생성되기 때문에 alert기능도 따로
만들어줘야했어. 그렇게 alert기능 코드가 중복이 되서 나란히 보이길래 반복되는 코드를 쉽게
쓸 수 없을까 했지. 그래서 재사용할 수 있게 js파일을 따로 만들어서 script src속성으로
alert기능을 쓸 수 있게 불러와서 썼어.
alert기능을 js 파일로 따로 빼서 재사용해 봤어.
시도:
1. import, export
- alert.js에서 export const movieIdAlert로 내보내고 index.html문서에서 import해서 쓰려고 했더니 이런 cors오류가 났어.
Access to script at 'file:///C:/Users/user/~어쩌구 저장소4/search-feat/js/alert.js' from
origin 'null' has been blocked by CORS policy: Cross origin requests are only supported
for protocol schemes: http, data, isolated-app, chrome-extension, chrome, https, chrome-untrusted.
사용한 import 문
import { movieIdAlert } from "./js/alert.js"
- 이건 CDN이 아닌 직접 만들어서 쓰려면 로컬환경이 아니라 http나 https에서 사용해야해서
배포를 하고나서 쓸 수 있더라.
2. script의 src속성으로 외부폴더의 js파일을 가져오면서 import도 하면서 최상단에
const alert = movieIdAlert("Class", "card-content");
이렇게도 달아봤어 그리고 이때는 아예 필요한 $cardAll 변수 선언문도 같이 alert에 넣었는데
// alert.js - ex ) alert (`영화 Id : 123`)
const movieIdAlert = ({prop, className}) => {
const $cardAll = document.getElementsBy`${Class}`}(`"${className}"`);
// 전체카드 중에서
for (let i = 0; i < $cardAll.length; i++) {
//카드 하나 클릭 시,
$cardAll[i].addEventListener("click", async (event) => {
let oneTargetCardId = event.target.children[0].id;
alert(`영화 id : ${oneTargetCardId}`);
});
}
};
이런 구조였다보니,
1. 일단 받아오는 것도 객체로 씌워서 가져와서 안 됐을 뿐더러
2. getElementsBy~메서드 자체를 템플릿 리터럴로 쓰면 문자열로 들어가다보니 메서드의 역할을 잃게 되고
3. 제일 중요한
const $cardAll = document.getElementsBy`${Class}`}(`"${className}"`);
이 코드에서 값을 상속받아오지 않고 제대로 된 문장을 쓰더라도 작동이 안 됐어.
일단 이 코드가 들어있는 곳에서 해당 className을 가져올 곳이 없어서 필요가 없는 코드가 됐지.
해결
그래서 최종적으로,
1. 선언했던 movieIdAlert()를 할당한 alert변수를 없애고, body안에 script src 속성으로 alert.js를 불러와서 최하단에 두고
( export, import는 배포하면서 사용해보려고.)
2. 전체 카드가 할당된 prop과 alert에 보일 keyName을 가져오게 했어.
보다보니 children[0]의 내부 정보인 id부분도 상속값으로 대체할 수 있지 않을까 해서 수정해 보려고 해.
// alert.js - ex ) alert (`영화 Id : 123`)
// prop : 전체 카드가 할당된 값
const movieIdAlert = (keyName, prop) => {
// 전체카드(prop) 중에서
for (let i = 0; i < prop.length; i++) {
//카드 하나prop[i] 클릭 시,
prop[i].addEventListener("click", async (event) => {
let oneTargetCardId = event.target.children[0].id;
alert(`${keyName} : ${oneTargetCardId}`);
});
}
};
해결 전 HTML
<body>
<h1>최고 평점 영화 콜렉션</h1>
<h2>영화 검색 :</h2>
<input type="text" id="input" placeholder="영화 제목을 검색해 보세요" />
<button id="searchBtn" type="button">검색</button>
<div id="cards-container"></div>
<script> 아래 스크립트문 자리</script>
</body>
-해결 전 script 내부 js
-또~옥같이 중복으로 쓰이던 코드
const $cardAll = document.getElementsByClassName("card-content");
//전체카드 중에서
for (let i = 0; i < $cardAll.length; i++) {
//카드 하나 클릭 시,
$cardAll[i].addEventListener("click", async (event) => {
let onetargetCardId = event.target.children[0].id;
alert(`영화 id : ${onetargetCardId}`);
});
}
외부 js파일
- alert.js
- 영화 id보여주는 Alert
// alert.js - ex ) alert (`영화 Id : 123`)
const movieIdAlert = (keyName, prop) => {
// 전체카드 중에서
for (let i = 0; i < prop.length; i++) {
//카드 하나 클릭 시,
prop[i].addEventListener("click", async (event) => {
let onetargetCardId = event.target.children[0].id;
alert(`${keyName} : ${onetargetCardId}`);
});
}
};
- script 내부 js
- 재사용 후 코드
// 7. 찾은 키워드에 대한 카드 정보를 채우기
equalCardData.map((searchCard, i) => {
const $searchCardDiv = document.createElement("div");
$searchCardDiv.setAttribute("class", "card-content");
// Element.innerHTML은 incertAdjacentHTML("afterend", "");로 추후 수정해보기
// innerHTML은 script문으로 공격하면 text로 dom정보를 다 가져와서 XXS공격에 취약
$searchCardDiv.innerHTML = `
~대략 내용 있음~
`;
return $cards.append($searchCardDiv);
});
//전체카드 중에서
movieIdAlert("영화 id", $cardAll); // <= 이 두 곳에 적용됨
});
//카드 클릭 시, 클릭한 영화카드 id값 alert창에 띄우기
movieIdAlert("영화 id", $cardAll); // <=이 두 곳에 적용됨
});
느낀 점
- 두 번 길게 쓸 거 한 번에 줄여쓰니까 보기에도 좋고 쓰기 편한 것 같아.
- 보다보니 innerHTML를 쓰면 text로 받아와져서 내부 DOM태그 상태를 다 볼 수 있어서 스크립트 XSS공격에 취약하다길래 incertAdjacentHTML()메서드를 사용해서 수정해보려고.
*참고 사이트
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/export
- https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-%EB%AA%A8%EB%93%88-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-import-export-%EC%A0%95%EB%A6%AC
'개발일지' 카테고리의 다른 글
[TIL] 24_0105 실행 컨텍스트, 호이스팅 (0) | 2024.01.05 |
---|---|
[TIL] 24_0104 선택요구사항까지 마치고, (0) | 2024.01.04 |
[TIL] 24_0102 검색 기능과 setAtrribute()와 classList.add() (2) | 2024.01.02 |
[TIL] 23_1229 js 문법과 검색 기능에 필요한 함수들 (0) | 2023.12.29 |
[TIL] 23_1228 코드 리뷰, 코드 리팩토링 (0) | 2023.12.28 |