إضافة وإزالة الصف ، تطبيق الأنماط على التمرير

10

مشكلة

أواجه مشكلة في إضافة الفصول وإزالتها ، وتطبيق الأنماط على التمرير.

على وجه التحديد ، عندما أقوم بالتمرير لأسفل الصفحة:

  • فئة is-red لا يزال في الأول .dot__outer مجموعة عند التمرير لأسفل الصفحة عندما يجب إزالتها ، يجب أن تكون هناك مجموعة واحدة مميزة مع is-red صف دراسي
  • يبدو أن هناك مشكلة في عبارة if-statement ، حيث تظل الألوان ألوانها الافتراضية ولا تتغير عند التمرير

سلوك متوقع

التمرير:

  • عند التمرير ، قم بإزالة الفصل is-red على جميع divs مع فئة dot__outer
  • أضف فئة is-red إلى التالي dot__outer في السلسلة بعد قيام المستخدم بتمرير لوحة معينة. أي إذا كان المستخدم في اللوحة الثانية ، فيجب تمييز المجموعة الثانية باللون الأحمر

ألوان النقاط:

  • على الخلفيات السوداء ، يجب أن تكون النقاط وحدودها بيضاء
  • على الخلفيات البيضاء ، يجب أن تكون النقاط وحدودها سوداء
  • في كلتا الحالتين ، أي dot__outer مع فئة is-red يجب أن يكون أحمر

scripts.js

$(function() {

  function updateProgress() {
    let dot = $(".dot");

    let dotsBottom = $(".dots").offset().top + $(".dots").outerHeight();
    let panelHeaderBottom =$(".panel-1").offset().top + $(".panel-1").outerHeight();
    let panelRelatedTop = $(".panel-8").offset().top;

    // If the `dot__outer` has a class of `is-active` the dot should also be red. By default, the dot and border should be white.
    if (dot.parent().hasClass("is-red")) {
      $(this).css("background", "red");
    } else {

      // If the position of the dots is less than the bottom of the header or greater than the top of the related section, the dots are white. Otherwise, the dots are black
      if (dotsBottom < panelHeaderBottom || dotsBottom > panelRelatedTop) {
        $(this).css("background", "#000");

      } else {
        $(this).css("background", "#fff");
      }
    }

    $(".panel").each(function(index) {
      let currentPosition = $(window).scrollTop();
      let panelTop = $(this).offset().top;
      let panelBottom = $(this).offset().top + $(this).outerHeight();

      if ((currentPosition > panelTop) && (currentPosition < panelBottom)) {        
        $(".dot__outer").removeClass("is-red");
        $(".dot__outer").eq(index).addClass("is-red");
      } else {
        $(".dot__outer").eq(0).addClass("is-red");
      }
    });
  }

  $(window).scroll(function() {
    updateProgress();
  });
});

index.html

<div class="panels">
  <div class="panel panel-1">Panel #1</div>
  <div class="panel panel-2">Panel #2</div>
  <div class="panel panel-3">Panel #3</div>
  <div class="panel panel-4">Panel #4</div>
  <div class="panel panel-5">Panel #5</div>
  <div class="panel panel-6">Panel #6</div>
  <div class="panel panel-7">Panel #7</div>
  <div class="panel panel-8">Panel #8</div>
</div>

<div class="dots">

  <div class="dot__outer is-red">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>
</div>

Codepen

https://codepen.io/yacoubian/pen/PBOVKw؟editors=1010

تحديث

تم إصلاح مشكلة التمرير ، وتم تحديث الشفرة.

4 الاجابة

1
افضل جواب

هذا نهج آخر يمكنك اتباعه:

function updateProgress() {
    let dotsBottom = $(".dots").offset().top + $(".dots").outerHeight();
    let dotBorder = $(".dot__outer");

    let headerBottom = $(".panel-1").offset().top + $(".panel-1").outerHeight();
    let relatedTop = $(".panel-8").offset().top;

    $(".panel").each(function(index) {
        let currentPosition = $(window).scrollTop();
        let panelTop = $(this).offset().top;
        let panelBottom = $(this).offset().top + $(this).outerHeight();

        if (currentPosition > panelTop && currentPosition < panelBottom) {
            dotBorder.removeClass("is-red");
            dotBorder.eq(index).addClass("is-red").children().css("background", "red");

            if (dotsBottom < headerBottom || dotsBottom > relatedTop) {
                dotBorder.not(".is-red").children().css("background", "#fff");
            } else {
                dotBorder.not(".is-active").children().css("background", "#000");
            }
        }
    });
}
:مؤلف
0

هنا هو الحل. هذا يتحقق ديناميكيًا من موضع اللوحة ويقارنها بكل موضع نقطة ثم يطبق فئة على نمط css.

الكودبين : https://codepen.io/tylerfowle/pen/QBaBgO

  1. لقد أضفت light و dark الطبقة على لوحات html.
  2. في JS نكتشف ما إذا كانت اللوحة في إطار العرض ، وإذا كانت هي الفئة التي تحتوي عليها (فاتحة أو داكنة).
  3. ثم ندور خلال كل من .dot__outer العناصر ومعرفة اللوحة الموجودة فيها وتطبيق الفئة الصحيحة. نستخدم نقطة المنتصف لتحديد اللوحة التي توجد بها غالبية النقطة.

$(function() {
  let dotClass = "dark";

  function updateProgress() {
    let viewportTop = $(window).scrollTop();
    let viewportBot = viewportTop + $(window).height();

    $(".panel").each(function(index) {
      // save the ref to the current panel for use in the dot loop
      let $this = $(this);
      let panelTop = $(this).offset().top;
      let panelBot = panelTop + $(this).outerHeight();

      // add class based on panel that is within viewport, remove from siblings
      if ((viewportTop > panelTop) && (viewportTop < panelBot)) {
        $(".dot__outer").eq(index).addClass("is-red").siblings().removeClass("is-red");
      }

      $(".dot__outer").each(function(){
        let dotTop = $(this).offset().top;
        let dotMid = dotTop + $(this).outerHeight()/2;
        let dotBot = dotTop + $(this).outerHeight();

        if ($this.hasClass("light")) {
          dotClass = "light";
        } else {
          dotClass = "dark";
        }

        if (panelTop < dotMid && panelBot > dotMid) {
          $(this).removeClass("dark light").addClass(dotClass);
        }

      });

    });
  }

  $(window).scroll(function() {
    updateProgress();
  });

});
body {
  margin: 0;
}

.panel {
  width: 100vw;
  height: 100vh;
  border-bottom: 1px solid red;
  font-size: 24px;
  font-weight: 700;
  color: #000;
}
.panel.panel-1, .panel.panel-8 {
  background: #000;
  color: #fff;
}

.dots {
  position: fixed;
  bottom: 48px;
  right: 48px;
}

.dot {
  width: 5px;
  height: 5px;
  background: white;
  border-radius: 50%;
}

.dot__outer {
  margin-bottom: 16px;
  padding: 8px;
  border: 1px solid white;
}
.dot__outer.light {
  border-color: black;
}
.dot__outer.light .dot {
  background: black;
}
.dot__outer.dark {
  border-color: white;
}
.dot__outer.dark .dot {
  background: white;
}
.dot__outer.is-red {
  border: 1px solid red !important;
}
.dot__outer.is-red .dot {
  background: red !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panels">
  <div class="panel panel-1 dark">Panel #1</div>
  <div class="panel panel-2 light">Panel #2</div>
  <div class="panel panel-3 light">Panel #3</div>
  <div class="panel panel-4 light">Panel #4</div>
  <div class="panel panel-5 light">Panel #5</div>
  <div class="panel panel-6 light">Panel #6</div>
  <div class="panel panel-7 light">Panel #7</div>
  <div class="panel panel-8 dark">Panel #8</div>
</div>

<div class="dots">

  <div class="dot__outer is-red">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>
</div>

:مؤلف
0

ربما سأقوم بحل بعض المشكلات باستخدام CSS ، وخاصة جزء التلوين.

إليك فكرة حيث قمت بتقليص كود JS لإضافة / إزالة الصف فقط بناءً على قسم بسيط للعثور على الفهرس.

بعد ذلك ، استخدمت بعض خدعة CSS للحصول على تلوين المربعات:

  • بالنسبة للحدود ، استخدمت box-shadow لإنشاء حد ثانٍ بلون مختلف بحيث يكون واحد فقط مرئيًا اعتمادًا على الخلفية.
  • بالنسبة للخلفية ، حددت تلوينًا باستخدام التدرج اللوني وهو عكس اللون للموقع. لقد قمت بإصلاحه وقمت بتعديل الموضع على التمرير باستخدام متغير CSS.

قم بتشغيل المقتطف على الصفحة الكاملة للحصول على تجربة أفضل

$(function() {

  function updateProgress() {
        let currentPosition = $(window).scrollTop();
        let index = Math.floor(currentPosition/$(window).height());
        
        $(".is-red").removeClass("is-red");
        $(".dot__outer").eq(index).addClass("is-red");
        $('.dot').css('--p',(-currentPosition)+'px');
  }

  $(window).scroll(function() {
    updateProgress();
  });
});
body {
  margin: 0;
}

.panel {
  height: 100vh;
  border-bottom: 1px solid red;
  font-size: 24px;
  font-weight: 700;
  color: #000;
}

.panel.panel-1,
.panel.panel-8 {
  background: #000;
  color: #fff;
}

.dots {
  position: fixed;
  top: 48px;
  right: 48px;
}

.dot {
  width: 5px;
  height: 5px;
  background: 
    linear-gradient(to bottom,
      #fff 0%,#fff 12.5%,
      #000 12.5%,#000 87.5%,
      #fff 87.5%,#fff 100%) no-repeat;
  background-size:200vw 800vh;
  background-attachment:fixed;
  background-position:0 calc(var(--p,48px) + 48px);
  border-radius: 50%;
}

.dot__outer {
  border: 1px solid #fff;
  margin-bottom: 16px;
  padding: 8px;
  box-shadow:1px 1px 0px #000,
             -1px 1px 0px #000,
             1px -1px 0px #000,
             -1px -1px 0px #000;
}

.dot__outer.is-red {
  border: 1px solid red;
  box-shadow:1px 1px 0px red,
             -1px 1px 0px red,
             1px -1px 0px red,
             -1px -1px 0px red;
}

.dot__outer.is-red .dot {
  background: red;
}
<script
  src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div class="panels">
  <div class="panel panel-1">Panel #1</div>
  <div class="panel panel-2">Panel #2</div>
  <div class="panel panel-3">Panel #3</div>
  <div class="panel panel-4">Panel #4</div>
  <div class="panel panel-5">Panel #5</div>
  <div class="panel panel-6">Panel #6</div>
  <div class="panel panel-7">Panel #7</div>
  <div class="panel panel-8">Panel #8</div>
</div>

<div class="dots">

  <div class="dot__outer is-red">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>
</div>

:مؤلف
-1
افضل جواب

ما زلت أتعلم جافا سكريبت ولكني أعرف أن Bootstrap يحتوي على ScrollSpy والذي سيفعل ذلك لك باستخدام ما هو موجود بالفعل في bootstrap.js. قد تساعدك هذه البرامج التعليمية أيضًا إذا كنت لا تريد تبديل السمة إلى Bootstrap.

  • انتقل الصفحة إلى معرف

  • انظر "رمز موضع التمرير" من قبل قلم القلم زكاري أولسون. هذا هو الجزء الأخير من عنوان URL codepen.io/zacharyolson/pen/uaEzD

  • تغيير لون الصفحة عند التمرير في JS Fiddle - jsfiddle.net/ncuydr9y/1

:مؤلف
فوق
قائمة طعام