이벤트 위임 방법에 대해 모르던 시절 구현한건 코드가 오질나게 길죠
이벤트 위임을 사용해서 좀 더 줄여봤습니다.
HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>커스텀 셀렉트 - 이벤트 위임</title>
<link href="custom_select.css" rel="stylesheet" type="text/css"/>
<script src="custom_select.js" defer></script>
</head>
<body>
<div class="myDiv">
<select>
<option>test__01</option>
<option>test__02</option>
<option>test__03test__03test__03</option>
</select>
<!--
<div class="sel__cont">
<div class="sel__selected" data-select="result">test__01</div>
<ul class="sel__ul off">
<li data-select="item">test__01</li>
<li data-select="item">test__02</li>
<li data-select="item">test__03test__03test__03</li>
</ul>
</div>
-->
</div><!-- -->
<div class="myDiv">
<select>
<option>hello__a</option>
<option>hello__b</option>
<option>hello__c</option>
</select>
</div><!-- -->
<div class="myDiv">
<select>
<option>world__01</option>
<option>world__02</option>
<option>world__03</option>
</select>
</div><!-- -->
</body>
</html>
|
cs |
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
@charset "utf-8";
*{margin:0;padding:0;}
li{list-style-type:none;}
html,body{font-size:20px;}
/* select{display:none;} */
.myDiv{
display:flex;flex-wrap:wrap;
align-items:center;
position:relative;
width:90%;
margin:1rem auto; padding:1rem;
background:#eee;}
select{opacity:.5;font-family:inherit;font-size:inherit;color:inherit;}
.sel__cont{position:relative;}
.sel__selected{
position:relative;
padding:.5em 3em .5em 1em;
background:#fff; border:1px solid rgb(42, 55, 112);
font-weight:bold;color:rgb(21, 20, 46);
cursor:pointer;}
.sel__selected::after{
content:'';display:block;position:absolute;
top:calc(50% - .3em);right:.8em;
transform:rotate(45deg);
width:.4em;height:.4em;
border:2px solid #d2d2d2;border-width:0 4px 4px 0;}
.sel__ul{
position:absolute; z-index:10;
top:99%;left:0;
border-top:1px solid #d2d2d2;}
.sel__ul.off{display:none;}
.sel__ul li{
position:relative;
padding:.5em 3em .5em 1em;
background:#fff;
border:1px solid #ccc;border-top:none;
cursor:pointer;}
.sel__ul li:hover{
background:rgb(42, 55, 112);color:#fff;}
|
cs |
JS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
const select_all = document.getElementsByTagName('SELECT');
/* 01.CUSTOM SELECT 자동 생성 */
let sel__cont, sel__selected, sel__ul, sel__li;
let opt_all;
for(let sel of select_all){ makeSelect(sel); }
function makeSelect(sel){
sel__cont = document.createElement('DIV');
sel__cont.classList.add('sel__cont');
sel__cont.setAttribute('data-select', 'sect')
sel__selected = document.createElement('DIV');
sel__selected.classList.add('sel__selected');
sel__selected.setAttribute('data-select','result');
sel__ul = document.createElement('UL');
sel__ul.classList.add('sel__ul');
sel__ul.classList.add('off');
opt_all = sel.getElementsByTagName('OPTION');
sel__selected.innerHTML = opt_all[0].innerHTML;
for(let opt of opt_all){
sel__li = document.createElement('LI');
sel__li.setAttribute('data-select','item')
sel__li.innerHTML = opt.innerHTML;
sel__ul.appendChild(sel__li);}
sel__cont.appendChild(sel__selected);
sel__cont.appendChild(sel__ul);
sel.parentElement.appendChild(sel__cont);
}//makeSelect
/* 02. 이벤트 위임으로 클릭시 받아옴 */
const sect_cus = document.querySelectorAll("[data-select='sect']");
const result = document.querySelectorAll("[data-select='result']");
for(let sect of sect_cus){
sect.addEventListener('click',e => startSelect(e));
}
function startSelect(e){
const target = e.target;
switch(target.dataset.select){
case "result" :
target.nextElementSibling.classList.remove('off');
break;
case "item" :
changeResult(target);
realSelect(target);
break;
}
}//startSelect
function changeResult(tg){
//custom select의 result 값 바꾸기
const thisVal = tg.innerHTML;
const thisResult = tg.parentElement.previousElementSibling;
thisResult.innerHTML = thisVal;
tg.parentElement.classList.add('off');
}//changeResult
function realSelect(tg){
//찐 select 선택되게 하기
const realSelect = tg.parentElement.parentElement.previousElementSibling;
const realOption = realSelect.children;
const thisIndex = Array.prototype.indexOf.call(tg.parentElement.children, tg);
realOption[thisIndex].selected = true;
}//realSelect
|
cs |
코드 자체는 한 6줄 정도 더 늘어났지만 개인적으로는 함수도 분리하고 그래서인지 더 알아보기 쉽다고 생각해욤
밑에는 소스코드 ^_^
'CSS&JS > ⚡Thinkers' 카테고리의 다른 글
twitter app header처럼 vanilla JS로 스크롤에 따라 내려오고 올라가는 헤더 만들기(2) (0) | 2021.06.10 |
---|---|
marquee 텍스트 효과 CSS로 구현하기 (0) | 2021.05.07 |
fixed thead(스크롤 할 때 부모 엘리먼트에 fix되는 thead를 만들고싶다면) (0) | 2021.04.14 |
twitter app header처럼 vanilla JS로 스크롤에 따라 내려오고 올라가는 헤더 만들기 (0) | 2021.04.09 |
<canvas>로 피자 조각(파이) 그리기 - 삼각함수 사용 (0) | 2021.04.03 |