2016-05-31 9 views
0

Ich habe Schwierigkeiten, ein Bildlaufproblem auf einem Plugin zu lösen, das ich versuche zu schreiben. Ich füge einen Screenshot hinzu, von dem ich hoffe, dass er die Benutzeroberfläche leichter beschreibt. UISeitenteil Navigation mit Javascript

Zwei Dinge müssen passieren:

1) Wenn der Benutzer blättert in Sicht, der Abschnitt ‚aktiv‘ und wiederum wird, die ‚aktiv‘ sowie der entsprechende Punkt bekommt. Jeder vorherige Punkt sollte beim Scrollen aktiv bleiben. Wenn der Benutzer nach oben scrollt, sollte die 'aktive' Klasse von den Punkten entfernt werden. Ich bin mir nicht sicher, wie ich das lösen soll? Scrollrichtung erkennen? So sieht der aktuelle Code aus:

var _activeSection = function() { 

    var setActive; 
    setActive = false; 

    for (var i = 0, len = sections.length; i < len; i++) { 
     // Last section, bottom of window 
     if (!setActive && elementInView(sections[i]) && (window.innerHeight + window.scrollY) >= document.body.offsetHeight) { 
      sections[i].classList.add('active'); // Add 'active' class when Section is in view and reaches bottom of the viewport 
     } else if (!setActive && elementInView(sections[i])) { 
      sections[i].classList.add('active'); // Add 'active' class when Section is in view 
      setActive = true; 
     } else { 
      sections[i].classList.remove('active'); 
     } 
    } 

}; 

2) Dies ist der schwierige Teil: Das Scroll-Fortschrittselement (der Think-Vertical-Bar). Im Moment kann ich keinen genauen Weg finden, um jedes Inkrement genau zu berechnen. Aktuelle Funktion:

var _setScrollProgress = function() { 

    // How many sections are there? 
    var sectionCount = (sections.length -1); 

    // Metrics 
    var scrollProgress = (scrollTop/root.innerHeight) * 100/sectionCount + '%';// get amount scrolled (in %) 

    if (settings.position === 'left' || settings.position === 'right') { 
     highlight.style.height = scrollProgress; 
    } 

}; 

Alle Ideen und oder Code-Schnipsel wären großartig. Ich fange an, meine Haare mit diesem Ding auszuziehen.

Hinweis: Pure/Vanilla Javascript-Lösungen nur bitte, keine jQuery.

+0

Sind Sie mit dem Scroll-Ereignis-Listener? https://developer.mozilla.org/en/docs/Web/Events/scroll – Danmoreng

+0

Ja, natürlich. Ich habe nicht den gesamten Code im Plugin enthalten. Aber ja, absolut. Ich benutze auch den Listener und die Drosselung des Scroll-Ereignisses. – nfq

Antwort

1

Als Annäherung versuche ich immer, das Problem auf die reine Geometrie zu reduzieren. Wenn Sie auf Bildlaufereignisse reagieren, können Sie ein aktualisiertes Rechteck beibehalten, das der Position des Ansichtsfensters über Ihrem Dokument entspricht. Sie können eine Liste von Positionsrechtecken für jeden Seitenabschnitt erstellen.

Alles, was Sie tun müssen, ist alle Lichter auszuschalten, und dann leuchten Sie diejenige, deren Mittellinie am nächsten zu Ihrem Viewport Rechteck Mittellinie ist.

Sie können alle Arten von Komplexität durch die Verwendung von Rechteckgeometrie loswerden!

Richtig, hier ist eine Demo - ich beschrieb die Midline-Sache ein bisschen falsch, stellt sich heraus, es ist Abschnitt oben vs. Bildschirm Mittellinie. Machen Sie Mittellinie vs. Mittellinie, und Sie verfolgen nicht gerade.

<!DOCTYPE html> 
 
<html> 
 
    <head> 
 
     <title>Little Demo</title> 
 
     <style type="text/css"> 
 
     body { 
 
      margin: 10px; 
 
     } 
 
      .section { 
 
       position: relative; 
 
       display: block; 
 
       width: 70%; 
 
       margin: 0 0 10px; 
 
       background: red; 
 
      } 
 
      .section:before { 
 
       content: ''; 
 
       display: block; 
 
       padding-top: 60%; 
 
      } 
 
      .guide { 
 
       position: fixed; 
 
       left: 100%; 
 
       top: 50%; 
 
       width: 20%; 
 
       margin-left: -5%; 
 
       list-style: none; 
 
       padding: 0; 
 
      } 
 
      .guide li { 
 
       position: relative; 
 
       margin-bottom: 10px; 
 
      } 
 
      .guide b { 
 
       position: relative; 
 
       display: inline-block; 
 
       width: 20px; 
 
       height: 20px; 
 
       background: black; 
 
       border-radius: 10px; 
 
       vertical-align: middle; 
 
      } 
 
      .guide b:before { 
 
       position: absolute; 
 
       content: ''; 
 
       display: block; 
 
       height: 20px; 
 
       border-left: 2px solid black; 
 
       left: 9px; 
 
       top: -10px; 
 
      } 
 
      .guide li:first-child b:before { 
 
       content: none; 
 
      } 
 
      .guide span { 
 
       position: absolute; 
 
       top: -5px; 
 
       left: -4px; 
 
       margin-left: -120px; 
 
       display: block; 
 
       white-space: nowrap; 
 
       width: 140px; 
 
       text-align: right; 
 
       border: 1px black solid; 
 
       padding: 4px; 
 
       box-shadow: 3px 3px rgba(0,0,0,0.3); 
 
       border-radius: 10px; 
 
       opacity: 0; 
 
      } 
 
      .guide span b { 
 
       width: 16px; 
 
       height: 16px; 
 
       background: red; 
 
       border: 2px solid black; 
 
      } 
 
      .guide span b:before { 
 
       border-color: red; 
 
       left: 6px; 
 
      } 
 
     </style> 
 
    </head> 
 
    <body> 
 
     <div class="section">  </div> 
 
     <div class="section">  </div> 
 
     <div class="section">  </div> 
 
     <div class="section">  </div> 
 
     <div class="section">  </div> 
 
     <div class="section">  </div> 
 

 
     <ul class="guide"> 
 
      <li><b></b><span class="indicator">Section 1 <b></b></span></li> 
 
      <li><b></b><span class="indicator">Section 2 <b></b></span></li> 
 
      <li><b></b><span class="indicator">Section 3 <b></b></span></li> 
 
      <li><b></b><span class="indicator">Section 4 <b></b></span></li> 
 
      <li><b></b><span class="indicator">Section 5 <b></b></span></li> 
 
      <li><b></b><span class="indicator">Section 6 <b></b></span></li> 
 
     </ul> 
 
     <script type="text/javascript"> 
 
      //I'd measure this in JQuery, but do it mathematically here: 
 
      //Calculate the midpoints of all of the sections. 
 
      var sections = document.getElementsByClassName('section'); 
 
      var sectiontops = []; 
 
      
 
      function updateSectionTops() { 
 
       sectiontops = []; 
 
       var y = 10; //top body margin is 10 
 
       for (var s=0; s<sections.length; s++) { 
 
        var h = sections[s].offsetHeight; 
 
        sectiontops.push(y); 
 
        y+=h; 
 
       } 
 
      } 
 

 
      var indicators = document.getElementsByClassName('indicator'); 
 

 
      function updateIndicators() { 
 
       for (var i = 0; i < indicators.length; i++) { 
 
        indicators[i].style.opacity = 0; 
 
       } 
 
       var ls = 0; 
 
       for (var s = 0; s < sections.length; s++) { 
 
        if (sectiontops[s] > clientmid) break; 
 
        ls = s; 
 
       } 
 
       for (var i = 0; i <= ls; i++) { 
 
        indicators[i].style.opacity = 1; 
 
       } 
 
       
 
      } 
 

 
      var clientmid = 0; 
 
      function updateClientMid() { 
 
       var height = window.innerHeight 
 
        || document.documentElement.clientHeight 
 
        || document.body.clientHeight; 
 
       clientmid = window.scrollY + (height/2); 
 
       updateSectionTops(); 
 
       updateIndicators(); 
 
      } 
 
      updateClientMid(); 
 

 
      window.onscroll = updateClientMid; 
 
      window.onresize = updateClientMid; 
 
     </script> 
 
    </body> 
 
</html>

+0

Danke für den Tipp Mark. Mit Mittellinie, schlägst du vor, ich stelle mir vertikale Mitte des Ansichtsfensters und Arbeit davon vor? Ich habe verschiedene Dinge ausprobiert, sogar skizziert, was die Funktionalität auf einem Blatt Papier sein soll und ich konnte die Probleme noch nicht vollständig lösen. – nfq

+0

Wenn Sie davon ausgehen, dass Ihre Hauptscrollrichtung vertikal ist, dann ist der Abstand zwischen dem Mittelpunkt Ihrer Idee des Ansichtsfensters (eine horizontale Linie Y-Wert usw.) und der Mittellinie Ihres Abschnittsrechtecks ​​der nächstgelegene Abschnitt. Wenn Ihre Bildlaufleiste horizontal ist, dann sehen Sie vertikale Mittellinien. Wenn beide, dann können Sie dx * dx + dy * dy, dx und dy als die Unterschiede zwischen vertikalen und horizontalen Mittellinien verwenden. –

+0

Entschuldigung. Ja, ich meinte horizontal (Mittellinie) mit einer vertikalen Schriftrolle. Horizontales Scrollen ist mit diesem Plugin nicht wirklich notwendig. Danke für Ihre Vorschläge. Aber sie helfen mir nicht wirklich, denn was Sie vorschlagen, habe ich bereits umgesetzt. Wenn der Abschnitt in die Ansicht scrollt, erhält er im Grunde eine Klasse "aktiv", die wiederum dynamisch die Klasse "aktiv" zum Punkt hinzufügt. Ich kämpfe mit dem Rest, was ich im Wesentlichen in der ursprünglichen Frage beschrieben habe. – nfq