중복코드 개선(for each 예시)
본문 바로가기

Frontend

중복코드 개선(for each 예시)

문제인식

제품 썸네일에 마우스를 가져다댈때마다 아이템의 상세정보와 링크버튼이 마치 호버효과처럼 뜨게해야해서

mouseenter과 mouseleave 이벤트리스너로 만들었음. 제품이 많다보니 중복코드 발생

중복코드

		document.querySelector(".iot_thumb.item_1").addEventListener('mouseenter', function (event) {
			document.querySelector(".thumb_hover1").style.display = 'block';
		})
		document.querySelector(".iot_thumb.item_1").addEventListener('mouseleave', function (event) {
			document.querySelector(".thumb_hover1").style.display = 'none';
		})

		document.querySelector(".iot_thumb.item_2").addEventListener('mouseenter', function (event) {
			document.querySelector(".thumb_hover2").style.display = 'block';
		})
		document.querySelector(".iot_thumb.item_2").addEventListener('mouseleave', function (event) {
			document.querySelector(".thumb_hover2").style.display = 'none';
		})

		document.querySelector(".iot_thumb.item_3").addEventListener('mouseenter', function (event) {
			document.querySelector(".thumb_hover3").style.display = 'block';
		})
		document.querySelector(".iot_thumb.item_3").addEventListener('mouseleave', function (event) {
			document.querySelector(".thumb_hover3").style.display = 'none';
		})

		document.querySelector(".iot_thumb.item_4").addEventListener('mouseenter', function (event) {
			document.querySelector(".thumb_hover4").style.display = 'block';
		})
		document.querySelector(".iot_thumb.item_4").addEventListener('mouseleave', function (event) {
			document.querySelector(".thumb_hover4").style.display = 'none';
		})

 

수십개가넘지만 생략..

 

1차시도

	for(let i = 1; i<15; i++){
		document.querySelector(".iot_thumb.item_"+ i+"").addEventListener('mouseenter', function (event) {
			document.querySelector(".thumb_hover" + i + "").style.display = 'block';
		})
		document.querySelector(".iot_thumb.item_" + i + "").addEventListener('mouseleave', function (event) {
			document.querySelector(".thumb_hover" + i + "").style.display = 'none';
		})
	}

 

단순히 for문을 돌리면되지않을까?

며칠안가서 코드의 문제점을 발견하였다.

 

우선 제품을 등록할때마다 for문안에 i<15를 바꿔줘야하는데 이건 맥시멈값으로 1000~으로 잡으면되긴하면된다쳐도

 

제일 큰 문제는 예를들어 제품2를 지워달라했을때 .iot_thumb.item_2가 있는 코드 전부를 지워버리면

for문안의 i=2가 사라지는셈이된다 즉 i가 1,3,4,5,6~밖에없으므로 for문을 돌릴때 에러가 발생한다!!!!

 

i = 2인 제품코드를 지울경우 에러발생

 

이경우 .iot_thumb.item_1을제외한 모든제품코드 수정해야하는데 만약 제품이 수백개일경우는 일일이 찾아서 수정해야하므로 실로 문제가많은 코드라 할수있다.

 

2차시도

배열과 forEach문을 사용해보자.

맨날 개념이 햇갈려서 잠깐 정리.

['a','b','c'].forEach(function(item,index,array){
    console.log(item,index,array)
});

item은 a,b,c를 각각의미하고 index는 아이템들의 index번호, array는 배열그자체를 의미하고 item, index, array를 꼭다 안써도된다.

화살표함수도 오케이!

 

	let item_elements = [
		'.iot_thumb.item_1'
		, '.iot_thumb.item_2'
		, '.iot_thumb.item_3'
		, '.iot_thumb.item_4'
		, '.iot_thumb.item_5'
		, '.iot_thumb.item_6'
		, '.iot_thumb.item_7'
		, '.iot_thumb.item_8'
		, '.iot_thumb.item_9'
		, '.iot_thumb.item_10'
		, '.iot_thumb.item_11'
		, '.iot_thumb.item_12'
		, '.iot_thumb.item_13'
		, '.iot_thumb.item_14'
	]

	item_elements.forEach((item, index) => {
		document.querySelector(item).addEventListener('mouseenter', () => {
			document.querySelector('.thumb_hover' + (index+1) + '').style.display = 'block'
		})
	})

	item_elements.forEach((item, index) => {
		document.querySelector(item).addEventListener('mouseleave', () => {
			document.querySelector('.thumb_hover' + (index+1) + '').style.display = 'none'
		})
	})

 

다행히해결됨. 예를들어 iot_thumb_item_3 제품에 마우스를 가져다대면 그에 해당되는

.thumb_hover3값이 뜨게했다.

index는 0부터시작하므로 +1을 해줬는데 괄호를 안하니까 '01'로 출력되므로 주의

 

3차시도 childNodes

아악 두번째 item을 지워보니 index+1이 문제인듯하다. 제품번호가 밀리게되면서 제품3에 마우스커서를 가져다대면 제품2에 효과가발생함. 그래서 고민하다가 childNodes를 적용하니 해결됨.. 

	let item_elements = [
		'.iot_thumb.item_1'
		// , '.iot_thumb.item_2'
		, '.iot_thumb.item_3'
		, '.iot_thumb.item_4'
		, '.iot_thumb.item_5'
		, '.iot_thumb.item_6'
		, '.iot_thumb.item_7'
		, '.iot_thumb.item_8'
		, '.iot_thumb.item_9'
		, '.iot_thumb.item_10'
		, '.iot_thumb.item_11'
		, '.iot_thumb.item_12'
		, '.iot_thumb.item_13'
		, '.iot_thumb.item_14'
	]

	item_elements.forEach((item, index) => {
		document.querySelector(item).addEventListener('mouseenter', () => {
			// document.querySelector('.thumb_hover' + (index+1)+'').style.display = 'block'
			document.querySelector(item).childNodes[1].style.display = 'block'
		})
	})

	item_elements.forEach((item, index) => {
		document.querySelector(item).addEventListener('mouseleave', () => {
			// document.querySelector('.thumb_hover'+(index+1)+'').style.display = 'none'
			document.querySelector(item).childNodes[1].style.display = 'none'
		})
	})

forEach를 왜쓰는지 어렴풋이 이유를 알게됫고 직접 활용해 성공하니 기분이좋다.

 

반응형