【问题标题】:How to make image title display on scroll如何使图像标题显示在滚动条上
【发布时间】:2019-12-24 16:11:25
【问题描述】:

我正在尝试确保 javascript 显示屏幕上每个图像的图像标题。我似乎已经知道如何将标题转换为文本节点,但我不知道如何确保文本仅在图像在屏幕上时显示,而在图像离开屏幕时消失。

请仅使用纯 JavaScript。 谢谢。

ri.addEventListener("scroll", function iT() {
  const iA = Array.from(document.querySelectorAll("#right img"));
  aP = document.querySelector(".aboutProject");

  iA.forEach(function(item) {
    const iT = item.title;
    const iP = item.getBoundingClientRect().top;

    const wH = window.innerHeight / 1.2;
    if (iP < wH && iP >= 0) {
      const h = document.createElement("H4");
      const t = document.createTextNode(iT);
      h.appendChild(t);
      aP.appendChild(h);
    }
  });
});
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
}

body {
  background-color: rgb(254, 238, 228);
  max-width: 100vw;
  min-height: auto;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

.aboutProject {
  display: grid;
  align-content: center;
  justify-items: center;
}

#right {
  width: 50vw;
  height: 100vh;
  display: grid;
  align-items: center;
  justify-content: center;
  overflow-x: hidden;
  overflow-y: auto;
}

#right a img {
  height: 92.5vh;
  width: 50vw;
  object-fit: cover;
  object-position: center;
}
<div class="container">
  <div class="aboutProject">
    <h4>title comes here</h4>
  </div>

  <div id="right">
    <a href="project6" id="lastClone"><img src="https://www.metoffice.gov.uk/binaries/content/gallery/metofficegovuk/hero-images/weather/cloud/cumulus-cloud.jpg" title="project 6clone" /></a>
    <a href="project1"><img src="https://cdn1.epicgames.com/ue/product/Screenshot/StoreUltraDynamicSkyscreenshot1-1920x1080-f5d2cdb93df61507a2e584354de459ca-1920x1080-a431ce7a2eb0a4eb720b25de2ba0aca3.png" title="project 1" /></a>
    <a href="project2"><img src="https://www.rolls-roycemotorcars.com/content/dam/rrmc/marketUK/rollsroycemotorcars_com/2-6-4-under-the-stars/page-properties/rolls-royce-under-the-stars-hero-d.jpg" title="project 2" /></a>
    <a href="project3"><img src="https://www.citynews1130.com/wp-content/blogs.dir/sites/9/2018/05/27/iStock-697020460.jpg" title="project 3" /></a>
    <a href="project4"><img src="https://lh6.googleusercontent.com/GlbCESxjIY2pjzV9B9hwoySVG6sJRErg_ylUlHt2XUm2PWhDpDWBZMOkUL0s4wMImdG8LP8Xm6KfB3KPVddCiBGSJO9psgZ13DkPSjNUngDg1iyGkQvxOQXdLDp1PXyF9b-lVSQ" title="project 4" /></a>
    <a href="project5"><img src="https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2019/07/moon_seen_from_space_station/19494773-1-eng-GB/Moon_seen_from_Space_Station_pillars.jpg" title="project 5" /></a>
    <a href="project6"><img src="https://www.metoffice.gov.uk/binaries/content/gallery/metofficegovuk/hero-images/weather/cloud/cumulus-cloud.jpg" title="project 6" /></a>
    <a href="project1" id="firstClone"><img src="https://cdn1.epicgames.com/ue/product/Screenshot/StoreUltraDynamicSkyscreenshot1-1920x1080-f5d2cdb93df61507a2e584354de459ca-1920x1080-a431ce7a2eb0a4eb720b25de2ba0aca3.png" title="project 1clone" /></a>
  </div>
</div>

【问题讨论】:

标签: javascript foreach addeventlistener appendchild


【解决方案1】:

您需要使用IntersectionObserver API。此 API 用于查看元素是否进入或退出用户的视口,例如用户滚动或滑动时。而且它的速度很快,无需进行复杂的计算。

IntersectionObserver 的实例采用回调函数选项对象。在观察者的回调中,您可以检查entry(这是您正在观察的元素等等)是否为intersecting,这意味着它是否在视图中。选项用于确定何时触发回调。

很高兴听到您知道如何根据 img 元素的属性将元素附加到文档中。但在这种情况下,我假设您的标题将始终相同,因此无需动态生成图像的标题。只需在 HTML 中添加标题并使用 CSS 将其隐藏。然后当图像进入视图时,通过添加一个类来显示标题。
每当图像离开视口时,删除类和 CSS。

我已经修改了下面的示例来演示 IntersectionObserver。

// Callback that is fired whenever an entry enters or leaves the view.
function intersectionCallback(entries) {
  entries.forEach(entry => {
    const { target, isIntersecting } = entry;
    if (isIntersecting && !target.classList.contains('show')) {
      target.classList.add('show');
    } else {
      target.classList.remove('show');
    }
  });
}

// Options for the observer.
const observerOptions = {
  rootMargin: '50px 0px'
};

// Create an instance of the observer with the callback and the options.
const observer = new IntersectionObserver(intersectionCallback, observerOptions);

// Select the right images and observe them all.
const rightImages = document.querySelectorAll("#right a");
rightImages.forEach(image => observer.observe(image));
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
}

body {
  background-color: rgb(254, 238, 228);
  max-width: 100vw;
  min-height: auto;
}

#right {
  width: 50vw;
  height: 100vh;
  display: grid;
  align-items: center;
  justify-content: center;
  overflow-x: hidden;
  overflow-y: auto;
}

#right a {
  display: grid;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}

#right a img {
  grid-area: 1 / 1 / 2 / 2;
  height: 92.5vh;
  width: 50vw;
  object-fit: cover;
  object-position: center;
}

#right a h4 {
  grid-area: 1 / 1 / 2 / 2;
  color: white;
  text-transform: uppercase;
  opacity: 0;
  text-align: center;
  transition: opacity 250ms 250ms ease-in-out;
  z-index: 1;
}

#right a.show h4 {
  opacity: 1;
}
<div class="aboutProject"></div>

<div id="right">
  <a href="project6" id="lastClone">
    <img src="https://www.metoffice.gov.uk/binaries/content/gallery/metofficegovuk/hero-images/weather/cloud/cumulus-cloud.jpg" title="project 6clone" />
    <h4>project 6clone</h4>
  </a>
  <a href="project1"><img src="https://cdn1.epicgames.com/ue/product/Screenshot/StoreUltraDynamicSkyscreenshot1-1920x1080-f5d2cdb93df61507a2e584354de459ca-1920x1080-a431ce7a2eb0a4eb720b25de2ba0aca3.png" title="project 1" />
    <h4>project 1</h4>
  </a>
  <a href="project2"><img src="https://www.rolls-roycemotorcars.com/content/dam/rrmc/marketUK/rollsroycemotorcars_com/2-6-4-under-the-stars/page-properties/rolls-royce-under-the-stars-hero-d.jpg" title="project 2" />
    <h4>project 2</h4>
  </a>
  <a href="project3"><img src="https://www.citynews1130.com/wp-content/blogs.dir/sites/9/2018/05/27/iStock-697020460.jpg" title="project 3" />
    <h4>project 3</h4>
  </a>
  <a href="project4"><img src="https://lh6.googleusercontent.com/GlbCESxjIY2pjzV9B9hwoySVG6sJRErg_ylUlHt2XUm2PWhDpDWBZMOkUL0s4wMImdG8LP8Xm6KfB3KPVddCiBGSJO9psgZ13DkPSjNUngDg1iyGkQvxOQXdLDp1PXyF9b-lVSQ" title="project 4" />
    <h4>project 4</h4>
  </a>
  <a href="project5"><img src="https://www.esa.int/var/esa/storage/images/esa_multimedia/images/2019/07/moon_seen_from_space_station/19494773-1-eng-GB/Moon_seen_from_Space_Station_pillars.jpg" title="project 5" />
    <h4>project 5</h4>
  </a>
  <a href="project6"><img src="https://www.metoffice.gov.uk/binaries/content/gallery/metofficegovuk/hero-images/weather/cloud/cumulus-cloud.jpg" title="project 6" />
    <h4>project 6</h4>
  </a>
  <a href="project1" id="firstClone"><img src="https://cdn1.epicgames.com/ue/product/Screenshot/StoreUltraDynamicSkyscreenshot1-1920x1080-f5d2cdb93df61507a2e584354de459ca-1920x1080-a431ce7a2eb0a4eb720b25de2ba0aca3.png" title="project 1clone" />
    <h4>project 1clone</h4>
  </a>
</div>

如果您有任何问题,或者我不清楚,请告诉我。

【讨论】:

  • 非常感谢,如果h4都设置在同一个地方,这样可以吗?我将图像标题放在屏幕的右下角。
  • 这是否意味着标题保持在同一个位置,但其内容会根据滚动的图像而变化?
  • 是的,就是这样。我已经更新了我的代码 sn-p,所以如果需要,你可以看到我的意思
  • 我明白你的意思。是的,这是可能的,但更复杂,因为您必须对何时显示哪个标题做出条件。因为多个图像可以一起在视口中,所以你显示哪个标题以及何时显示?尝试创建它,如果您无法弄清楚,我们可以再次为您提供帮助。
猜你喜欢
  • 1970-01-01
  • 2010-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
  • 1970-01-01
  • 2016-08-08
  • 1970-01-01
相关资源
最近更新 更多