// 아코디언 메뉴 눌렀을 때(class = show) 해당 jsp 파일 불러오기
$('.accordion-button').on('click', function(){
var myTarget = $(this).attr('data-bs-target'); // 내가 누른 버튼의 타겟 찾음
var targetId = myTarget.substr(1, myTarget.length); // # 뺌
var targetId2 = document.getElementById(targetId);
console.log("targetId : " + targetId);
console.log("targetId2 : " + targetId2);
setTimeout(function() { // show 실행까지 기다림 ( 0.4s )
var targetClass = $(targetId2).attr('class');
if( targetClass.indexOf('show') >= 0 ) {
console.log("show 있음 : " + targetClass);
var subStrId = targetId.substr(0, targetId.indexOf('Div'));
$(targetId2).find(".accordion-body").load("/MN/" + subStrId + ".do");
console.log("targetId : " + targetId + ", targetId : " + subStrId );
}
}, 400);
});
부트스트랩 아코디언 메뉴 사용시 메뉴 눌렀을 때 class 부분에 show가 생성되면서 열리는 걸 감지 후 열리도록 만듦. onclikc 당시에 show가 바로 추가 되는 게 아니기 때문에 setTimeout()으로 최소 0.4초 간격을 주었는데 이것 때문에 너무 늦게 열리는 게 단점이 되었다. 그래서 새로운 방법을 구상중
$(function(){
const target = document.querySelector('#frontRefMenu');
var showFinder = new MutationObserver(function(show){
//show.forEach(function(show){
console.log('변형 감지 : ' + show);
//});
});
// attributes, childList, characterData : 기본적으로 true 세팅 돼 있어야만 오류 없음
// ==> 여기까지는 자식 요소까지만 감지를 하기 때문에 subtree 이것까지 추가를 해줘야 됨
const option = { attributes: true,
childList: true,
characterData: true,
subtree: true };
showFinder.observe(target, option);
});
두번 째는 DOM 변경 감시를 돕는 MutationObserver 생성자를 사용했다. body내의 변화를 감지하고 show가 생성 될 때를 읽어들여 div 안에 jsp 파일을 호출하도록 하기 위해서 이런 방법을 생각함. 가장 시간을 많이 잡아 먹는 부분이 option 설정 하는 부분이었는데 자손만 감지를 하도록 세팅하는 세가지(attributes, childList, characterData)에 추가 적으로 자식 안쪽으로도 감지를 해야 하기 때문에 subtree 이것까지 추가를 해줬다.
참고 사이트 - https://developer.mozilla.org/ko/docs/Web/API/MutationObserver
MutationObserver - Web API | MDN
MutationObserver 는 개발자들에게 DOM 변경 감시를 제공합니다. DOM3 이벤트 기술 설명서에 정의된 Mutation Events 를 대체합니다.
developer.mozilla.org
변형 감지 시 받은 객체는 : [object MutationRecord]
* 출력 방법은 아래
// [object MutationRecord] 출력 방법
show.forEach((show) => console.log());
/* mome
show.forEach(function(show){
console.log( show ); // 객체 정보 출력
console.log( show.target ); // target 내용 출력
//console.log( 'target' in show ); // true false 출력
});
*/
항상 까먹는 객체 콘솔 출력 방법 ..
** show.forEach((show) => console.log());
이걸 사용할 때 에러가 잘 나서
** show.forEach(function(show) {
console.log();
});
이렇게 사용했다.
더 최적화 시키기 위해서 1번 2번의 방법을 합쳐서 타깃을 body가 아니라 내가 누르는 버튼의 연결 돼 있는 div로 잡았다. 방대한 요소들을 지켜 보는 것보다 이 편이 더 과부화를 줄일 수 있지 않을까 싶어 생각해 냄
// 아코디언 메뉴 안에 jsp 파일 호출을 위한 함수
$('.accordion-button').click(function(){
// 메뉴 선택 시 지켜 볼 타깃
const myTarget = $(this).attr('data-bs-target'); // 선택한 메뉴의 div Id 읽음
const targetId = myTarget.substr(1, myTarget.length); // # 뺌
const target = document.getElementById(targetId);
// 닫기 위해 메뉴를 누르는 경우도 있으니, class에 show가 생길 때만 감지
var showFinder = new MutationObserver(function(show){
show.forEach(function(show) {
if($(show.target).hasClass('show')) { // class에 show가 생겼을 때
const subStrId = targetId.substr(0, targetId.indexOf('Div'));
// 페이지 호출
$(target).find(".accordion-body")
.load("/MN/" + subStrId + ".do");
} else {
}
});
});
// * MutationObserver 옵션 설정
// attributes, childList, characterData : 기본 세팅이 돼 있어야만 오류 없음
// ==> 여기까지는 자식 요소까지만 감지를 하기 때문에 subtree 이것까지 추가를 해줘야 됨
const option = {
attributes: true,
childList: true,
characterData: true,
subtree: true
};
showFinder.observe(target, option); // 감지 시작
});
맨날 사용하는 방법 대신에 새로운 생성자를 사용해 봤는데 알아가는 재미가 있었다. 하루 꼬박 붙잡고 있었지만 역시 다 풀고 나니까 뿌듯!! 일단 만들어 놓은 함수들 정리 좀 해놓고, 검색 후에 아코디언 메뉴 열려서 문자열 찾는 기능도 만들고 싶음!!
(+) 여기서 또 문제!!
변경 감지 시 같은 id값을 3~9번까지 호출하는 문제 때문에 load로 페이지 호출 뒤 break문을 사용해 봤다.
// 페이지 호출
$(target).find(".accordion-body")
.load("/MN/" + subStrId + ".do");
break;
하지만 $.each / $.forEach문 사용할 때 break를 사용하면
Uncaught SyntaxError: Illegal break statement
이러한 에러가 뜨기 때문에(일반 반복문이 아니라 배열 및 객체를 순회할 때마다 callback을 실행하는 함수 라서 사용 못 함) 함수를 따로 떼어내서 return을 사용하면 된다고 함.
참고 사이트 - https://yeonyeon.tistory.com/7
[jQuery] Uncaught SyntaxError: Illegal break statement
javascript, jQuery 오류 Uncaught SyntaxError: Illegal break statement $.each() 함수에서 break; 문을 사용하면 위와 같은 오류가 뜬다. for문이나 while문 같은 반복문을 쓸 때처럼 each문에서도 사용할 수 있다고 생각
yeonyeon.tistory.com
일반 배열이라면 예제들을 보고 요리조리 따라해볼텐데~~ MutationRecord 객체의 경우 내가 잘 못 하는 건지 함수를 따로 떼내어서 return 하려고 하면 배열이 아니기 때문에 작동이 안 된다는 오류가 자꾸 떴다. 반복 호출만 막으면 되는 거 아니야? 싶어서 결국엔 아래의 방법을 택했다.
MutationObserver 생성자 호출 전에
let num = 0; 숫자형 변수 선언
변경 감지 후 if문에 ( ... && num == 0) 추가
페이지 호출 후 num++ 하면 끝~~~~
// 아코디언 메뉴 안에 jsp 파일 호출을 위한 함수
$('.accordion-button').click(function(){
// 메뉴 선택 시 지켜 볼 타깃 선정
const myTarget = $(this).attr('data-bs-target');
const targetId = myTarget.substr(1, myTarget.length); // # 빼고 아이디만 갖고 옴
const target = document.getElementById(targetId);
// forEach문에서는 break 사용 불가능. 변수로 중복 실행 방지
let num = 0;
// 닫기 위해 메뉴를 누르는 경우도 있으니, class에 show가 생길 때만 감지
var showFinder = new MutationObserver(function(show){
show.forEach(function(show) {
if($(show.target).hasClass('show') && num == 0) { // class에 show가 생겼을 때 딱 한 번 실행
console.log($(show.target).attr('id'));
console.log(num);
const subStrId = targetId.substr(0, targetId.indexOf('Div'));
// 페이지 호출
$(target).find(".accordion-body")
.load("/MN/" + subStrId + ".do");
num++;
}
});
});
// * MutationObserver 옵션 설정
// attributes, childList, characterData : 기본 세팅이 돼 있어야만 오류 없음
// ==> 여기까지는 자식 요소까지만 감지를 하기 때문에 subtree 이것까지 추가를 해줘야 됨
const option = {
attributes: true,
childList: true,
characterData: true,
subtree: true
};
// 감지 시작
showFinder.observe(target, option);
});
'개발일지 > JavaScript + jquery' 카테고리의 다른 글
substr 사용 금지 (0) | 2024.09.10 |
---|---|
[JavaScript] 인쇄 기능 재설계 (0) | 2023.01.30 |
[jquery] ajax 처리시 한 번에 데이터 전달 - serialize() (0) | 2022.07.06 |
[jquery] 프론트 단에서 모바일 구분하기 (0) | 2022.07.06 |
[JavaScript] radio check div 숨기기/표시하기 문제해결 (0) | 2022.04.16 |