개발자는 죽어서 코드를 남긴다
[php, JQuery] 국내 지역 리스트 형식으로 생성하기. [append 된 개체의 onclick 이벤트 작동이 안돼요. document의 onclick 이벤트가 두번씩 떠요.] 본문
[php, JQuery] 국내 지역 리스트 형식으로 생성하기. [append 된 개체의 onclick 이벤트 작동이 안돼요. document의 onclick 이벤트가 두번씩 떠요.]
PoDoll 2022. 9. 19. 15:05새로운 사이트를 만드려고 필요한 것을 정리하던 중에
사람인에서 쓰는것과 비슷한 지역구 선택 폼이 필요한것 같아서
기존에 쓰던 셀렉트 형식의 폼을 가져와서 리스트 형식으로 전환해주었다
지역구는 하드코딩이 되어있는 소스가 있어서 빌려와서 사용했다
소스 출처 : https://choiguevara88.tistory.com/4
PHP/JS 동적으로 바뀌는 행정구역 select 태그 만들기 [도시선택]
웹사이트를 구축하다 보면 사용자에게 정해진 행정구역의 값을 정확하게 입력받기 위해서 select 태그를 사용해야 할 경우가 발생한다. 첫 번째 select 태그에서 특별·광역시/도를 선택하면 두 번
choiguevara88.tistory.com
<?
function area_info($도="") {
$area_1 = array("서울특별시","부산광역시","대구광역시","인천광역시","광주광역시","대전광역시","울산광역시","세종특별자치시","경기도","강원도","충청북도","충청남도","전라북도","전라남도","경상북도","경상남도","제주특별자치도");
$area_2 = array();
$area_2["서울특별시"] = array("종로구","중구","용산구","성동구","광진구","동대문구","중랑구","성북구","강북구","도봉구","노원구","은평구","서대문구","마포구","양천구","강서구","구로구","금천구","영등포구","동작구","관악구","서초구","강남구","송파구","강동구");
$area_2["부산광역시"] = array("중구","서구","동구","영도구","부산진구","동래구","남구","북구","해운대구","사하구","금정구","강서구","연제구","수영구","사상구","기장군");
$area_2["대구광역시"] = array("중구","동구","서구","남구","북구","수성구","달서구","달성군");
$area_2["인천광역시"] = array("중구","동구","미추홀구","연수구","남동구","부평구","계양구","서구","강화군","옹진군");
$area_2["광주광역시"] = array("동구","서구","남구","북구","광산구");
$area_2["대전광역시"] = array("동구","중구","서구","유성구","대덕구");
$area_2["울산광역시"] = array("중구","남구","동구","북구","울주군");
$area_2["세종특별자치시"] = array("세종");
$area_2["경기도"] = array("수원시","성남시","의정부시","안양시","부천시","광명시","평택시","동두천시","안산시","고양시","과천시","구리시","남양주시","오산시","시흥시","군포시","의왕시","하남시","용인시","파주시","이천시","안성시","김포시","화성시","광주시","양주시","포천시","여주시","연천군","가평군","양평군");
$area_2["강원도"] = array("춘천시","원주시","강릉시","동해시","태백시","속초시","삼척시","홍천군","횡성군","영월군","평창군","정선군","철원군","화천군","양구군","인제군","고성군","양양군");
$area_2["충청북도"] = array("청주시","충주시","제천시","보은군","옥천군","영동군","진천군","괴산군","음성군","증평군","단양군");
$area_2["충청남도"] = array("천안시","공주시","보령시","아산시","서산시","논산시","계룡시","금산군","부여군","서천군","청양군","홍성군","예산군","태안군","당진시");
$area_2["전라북도"] = array("전주시","군산시","익산시","정읍시","남원시","김제시","완주군","진안군","무주군","장수군","임실군","순창군","고창군","부안군");
$area_2["전라남도"] = array("목포시","여수시","순천시","나주시","광양시","담양군","곡성군","구례군","고흥군","보성군","화순군","장흥군","강진군","해남군","영암군","무안군","함평군","영광군","장성군","완도군","진도군","신안군");
$area_2["경상북도"] = array("포항시","경주시","김천시","안동시","구미시","영주시","영천시","상주시","문경시","경산시","군위군","의성군","청송군","영양군","영덕군","청도군","고령군","성주군","칠곡군","예천군","봉화군","울진군","울릉군");
$area_2["경상남도"] = array("창원시","진주시","통영시","사천시","김해시","밀양시","거제시","양산시","의령군","함안군","창녕군","고성군","남해군","하동군","산청군","함양군","거창군","합천군");
$area_2["제주특별자치도"] = array("제주시","서귀포시");
if($도 == "") return $area_1;
else return $area_2[$도];
}
$area_list = area_info();
$area_list2 = area_info($area_list[0]);
?>
<table class="table1">
<tbody class="padding">
<tr>
<td>
<ul name="client_area" id="client_area" >
<? foreach($area_list AS $area) { ?>
<li value="<?=$area?>"><?=$area?></li>
<? } ?>
</ul>
</td>
</tr>
<tr>
<td><ul name="client_area2" id="client_area2">
<li value="">시/군/구</li>
</ul>
</td>
</tr>
</tbody>
</table>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(document).on("click","#client_area li", function(){
setArea2($(this).text());
});
$(document).on("click","#client_area2 li", function(){
console.log("client_area2의 하위요소 li가 선택되었습니다. text : " + $(this).text());
});
</script>
<script language="javascript">
function setArea2(area1) {
var areaArr = new Array();
<? foreach($area_list AS $area) { $areaArr = area_info($area); $areaTxt="";
foreach($areaArr AS $area2) { $areaTxt .= "'$area2',"; } $areaTxt = substr($areaTxt,0,-1); ?>
areaArr["<?=$area?>"] = [<?=$areaTxt?>];
<? } ?>
var html = "";
areaArr[area1].forEach(function(element){ html += "<li value='"+element+"'>"+element+"</li>"; });
$("ul[name='client_area2']").children('li').empty();
$("ul[name='client_area2']").children('li').append(html);
}
</script>
(지역구 이름을 필요한 형식으로 가공해주었다)
대충 이런식으로 #client_area 에 지역을 출력하고
해당지역을 누르면 #client_area2에 그 지역의 시/군/구가 출력이 되는 형식의 리스트가 완성되었다
처음에는
$('#client_area').children('li').click(function(){
alert("이벤트 시작!");
});
이런식으로 이벤트를 제어하려고 했는데
왠일인지 클릭을 해도 이벤트가 발생하지 않았다.
임의로 #clinet_area에 <li>를 하나 추가해주었더니 해당 리스트에는 제대로 클릭시 함수가 호출이 되었다
짐작가는 점이 리스트를 append로 붙여서 일어나는 상황인 것 같아서
document.on("click",(선택자),function()
이런 구문으로 바꾸어 주었더니 해결되었다.
(상위요소인 document를 통해 제어하는것이 차이점인데 확실한 지식이 없으므로 넘어가겠음)
이제 client_area2를 클릭하는 이벤트로 ajax를 통해 클릭한 리스트의 값을 받아 처리하면 될것 같은데
또다른 문제가 발생했다
하위요소를 클릭했을때 두번씩 함수가 호출되면서 한번은 client_area2의 모든 요소가 반응하는 식의 오류였다
찾아보니 Bubble up 혹은 버블링이라고 부르는 현상인데
자식요소의 click 이벤트에서, 자식요소를 감싸고 있는 부모태그가 반응하는 현상이라고 한다
해당현상의 해결 방법으로 제이쿼리의 off() 나 unbind()를 이용한 방법이 있는데
우리는 앞선 오류의 해결로 선택자를 바꾸어 document를 상위요소로 가지게 되었기 때문에
document.off("click").on("click",(선택자),function()
이런식으로 처리를 해버리면 document의 다른 클릭이벤트에 문제가 생길것이므로
자식요소의 이벤트가 부모요소로 전파되지 않도록 하는 함수 stopPropagation()를 이용해서 해결했다
최종적으로는
$(document).on("click","#client_area2 li", function(e){
e.stopPropagation();
console.log("client_area2의 하위요소 li가 선택되었습니다. text : " + $(this).text());
});
이런식으로 바꾸어 주면서 해결이 되었다
원하는대로 한번 클릭할때마다 클릭한 요소의 값을 받아오는 식으로 정리가 되었다.