اذهب إلى المحتوى
  • 0

استفسار بخصوص API Intersection Observer

Ahmed Ebrahim11

السؤال

السلام عليكم 

اذا كان لدي صفحه تحتوي علي عدد من ال sections اريد استخدام intersection observer قمت بقراءه مقالتين وجربت ولم تجدي معي حيث اريد عند الوصول ل section منهم ياتي من اسفل ببط او slow animation  ولكن عند التقاطع 

هل يمكن الحصول عل شرح مبسط للاليه ؟

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 0

في هذا المثال ، نتلاشى في صورة عند التمرير بإضافة فئة fadeIn إليها عندما تدخل منفذ العرض. هذا هو js:

const img = document.querySelector("img")

const callback = (entries, observer) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.classList.add("fadeIn")
    }
  })
}
const options = {}

const myObserver = new IntersectionObserver(callback, options)
myObserver.observe(img)

إنشاء مراقب التقاطع intersection observer

أولاً ، نقوم بإنشاء مراقب تقاطع عن طريق استدعاء المُنشئ الخاص به وتمريره وظيفة callback وكائن خيارات اختياري.

الخيارات كائن له 3 خصائص:

const options = {
  root: null,
  rootMargin: '0px',
  threshold: 0
}
  • root : افتراضي فارغ. إنه منفذ العرض. يمكن أن يكون المستند أو عنصر HTML. إذا كان الجذر فارغًا ، يتم تعيين المستند افتراضيًا.
  • rootMargin: الافتراضي 0 بكسل. يحدد إزاحات كل جانب من المربع المحيط بالجذر. بمعنى آخر ، تقلل القيم الموجبة من المربع المحيط بالجذر وتزيده القيم السالبة. حاول تمرير المربعات الثلاثة في هذا المثال.

callback 

const callback = (entries, observer) => {
  entries.forEach(entry => {
	// يصف كل إدخال تغييرًا في التقاطع لواحد تمت ملاحظته
     // العنصر الهدف:
    //   entry.boundingClientRect
    //   entry.intersectionRatio
    //   entry.intersectionRect
    //   entry.isIntersecting
    //   entry.rootBounds
    //   entry.target
    //   entry.time
  });
};

لقد استخدمتهما في تحريك fadeIn:

const callback = (entries, observer) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.classList.add("fadeIn")
    }
  })
}

لتحديد عنصر مراد مراقبته ، نستخدم دالة observe()  الخاصة بمراقب التقاطع.

إذا كنت تريد ملاحظة العديد من العناصر ، فعليك إضافتها واحدة تلو الأخرى.

myObserver.observe(img1)
myObserver.observe(img2)
myObserver.observe(img3)
//----- أو
const imgList = document.querySelectorAll(".imgToAnimate")

imgList.forEach(img => {
  myObserver.observe(img)
})

ﻹيقافها 

myObserver.unobserve(img)
// ----- أو
const callback = (entries, observer) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.classList.add("fadeIn")
      observer.unobserve(entry.target) // دالة إيقاف
    }
  })
}

وهذا مثال 

<!------------------HTML--------------->
<div class="container">
    <div class="wrapper">
      <img class="imgA" src="https://ljc-dev.github.io/hosted-assets/thumb-a.png" alt="avatar a">
    </div>
    <div class="wrapper">
      <img class="imgB" src="https://ljc-dev.github.io/hosted-assets/thumb-b.png" alt="avatar b">
    </div>
    <div class="wrapper">
      <img class="imgC" src="https://ljc-dev.github.io/hosted-assets/thumb-c.png" alt="avatar c">
    </div>
    <div class="wrapper">
      <img class="imgD" src="https://ljc-dev.github.io/hosted-assets/thumb-d.png" alt="avatar d">
    </div>
  </div>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html, body {
  width: 100%;
}

html {
  scroll-behavior: smooth;
}

.container {
  width: 100%;
  height: 100vh;
  overflow-x: hidden;
  overflow-y: auto;
  padding-top: 12rem;
}

.wrapper {
  position: relative;
  margin: 5rem auto;
  width: 400px;
  height: 400px;
}

img {
  position: absolute;
  top: 0;
  left: 0;
  height: 400px;
  opacity: 0;
  width: 400px;
  transition: all 1s;
}

.imgA {
  transform: translateX(-200px);
  opacity: 0;
}

.imgB {
  transform: translateX(200px);
  opacity: 0;
}

.imgC {
    transform: translateY(200px);
  opacity: 0;
}

.imgD {
  transform: scale(0);
}

.fadeInLeft {
  transform: translateX(0px);
  opacity: 1;
}

.fadeInRight {
  transform: translateX(0px);
  opacity: 1;
}

.fadeInBtm {
  transform: translateY(0px);
  opacity: 1;
}

.zoomIn {
  transform: scale(1);
  opacity: 1;
}
const container = document.querySelector(".container")
const wrappers = document.querySelectorAll(".wrapper")
const imgs = document.querySelectorAll("img")
const animClasses = [
  "fadeInLeft",
  "fadeInRight",
  "fadeInBtm",
  "zoomIn",
]
const observer = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    const currentIndex = Array.from(wrappers).indexOf(entry.target)
    if (entry.isIntersecting) {
      imgs[currentIndex].classList.add(animClasses[currentIndex])
    } else {
      if (entry.boundingClientRect.y > 0) {
        imgs[currentIndex].classList.remove(animClasses[currentIndex])
      }
    }
  })
}, {
  root: container,
  threshold: 0.1,
})


wrappers.forEach(wrapper => {
  observer.observe(wrapper)
})

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...