Sayfa Kaydırma'daki Etkin Menü Öğesi Değiştirilsin mi?


95

Sayfayı aşağı kaydırdıkça, aktif menü öğesi değişir. Bu nasıl yapılır?

Yanıtlar:


207

Kabın (genellikle pencere) kaydırma olayına bağlanarak yapılır .

Hızlı örnek:

// Cache selectors
var topMenu = $("#top-menu"),
    topMenuHeight = topMenu.outerHeight()+15,
    // All list items
    menuItems = topMenu.find("a"),
    // Anchors corresponding to menu items
    scrollItems = menuItems.map(function(){
      var item = $($(this).attr("href"));
      if (item.length) { return item; }
    });

// Bind to scroll
$(window).scroll(function(){
   // Get container scroll position
   var fromTop = $(this).scrollTop()+topMenuHeight;

   // Get id of current scroll item
   var cur = scrollItems.map(function(){
     if ($(this).offset().top < fromTop)
       return this;
   });
   // Get the id of the current element
   cur = cur[cur.length-1];
   var id = cur && cur.length ? cur[0].id : "";
   // Set/remove active class
   menuItems
     .parent().removeClass("active")
     .end().filter("[href='#"+id+"']").parent().addClass("active");
});​

Kaydırma animasyonu dahil jsFiddle'da yukarıdakileri iş başında görün .


2
Menü Sayfada kimlikleri ve düzenli sayfaların bir karışımı bulunuyorsa, sayfa üzerinde kimliği bağlantıları, sonra değiştirmek yerleştirmek menuItems = topMenu.find("a"),için menuItems = topMenu.find("a").slice(0,4),yerine 4[- 1 senin Sayfada bağlantıları] ile.
Stephen Saucier

6
Aslında menuItems = topMenu.find ('a [href ^ = "#"]') kullandım, böylece yalnızca bağlantı bağlantılarını döndürdüm. Tıkır tıkır çalışıyor.
Julian K

1
Keman kırıldı. Düzeltebilir misin? Thx
m1crdy

1
@ m1crdy Uyarılar için teşekkürler. Düzeltildi. Görünüşe göre jQuery Edge'de bir şey onu kırdı. 2.1.0 ile iyi çalışıyor :)
mekwall

1
@JoelAzevedo Görünüyor Sizzle değişti. JQuery 2.2 ile çalışacak şekilde yanıt ve test durumu güncellendi.
mekwall

16

Kodumu ve Keskin Nişancı ve demo bağlantımı kontrol edin:

    // Basice Code keep it 
    $(document).ready(function () {
        $(document).on("scroll", onScroll);

        //smoothscroll
        $('a[href^="#"]').on('click', function (e) {
            e.preventDefault();
            $(document).off("scroll");

            $('a').each(function () {
                $(this).removeClass('active');
            })
            $(this).addClass('active');

            var target = this.hash,
                menu = target;
            $target = $(target);
            $('html, body').stop().animate({
                'scrollTop': $target.offset().top+2
            }, 500, 'swing', function () {
                window.location.hash = target;
                $(document).on("scroll", onScroll);
            });
        });
    });

// Use Your Class or ID For Selection 

    function onScroll(event){
        var scrollPos = $(document).scrollTop();
        $('#menu-center a').each(function () {
            var currLink = $(this);
            var refElement = $(currLink.attr("href"));
            if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
                $('#menu-center ul li a').removeClass("active");
                currLink.addClass("active");
            }
            else{
                currLink.removeClass("active");
            }
        });
    }

canlı demo


3

@Marcus Ekwall'un cevabını tamamlamak için. Böyle yapmak yalnızca bağlantı bağlantılarını alacaktır. Ayrıca, sabit bağlantılarla normal bağlantıların bir karışımına sahipseniz sorun yaşamazsınız.

jQuery(document).ready(function(jQuery) {            
            var topMenu = jQuery("#top-menu"),
                offset = 40,
                topMenuHeight = topMenu.outerHeight()+offset,
                // All list items
                menuItems =  topMenu.find('a[href*="#"]'),
                // Anchors corresponding to menu items
                scrollItems = menuItems.map(function(){
                  var href = jQuery(this).attr("href"),
                  id = href.substring(href.indexOf('#')),
                  item = jQuery(id);
                  //console.log(item)
                  if (item.length) { return item; }
                });

            // so we can get a fancy scroll animation
            menuItems.click(function(e){
              var href = jQuery(this).attr("href"),
                id = href.substring(href.indexOf('#'));
                  offsetTop = href === "#" ? 0 : jQuery(id).offset().top-topMenuHeight+1;
              jQuery('html, body').stop().animate({ 
                  scrollTop: offsetTop
              }, 300);
              e.preventDefault();
            });

            // Bind to scroll
            jQuery(window).scroll(function(){
               // Get container scroll position
               var fromTop = jQuery(this).scrollTop()+topMenuHeight;

               // Get id of current scroll item
               var cur = scrollItems.map(function(){
                 if (jQuery(this).offset().top < fromTop)
                   return this;
               });

               // Get the id of the current element
               cur = cur[cur.length-1];
               var id = cur && cur.length ? cur[0].id : "";               

               menuItems.parent().removeClass("active");
               if(id){
                    menuItems.parent().end().filter("[href*='#"+id+"']").parent().addClass("active");
               }

            })
        })

Temelde değiştirdim

menuItems = topMenu.find("a"),

tarafından

menuItems =  topMenu.find('a[href*="#"]'),

Tüm bağlantıları bir yerde çapa ile eşleştirmek ve bununla çalışması için gerekli olan her şeyi değiştirmek

Eylem Çalışırken görün jsfiddle


Menü sayfadan daha büyük olduğunda, bunu dikey bir menü için özellikle nasıl genişletebilirim? pyze.com/product/docs/index.html Bir kullanıcı sağdaki içeriği kaydırdığında, soldaki uygun menüyü etkinleştirmek ve gerekirse aktif menüyü göstermek için menüyü kaydırmak istiyorum. Herhangi bir işaretçi takdir edilmektedir.
Dickey Singh

1
Bu çok tanrı, teşekkürler. Ancak, öznitelik seçiciyi * = 'den ^ =' ye değiştirirdim. * = Kullanırsanız , bu harici bir bağlantı olsa bile google.com/#something gibi şeyleri de yakalarsınız . Öznitelik seçici burada iyi açıklanmıştır: w3schools.com/css/css_attribute_selectors.asp
Jacques

0

Kabul edilen cevabın JQuery 3'te çalışmasını istiyorsanız, kodu şu şekilde değiştirin:

var scrollItems = menuItems.map(function () {
    var id = $(this).attr("href");
    try {
        var item = $(id);
      if (item.length) {
        return item;
      }
    } catch {}
  });

Ayrıca, bu kimliğe göre herhangi bir öğe yoksa javascript'in çökmesini önlemek için bir dene-yakala ekledim. Daha da geliştirmekten çekinmeyin;)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.