【问题标题】:click button scroll to specific div单击按钮滚动到特定的 div
【发布时间】:2019-03-14 15:49:11
【问题描述】:

我有一个具有固定菜单和内容框(div)的页面。 单击菜单时,内容框会滚动到特定的 div。

到目前为止一切顺利。

这是这里的示例。 https://jsfiddle.net/ezrinn/8cdjsmb9/11/

问题是当我包装整个 div 并将它们设置为显示/隐藏切换按钮时,滚动不起作用。

这是不工作的示例。 https://jsfiddle.net/ezrinn/8cdjsmb9/10/

这里还有sn-p

$('.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 jquery html css


    【解决方案1】:

    当您计算 offset 时,divhiddendisplay: 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;
    }
    

    【讨论】:

      【解决方案2】:

      在您的 CSS 中,不要使用 display: nonedisplay: block,而是尝试使用 visible

      .wrap { visibility:hidden;}
      .wrap.on { visibility:visible;}
      

      这将隐藏元素而不影响布局。

      更新小提琴:https://jsfiddle.net/a5u683es/

      【讨论】:

      • 谢谢。用css解决这个问题很简单:)
      【解决方案3】:

      问题是您在隐藏内容时尝试更新 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>

      【讨论】:

        【解决方案4】:

        完美运行,只是当你使用 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/

        不是最佳方式,但它是给你一个想法。对不起我的英语。

        【讨论】:

          【解决方案5】:

          只需签出我设计的这个工作页面

          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>

          【讨论】:

            猜你喜欢
            • 2022-07-29
            • 2019-09-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多