У меня есть страница с фиксированным меню и полем содержимого (div). При нажатии на меню окно содержимого прокручивается до определенного div.
Все идет нормально.
Это образец здесь. https://jsfiddle.net/ezrinn/8cdjsmb9/11/
Проблема в том, что когда я оборачиваю весь этот div и делаю их кнопкой переключения «показать/скрыть», прокрутка не работает.
Это образец, который не работает. https://jsfiddle.net/ezrinn/8cdjsmb9/10/
Также вот фрагмент
$('.btn').click(function() {
$(".wrap").toggleClass('on');
});
var div_parent_class_name;
var divs_class;
var id_offset_map = {};
$(document).ready(function() {
div_parent_class_name = "wrap_scroll";
divs_class = "page-section";
var scroll_divs = $("." + div_parent_class_name).children();
id_offset_map.first = 0;
scroll_divs.each(function(index) {
id_offset_map["#" + scroll_divs[index].id] = scroll_divs[index].offsetTop
});
$('a').bind('click', function(e) {
e.preventDefault();
var target = $(this).attr("href")
$('.wrap_scroll').stop().animate({
scrollTop: id_offset_map[target]
}, 600, function() {
/* location.hash = target-20; */ //attach the hash (#jumptarget) to the pageurl
});
return false;
});
});
$(".wrap_scroll").scroll(function() {
var scrollPos = $(".wrap_scroll").scrollTop();
$("." + divs_class).each(function(i) {
var divs = $("." + divs_class);
divs.each(function(idx) {
if (scrollPos >= id_offset_map["#" + this.id]) {
$('.menu>ul>li a.active').removeClass('active');
$('.menu>ul>li a').eq(idx).addClass('active');
}
});
});
}).scroll();body,
html {
margin: 0;
padding: 0;
height: 3000px;
}
.wrap { display:none;}
.wrap.on { display:block;}
.menu {
width: 100px;
position: fixed;
top: 40px;
left: 10px;
}
.menu a.active {
background: red
}
.wrap_scroll {
position: absolute;
top: 20px;
left: 150px;
width: 500px;
height: 500px;
overflow-y: scroll
}
#home {
background-color: #286090;
height: 200px;
}
#portfolio {
background: gray;
height: 600px;
}
#about {
background-color: blue;
height: 800px;
}
#contact {
background: yellow;
height: 1000px;
}<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class = "btn">show/hide</button>
<div class = "wrap">
<div class = "menu">
<ul>
<li><a class = "active" href = "#home">Home</a> </li>
<li><a href = "#portfolio">Portfolio</a> </li>
<li><a href = "#about">About</a> </li>
<li><a href = "#contact">Contact</a> </li>
</ul>a
</div>
<div class = "wrap_scroll">
<div class = "page-section" id = "home">hh</div>
<div class = "page-section" id = "portfolio">pp</div>
<div class = "page-section" id = "about">aa</div>
<div class = "page-section" id = "contact">cc</div>
</div>
</div>Что мне нужно, чтобы исправить код? пожалуйста помоги.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В вашем CSS вместо использования display: none и display: block попробуйте вместо этого использовать visible:
.wrap { visibility:hidden;}
.wrap.on { visibility:visible;}
Это скроет элемент, не влияя на макет.
Обновленная скрипта: https://jsfiddle.net/a5u683es/
Когда вы вычисляете свой offset, div это hidden с display: none. Это приводит к тому, что смещения устанавливаются/вычисляются равными нулю.
Вот быстрое исправление, которое я собрал вместе: https://jsfiddle.net/hrb58zae/
По сути, переместили логику для определения смещения после нажатия показать/скрыть.
var setOffset = null;
...
if (!setOffset) {
var scroll_divs = $("." + div_parent_class_name).children();
id_offset_map.first = 0;
scroll_divs.each(function(index) {
id_offset_map["#" + scroll_divs[index].id] = scroll_divs[index].offsetTop
});
setOffset = true;
}
Проблема заключалась в том, что вы пытаетесь обновить id_offset_map, когда содержимое скрыто. Когда вы используете опору display:none, вы не получите размеры для этого элемента, поэтому он не работает.
Я обновил логику, пожалуйста, проверьте скрипку https://jsfiddle.net/qfrsmnh5/
var id_offset_map = {};
var div_parent_class_name = "wrap_scroll";
var divs_class = "page-section";
var scroll_divs = $("." + div_parent_class_name).children();
function updateOffsets(){
id_offset_map.first = 0;
scroll_divs.each(function(index) {
id_offset_map["#" + scroll_divs[index].id] = scroll_divs[index].offsetTop
});
}
$(document).ready(function() {
$('.btn').click(function() {
$(".wrap").toggleClass('on');
if ($(".wrap").hasClass("on")){
updateOffsets();
}
});
$('a').on('click', function(e) {
e.preventDefault();
var target = $(this).attr("href")
$('.wrap_scroll').stop().animate({
scrollTop: id_offset_map[target]
}, 600, function() {
/* location.hash = target-20; */ //attach the hash (#jumptarget) to the pageurl
});
return false;
});
});
$(".wrap_scroll").on('scroll',function() {
var scrollPos = $(".wrap_scroll").scrollTop();
$("." + divs_class).each(function(i) {
var divs = $("." + divs_class);
divs.each(function(idx) {
if (scrollPos >= id_offset_map["#" + this.id]) {
$('.menu>ul>li a.active').removeClass('active');
$('.menu>ul>li a').eq(idx).addClass('active');
}
});
});
}).scroll();body,
html {
margin: 0;
padding: 0;
height: 3000px;
}
.wrap { display:none;}
.wrap.on { display:block;}
.menu {
width: 100px;
position: fixed;
top: 40px;
left: 10px;
}
.menu a.active {
background: red;
}
.wrap_scroll {
position: absolute;
top: 20px;
left: 150px;
width: 500px;
height: 500px;
overflow-y: scroll;
}
#home {
background-color: #286090;
height: 200px;
}
#portfolio {
background: gray;
height: 600px;
}
#about {
background-color: blue;
height: 800px;
}
#contact {
background: yellow;
height: 1000px;
}<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class = "btn">show/hide</button>
<div class = "wrap">
<div class = "menu">
<ul>
<li><a class = "active" href = "#home">Home</a></li>
<li><a href = "#portfolio">Portfolio</a> </li>
<li><a href = "#about">About</a> </li>
<li><a href = "#contact">Contact</a> </li>
</ul>
</div>
<div class = "wrap_scroll">
<div class = "page-section" id = "home">hh</div>
<div class = "page-section" id = "portfolio">pp</div>
<div class = "page-section" id = "about">aa</div>
<div class = "page-section" id = "contact">cc</div>
</div>
</div>работает отлично, просто когда вы используете display: none, вы не можете выполнять вычисления offsetTop, потому что на самом деле элемент не отображается, я не уверен, все ли значения дают 0 или undefined, я думаю, undefined, решение всегда вычисляет позиции с помощью функции:
var div_parent_class_name;
var divs_class;
var id_offset_map = {};
function calcTops(){
div_parent_class_name = "wrap_scroll";
divs_class = "page-section";
var scroll_divs = $("." + div_parent_class_name).children();
id_offset_map.first = 0;
scroll_divs.each(function(index) {
id_offset_map["#" + scroll_divs[index].id] = scroll_divs[index].offsetTop
});
}
https://jsfiddle.net/561oe7rb/1/
это не оптимальный способ, но он должен дать вам представление. Извините за мой английский.
Просто оформите заказ на этой рабочей странице, которую я разработал
jQuery(document).on('scroll', function(){
onScroll();
});
jQuery(document).ready(function($) {
div_slider();
showhide();
});
/*show hide content*/
function showhide(){
$('.toggle-wrapper button').on('click', function(){
$('.wrapper').toggle();
// div_slider();
})
}
/*scrolling page on header elements click*/
function div_slider(){
$('ul li a').on('click', function(e){
e.preventDefault();
$('ul li a').removeClass('active');
$(this).addClass('active');
var attrval = $(this.getAttribute('href'));
$('html,body').stop().animate({
scrollTop: attrval.offset().top
}, 1000)
});
}
/*adding active class on header elements on page scroll*/
function onScroll(event){
var scrollPosition = $(document).scrollTop();
$('ul li a').each(function () {
var scroll_link = $(this);
var ref_scroll_Link = $(scroll_link.attr("href"));
if (ref_scroll_Link.position().top <= scrollPosition && ref_scroll_Link.position().top + ref_scroll_Link.height() > scrollPosition) {
$('ul li a').removeClass("active");
scroll_link.addClass("active");
}
else{
scroll_link.removeClass("active");
}
});
}body {
margin: 0;
}
.toggle-wrapper {
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: #ccd2cc;
text-align: center;
}
.toggle-wrapper button {
background-color: #ED4C67;
color: #ffffff;
padding: 10px 20px;
border: 0;
cursor: pointer;
border-radius: 5px;
}
.toggle-wrapper button:active{
background-color: #B53471;
}
header {
background-color: #6C5CE7;
position: fixed;
top: 36px;
z-index: 99;
left: 0;
right: 0;
}
header ul {
list-style: none;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0;
margin: 0;
}
ul li {
flex: 1 100%;
display: flex;
justify-content: center;
}
.wrapper {
margin-top: 36px;
}
header a {
color: #ffffff;
padding: 15px;
display: block;
text-decoration: navajowhite;
text-transform: uppercase;
width: 100%;
text-align: center;
}
header a.active {
color: #000000;
background-color: #ffffff;
}
section {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
section.section1 {
background-color: #FFEAA7;
}
section.section2{
background-color:#FAB1A0;
}
section.section3{
background-color:#7F8C8D;
}
section.section4{
background-color:#4CD137;
}
section.section5{
background-color:#A3CB38;
}
section.section6{
background-color:#70A1FF;
}
section.section7{
background-color:#079992;
}<div class = "toggle-wrapper">
<button>Toggle</button>
</div>
<div class = "wrapper" style = "display: none;">
<header>
<ul>
<li><a class = "active" href = "#one">one</a></li>
<li><a href = "#two">two</a></li>
<li><a href = "#three">three</a></li>
<li><a href = "#four">four</a></li>
<li><a href = "#five">five</a></li>
<li><a href = "#six">six</a></li>
<li><a href = "#seven">seven</a></li>
</ul>
</header>
<section class = "section1" id = "one">SECTION ONE</section>
<section class = "section2" id = "two">SECTION TWO</section>
<section class = "section3" id = "three">SECTION THREE</section>
<section class = "section4" id = "four">SECTION FOUR</section>
<section class = "section5" id = "five">SECTION FIVE</section>
<section class = "section6" id = "six">SECTION SIX</section>
<section class = "section7" id = "seven">SECTION SEVEN</section>
</div>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Спасибо. просто решить эту проблему с помощью css :)