스크롤에 따라 메뉴 표시시키기
본문
안녕하세요!
모달창 안에서 좌측 탭을 누르면 우측 내용이 스크롤되거나, 반대로 우측에 마우스 스크롤링했을떄 좌측탭이 활성화 되게 작업하고있습니다.. 저번에도 글올렸는데 해결되지 않아서 다시올려요 ㅠㅠ....
1. 좌측메뉴 '클릭'했을떄 해당 섹션 스크롤링은 되지만 해당 메뉴탭에 .active되지않음 ...
2. 우측에서 스크롤링했을때도 .repairPage가 .modal-scroll 의 윗부분에 닿았을때 좌측탭 .active가 활성화되게 하고싶습니다.
클릭or스크롤 시 짝에 맞게 메뉴탭 활성화시키고싶은데 자꾸 세번쨰 탭에서만 active가 활성화되네요 ...
위 링크 응용한건데 제가 선택자를 잘못한건지 ..모달창띄운 상태로 저 동작을 하려니까 쉽지않네요
코드 수정 부탁드립니다 ..!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>스크롤메뉴</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="assets/js/script.js"></script>
<script type="text/javascript" src="https://code.jquery.com/ui/1.12.1/jquery-ui.js" ></script>
</head>
<style>
.apt-wrap {
width: 1200px;
height: auto;
margin: 0 auto;
padding-top: 74px;
min-height: calc( 1020px - 150px );
}
.modal-con .form-step {
display: none;
width: 82%;
height: 100%;
right: 0;
float: right;
}
.apt_box {
position: relative;
box-shadow: none;
border-radius: 10px;
border: solid 1px #DADCE0;
transition: all ease 0.2s;
padding: 0 0 0 30px;
}
.modal .modal-content.modal-content__form {
min-width: 900px;
max-width: 900px;
}
.modal-con .modal-con__menu li {
cursor: pointer;
font-size: 14px;
font-weight: 500;
display: block;
color: #9A9BA7;
transition: all ease 0.2s;
}
.modal-con .modal-con__menu li a {
cursor: pointer;
padding: 14px 21px;
font-size: 14px;
font-weight: 500;
display: block;
color: #9A9BA7;
transition: all ease 0.2s;
}
.modal-con .modal-con__menu li a {
padding: 14px 21px;
color: unset;
}
.modal-con .modal-con__menu li:hover, .modal-con .modal-con__menu li:active {
background: #F3F3F3;
color: #555969;
transition: all ease 0.2s;
}
.modal-content {
z-index: 10;
width: 50%;
position: absolute;
top: 50%;
transform: translateY( -50%);
}
.modal-con.modal-con__view .modal-con__menu li a.active {
background: #F3F3F3;
color: #555969;
}
.modal .modal-content.modal-content__form .box {
height: 720px;
}
.modal .box {
color: #000;
font-weight: 500!important;
padding: 0;
}
.modal-con {
overflow: hidden;
height: 600px;
scroll-behavior: smooth;
}
.modal-con .modal-con__menu {
position: absolute;
width: 18%;
height: calc( 100% - 108px );
left: 0;
padding-top: 12px;
border-right: solid 1px #E4E5ED;
background: #fff;
overflow-y: auto;
}
input#checkAll { display: none;}
html[data-current-page-index="0"] .repairPage-indicator {
transform:translateY(0);
}
.modal-scroll { scroll-behavior: smooth;}
</style>
<body>
<div id="apt" class="is-desktop">
<header class="is-flex is-justify-content-space-between is-align-items-center px-5 py-4">
</header>
<div class="apt-wrap">
<div class="mt-3 is-flex is-size-7 has-text-weight-medium">
<span style="color: #9A9BA7;">상단메뉴</span>
</div>
<div class="apt-content__body">
<div class="py-5">
<ul class="apt_table mt-3">
<li class="is-flex is-justify-content-space-between is-align-items-center mb-3">
<a href="javascript:void(0);" style="" class="is-block box apt_box clickMoveBox modalView p-3">
모달띄우기
</a>
<li class="is-flex is-justify-content-space-between is-align-items-center mb-3">
<a href="javascript:void(0);" style="" class="is-block box apt_box clickMoveBox modalView p-3">
모달띄우기
</a>
</li>
<li class="is-flex is-justify-content-space-between is-align-items-center mb-3">
<a href="javascript:void(0);" style="" class="is-block box apt_box clickMoveBox modalView p-3">
모달띄우기
</a>
</li>
<li class="is-flex is-justify-content-space-between is-align-items-center mb-3">
<a href="javascript:void(0);" style="" class="is-block box apt_box clickMoveBox modalView p-3">
모달띄우기
</a>
</li>
<li>
<div style="width: 100%; height: 1080px;"></div>
</li>
</ul>
</div>
</div>
</div>
<!------------------ 모달창--------------------------->
<div id="modalView" class="modal modal_view" style="/*display: none;*/">
<div class="modal-background"></div>
<div class="modal-content modal-content__form" style=" overflow: unset; ">
<div class="box">
<div class="afms-header__con is-flex is-justify-content-space-between is-align-items-center" style="height: 37px; background: #fff;">
<span class="header-icon">
<a href="javascript:void(0);" class="close_btn modal_close has-text-black">×</a>
</span>
</div>
<article>
<div class="modal-con modal-con__view">
<div class="modal-con__menu repairPage-indicator">
<ul style="height: calc( 100% - 108px );">
<li class="btnRepair"><a href="#repairPage-1">메뉴1-1</a></li>
<li class="btnRepair"><a href="#repairPage-2">메뉴1-2</a></li>
<li class="btnRepair"><a href="#repairPage-3">메뉴1-3</a></li>
<li class="tab_menu is-relative p-0" id="btnQuantity" style="border-top: solid 1px #E4E5ED">
<div class="media-content detail_view" style="cursor: pointer; padding: 14px 21px;">
<div class="is-flex is-align-items-center is-justify-content-space-between">
<div class="con_title is-flex is-align-items-self-end">
<span class="is-size-6" style="white-space: nowrap;">메뉴2-1</span>
</div>
</div>
</div>
<div class="media-content media-content__detail media-content__quantityDetail mb-3 has-background-white" style="overflow-x: unset; display: none;">
<div class="px-3 py-2">1.ㅇㅇㅇ</div>
<div class="px-3 py-2">2.ㅇㅇㅇ</div>
</div>
</li>
</ul>
</div>
<div class="form-step form-step__view current pt-0 repairPages" style="position: relative; ">
<div class="py-5 px-3" style="border-bottom: solid 1px #888888; position: fixed; top: 37px; background-color: #fff; z-index: 1; width: 82%;" >
<div class="is-flex is-align-items-end is-justify-content-space-between">
<span class="is-size-6 has-text-weight-semibold">메뉴리스트</span>
</div>
</div>
<div class="modal-scroll" style="position: absolute; height: 539px; width: 100%; bottom: 0; overflow: scroll">
<div class="py-5 repairPage repairPage-1" id="repairPage-1" style="border-bottom: solid 1px #888888;">
<span class="is-size-6 has-text-weight-semibold">메뉴1-1</span>
<div style="width: 100%; height: 650px; background: skyblue;"></div>
</div>
<div class="py-5 repairPage repairPage-2" id="repairPage-2" style="border-bottom: solid 1px #888888;">
<span class="is-size-6 has-text-weight-semibold">메뉴1-2</span>
<div style="width: 100%; height: 650px; background: skyblue;"></div>
</div>
<div class="pt-5 repairPage repairPage-3" id="repairPage-3" style="padding-bottom: 120px; ">
<div class="">
<span class="is-size-6 has-text-weight-semibold">메뉴1-3</span>
</div>
<div style="width: 100%; height: 650px; background: skyblue;"></div>
</div>
</div>
</div>
<div class="form-step form-step__viewQuantity form-step1 pt-5" style="padding-bottom: 80px;">
메뉴2-1
</div>
</div>
</article>
</div>
</div>
</div>
<!------------------ 모달창--------------------------->
</div>
</body>
<script>
//데이터조회 모달
$(document).on("click",".modalView",function(){
$(".modal_view").addClass("is-active");
$(".modal_view .form-step__view").css("display","inherit");
$(".modal_view .form-step__viewQuantity.form-step1").css("display","none");
$(".media-content__detail.media-content__quantityDetail").css("display","none");
$("html").css("overflow","hidden");
});
//데이터조회>상세물량산출내역>셀렉트박스 오픈
//데이터조회 좌측 탭메뉴에서 화면전환
// $(document).ready(function(){
//
// $('.modal_view .modal-con .modal-con__menu li').click(function(){
//
// var tab_id = $(this).attr('data-tab');
//
// $('.modal_view .modal-con .modal-con__menu li').removeClass('current');
// // $('.modal_view .form-step').removeClass('current');
//
// $(this).addClass('current');
// $("#"+tab_id).addClass('current');
// })
// })
//데이터조회 좌측 탭메뉴 스크롤링
// $(".btnRepairScroll").click(function() {
// //스크롤링 추가
// var scrolldiv = $(this).data("scrolldiv");
//
// location.hash = "#" + scrolldiv;
// // var offset = $("#"+scrolldiv+"").offset(); // Contains .top and .left
// //
// // if(scrolldiv == "repairInfo"){
// // $('.modal_view .modal-con').animate({
// // scrollTop: 0 });
// // }else{
// // $('.modal_view .modal-con').animate({
// // scrollTop: offset.top });
// // }
// });
//데이터조회 좌측 탭메뉴 스크롤링
$('.repairPage-indicator > li > a').click(function(e) {
var href = $(this).attr('href');
var targetTop = $(href).offset().top;
/*
// 한번에 가도록 하는 방법
$(window).scrollTop(targetTop);
*/
$('html').stop().animate({scrollTop:targetTop}, 300);
e.preventDefault();
});
function Page__updateIndicatorActive() {
var scrollTop = $('.modal-scroll').scrollTop() + 160;
// 역순으로 검색해야 편하다
$($('.repairPage').get().reverse()).each(function(index, node) {
var $node = $(this);
var offsetTop = parseInt($node.attr('data-offset-top'));
var id = $(this).attr("id");
var href_add = $(this).attr("href");
console.log("scrollTop = "+scrollTop);
console.log("offsetTop = "+offsetTop);
console.log("========================================");
if ( scrollTop >= offsetTop ) {
console.log("id = "+id);
console.log("href_add = "+href_add);
// 기존 녀석에게 활성화 풀고
$('.modal-con.modal-con__view .modal-con__menu li a.active').removeClass('active');
// 해당하는 녀석에게 활성화 넣고
var currentPageIndex = $node.index();
$('.modal-con.modal-con__view .modal-con__menu li a').eq(currentPageIndex).addClass('active');
$('html').attr('data-current-page-index', currentPageIndex);
return false; // 더 이상 다른 페이지를 검사하지 않는다.
}
});
}
// 각 페이지의 offsetTop 속성을 업데이트
function Page__updateOffsetTop() {
$('.repairPage').each(function(index, node) {
var $page = $(node);
var offsetTop = $page.offset().top;
$page.attr('data-offset-top', offsetTop);
});
// 계산이 바뀌었으니까, 다시 상태 업데이트
Page__updateIndicatorActive();
}
function Page__init() {
Page__updateOffsetTop();
}
// 초기화
Page__init();
// 화면이 리사이즈 할 때 마다, offsetTop을 다시계산
$(window).resize(Page__updateOffsetTop);
// 스크롤이 될 때 마다, 인디케이터의 상태를 갱신
/*
$(window).scroll(Page__updateIndicatorActive);
*/
$('.modal-scroll').scroll(function() {
// 스크롤 이동 시 실행되는 코드
Page__updateIndicatorActive();
});
//모달닫기
$(".modal_close").click(function() {
$(".modal").removeClass("is-active");
$("html").css("overflow","auto");
});
</script>
</html>
답변 2
모달창 띄우고나서 Page__updateOffsetTop() 만 실행해주시면 될거 같네요
다음과 같이 해볼 수 있을 것 같습니다.
function Page__updateOffsetTop() {
$('.repairPage').each(function(index, node) {
var $page = $(node);
var offsetTop = $page.offset().top;
// data-offset-top 속성을 세팅할 때, 섹션의 식별자를 함께 저장해주면 좋습니다.
$page.attr('data-offset-top', offsetTop)
.attr('data-section', index);
});
// 계산이 바뀌었으니까, 다시 상태 업데이트
Page__updateIndicatorActive();
}
function Page__updateIndicatorActive() {
var scrollTop = $('.modal-scroll').scrollTop() + 160;
$('.repairPage').each(function(index, node) {
var $node = $(this);
var offsetTop = parseInt($node.attr('data-offset-top'));
if (scrollTop >= offsetTop) {
// 기존 녀석에게 활성화 풀고
$('.modal-con.modal-con__view .modal-con__menu li a.active').removeClass('active');
// 해당하는 녀석에게 활성화 넣고
var sectionIndex = $node.attr('data-section');
$('.modal-con.modal-con__view .modal-con__menu li a').eq(sectionIndex).addClass('active');
$('html').attr('data-current-page-index', sectionIndex);
return false; // 더 이상 다른 섹션을 검사하지 않는다.
}
});
}
// 초기화
Page__init();
// 화면이 리사이즈 할 때 마다, offsetTop을 다시 계산
$(window).resize(Page__updateOffsetTop);
// 스크롤이 될 때 마다, 인디케이터의 상태를 갱신
$('.modal-scroll').scroll(function() {
// 스크롤 이동 시 실행되는 코드
Page__updateIndicatorActive();
});
각 섹션에 대한 data-section 속성을 추가하여 스크롤 시 해당 섹션의 인덱스를 활용하여 메뉴를 활성화하도록 변경하면 될 것 같습니다.
!-->
답변을 작성하시기 전에 로그인 해주세요.