2016-11-01 8 views
0

Ich versuche, eine Navigationsleiste, die ähnliche Funktionen wie folgt zu machen: https://jsfiddle.net/05jpxf45/ aber Knockout verwenden.Ändern Sie die Navigation aktive Klasse auf Bildlauf

Dies ist der entsprechende Code von meiner Ansicht Modell:

self.selectedTopicName = ko.observable(""); 

    self.selectedTopicName.subscribe(function() { 
     self.updateHighlight(); 
    }); 

    self.updateHighlight = function() { 
     $('.navigation-list li').each(function (index) { 
      var navTopic = $(this).attr('class').split(/\s+/)[0]; 
      $(this).removeClass('highlight'); 

      if (self.selectedTopicName().indexOf(navTopic) >= 0) { 
       $(this).addClass('highlight'); 
      } 
     }); 
    }; 

    self.scrollToPage = function (sectionRef) { 
     var target = $(sectionRef); 
     if (target.length) { 
      console.log(target.position().top); 
      $('html, body').stop().animate({ 
       scrollTop: target.position().top 
      }, 1000); 
     } 

(self.selectedTopicName wird in meiner Ansicht, wenn der Benutzer scrollt, so dass Bit sortiert ist).

<nav class="floating-nav-container"> 
<ul data-bind="foreach: sideMenuPageUnitData, attr: { class: 'navigation-list' }"> 
    <li data-bind="attr: { class: pageRef }"> 
     <a data-bind="attr: { href: pageData[0].name }, text: name, click: function (data, event) { $parent.scrollToPage('#section_' + pageData[0].name) }"></a> 
    </li> 
</ul> 
<span data-bind="text: selectedTopicName()"></span> 
</nav> 

(Dies funktioniert, wie ich es will, ich bin es gerade hier setzt meine Umrisse zu zeigen.)

Während diese Art und Weise funktioniert, es scheint nicht, wie es die „beste“ Weg, um es in Knockout zu tun und ich fragte mich, ob irgendjemand etwas dagegen hätte, mir einen Ratschlag zu geben, wie sie es machen würden.

Grundsätzlich jedes Mal, wenn selectedTopicName aktualisiert wird, bedeutet das, dass der Benutzer die Seite nach oben oder unten gescrollt hat, also benutze ich im Moment einen subscribe und dann die Elemente durch, aber es scheint nicht sehr elegant zu sein.

Danke!

Antwort

1

Wenn Sie Knockout verwenden, um ein benutzerdefiniertes Verhalten mit dem DOM zu erzielen, das mit den integrierten Bindungen nicht einfach durchgeführt werden kann, sollten Sie benutzerdefinierte Bindungen erstellen. Ich habe den Code genommen und verwandelte sie in eine benutzerdefinierte Bindung (für den Scroll-Teil jedenfalls):

ko.bindingHandlers.onScroll = { 
    init: function(element) { 
    $(document).on("scroll", function() { 
     var scrollPos = $(document).scrollTop(); 
     $(element).find('a').each(function() { 
     var currLink = $(this); 
     var refElement = $(currLink.attr("href")); 
     if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) { 
      $(element).find('a').removeClass("active"); 
      currLink.addClass("active"); 
     } else { 
      currLink.removeClass("active"); 
     } 
     }); 
    }); 
    } 
}; 

https://jsfiddle.net/05jpxf45/1/

Verwandte Themen