css 使用javascript?将背景色与滚动快照上的随机颜色div匹配,

68bkxrlz  于 2022-12-24  发布在  Java
关注(0)|答案(3)|浏览(103)

我正在通过制作这个网站来练习-https://backstagetalks.com/我创建了可滚动的div,并使每个div生成一个随机颜色。
但是,我想知道如何使用Javascript来识别特定div何时对齐到中心,以便它可以设置背景颜色以匹配该div的颜色
我尝试使用scrollX、scrollY和offSetTop、offsetHeight属性,但是div都有固定的offsetHeight,所以不起作用
我还不知道jquery,我还没有开始学习CSS或JS库/框架,所以我不知道如何使用这些来帮助。
这是代码:

const gra = function (min, max) {
    return Math.random() * (max - min) + min;
};

const init = function () {
    let items = document.querySelectorAll(".scroller div");
    for (let i = 0; i < items.length; i++) {

        items[i].style.minHeight = gra(100, 100) + "vh";

        const randomColor = Math.floor(Math.random() * 16777215).toString(16);
        items[i].style.backgroundColor = "#" + randomColor;
        let itemColor = items[i].style.backgroundColor;
        // items[i].style.borderColor = "#" + ((1 << 24) * Math.random() | 0).toString(16);
    }
}
init();
@import url('https://fonts.googleapis.com/css2?family=Bangers&family=Chivo+Mono:ital,wght@1,500&family=Hanalei+Fill&family=Fredoka+One&display=swap');

html, body{
    margin: 0;
    /* font-family: Arial, Helvetica, sans-serif; */
}
::-webkit-scrollbar {
    display: none;
}

header {
    padding: 0.7em 0 0 0 ;
    color: red;
    font-family: 'Bangers';
    font-size: 25px;
}

header h2 {
    margin: 0;
}

.container {
    height: 100vh;
    display: flex;
    justify-content: space-between;
    /* border: 2px solid brown; */
}

.scroller {
    max-height: 100vh;
    overflow: scroll;
    scroll-snap-type: y mandatory;
    margin: 0 auto;
    width: 100%;
    position: absolute;
    scroll-behavior: smooth;
    z-index: 1;
 
}

.book {
    /* border: 20px solid; */
    margin: 0 auto;
    /* padding: 1em; */
    width: 300px;
    scroll-snap-align: center;
    scroll-padding-top: 300px;
    display: flex;
    flex-flow: column;
    justify-content: center;
    text-align: center;
    font-size: 4em;
}

.links {
    display: flex;
    justify-content: space-between;
    flex-direction: column;
    /* padding: 0 1em; */
}

.links h2 {
    font-family: 'Fredoka One';
    font-weight: 100;
    padding: 0;
}

.issue-list {
    width: fit-content;
    margin-left: auto;
    font-family: 'Arial';
    font-size: 18px;
    z-index: 1;
}

.issue-list p{
    margin: 0;
}

.issue-list p a {
    cursor: pointer;
    text-decoration: none;
    color: black;
}

.info {
    position: absolute;
    bottom: 0;
    /* padding: 0 1em; */
}

.info p {
    font-size: 19px;
    font-weight: bold;
    font-family: 'Chivo Mono';
}
<div id="background" class="container">
    <header>
        <h2>BACKSTAGE TALKS</h2>
    </header>
    <div class="info">
        <p> Backstage Talks is a magazine <br>
            casual, but in depth dialogues <br>
            on design and business. Our decisions <br>
            shape and influence this complex <br>
            world—to have a chance to make the <br>
            right ones, we need to talk </p>
    </div>
    <div id="scroll-box" class="scroller">
        <div class="book" id="book_issue-1">1</div>
        <div class="book" id="book_issue-2">2</div>
        <div class="book" id="book_issue-3">3</div>
        <div class="book" id="book_issue-4">4</div>
        <div class="book" id="book_issue-5">5</div>
        <div class="book" id="book_issue-6">6</div>
    </div>

    <div class="links">
        <h2>info@backstagetalks.com</h2>
        <div class="issue-list">
            <p id="issue1"><a href="#book_issue-1">Issue #1</a></p>
            <p id="issue2"><a href="#book_issue-2">Issue #2</a></p>
            <p id="issue3"><a href="#book_issue-3">Issue #3</a></p>
            <p id="issue4"><a href="#book_issue-4">Issue #4</a></p>
            <p id="issue5"><a href="#book_issue-5">Issue #5</a></p>
            <p id="issue6"><a href="#book_issue-6">Issue #6</a></p>
        </div>
    </div>

</div>
k5ifujac

k5ifujac1#

你可以使用一个javascript函数(在这个例子中是scrollHandler)来检查你的一本书div是什么时候被捕捉的,就像下面的答案中的一个:
https://stackoverflow.com/a/66029649/5334486
一旦知道了"snapped"事件发生的时间,就可以遍历books的div,检查当前显示的是哪一个,测试getBoundingClientRect().top是否等于零。
最后,一旦知道当前对齐的是哪个div,就可以为body指定相同的背景色。

const gra = function(min, max) {
  return Math.random() * (max - min) + min;
};

const init = function() {
  let items = document.querySelectorAll(".scroller div");
  for (let i = 0; i < items.length; i++) {

    items[i].style.minHeight = gra(100, 100) + "vh";

    const randomColor = Math.floor(Math.random() * 16777215).toString(16);
    items[i].style.backgroundColor = "#" + randomColor;
    let itemColor = items[i].style.backgroundColor;
    // items[i].style.borderColor = "#" + ((1 << 24) * Math.random() | 0).toString(16);
  }
}
init();

function scrollHandler(e) {
  var atSnappingPoint = e.target.scrollTop % e.target.offsetHeight === 0;
  var timeOut = atSnappingPoint ? 0 : 150;

  clearTimeout(e.target.scrollTimeout);

  e.target.scrollTimeout = setTimeout(function() {
    //using the timeOut to evaluate scrolling state
    if (!timeOut) {
      console.log('Scroller snapped!');
      document.querySelectorAll(".scroller div").forEach(theDiv => {
         if (theDiv.id, theDiv.getBoundingClientRect().top == 0) {
             // THIS IS THE CURRENTLY SNAPPED BOOK
             console.log(theDiv.id, theDiv.style.backgroundColor)
             document.querySelector('body').style.backgroundColor = theDiv.style.backgroundColor
         }
      });
    }
  }, timeOut);
}


document.querySelector(".scroller").addEventListener('scroll', scrollHandler);
@import url('https://fonts.googleapis.com/css2?family=Bangers&family=Chivo+Mono:ital,wght@1,500&family=Hanalei+Fill&family=Fredoka+One&display=swap');
html,
body {
  margin: 0;
  /* font-family: Arial, Helvetica, sans-serif; */
}

::-webkit-scrollbar {
  display: none;
}

header {
  padding: 0.7em 0 0 0;
  color: red;
  font-family: 'Bangers';
  font-size: 25px;
}

header h2 {
  margin: 0;
}

.container {
  height: 100vh;
  display: flex;
  justify-content: space-between;
  /* border: 2px solid brown; */
}

.scroller {
  max-height: 100vh;
  overflow: scroll;
  scroll-snap-type: y mandatory;
  margin: 0 auto;
  width: 100%;
  position: absolute;
  scroll-behavior: smooth;
  z-index: 1;
}

.book {
  /* border: 20px solid; */
  margin: 0 auto;
  /* padding: 1em; */
  width: 300px;
  scroll-snap-align: center;
  scroll-padding-top: 300px;
  display: flex;
  flex-flow: column;
  justify-content: center;
  text-align: center;
  font-size: 4em;
}

.links {
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  /* padding: 0 1em; */
}

.links h2 {
  font-family: 'Fredoka One';
  font-weight: 100;
  padding: 0;
}

.issue-list {
  width: fit-content;
  margin-left: auto;
  font-family: 'Arial';
  font-size: 18px;
  z-index: 1;
}

.issue-list p {
  margin: 0;
}

.issue-list p a {
  cursor: pointer;
  text-decoration: none;
  color: black;
}

.info {
  position: absolute;
  bottom: 0;
  /* padding: 0 1em; */
}

.info p {
  font-size: 19px;
  font-weight: bold;
  font-family: 'Chivo Mono';
}
<div id="background" class="container">
  <header>
    <h2>BACKSTAGE TALKS</h2>
  </header>
  <div class="info">
    <p> Backstage Talks is a magazine <br> casual, but in depth dialogues <br> on design and business. Our decisions <br> shape and influence this complex <br> world—to have a chance to make the <br> right ones, we need to talk </p>
  </div>
  <div id="scroll-box" class="scroller">
    <div class="book" id="book_issue-1">1</div>
    <div class="book" id="book_issue-2">2</div>
    <div class="book" id="book_issue-3">3</div>
    <div class="book" id="book_issue-4">4</div>
    <div class="book" id="book_issue-5">5</div>
    <div class="book" id="book_issue-6">6</div>
  </div>

  <div class="links">
    <h2>info@backstagetalks.com</h2>
    <div class="issue-list">
      <p id="issue1"><a href="#book_issue-1">Issue #1</a></p>
      <p id="issue2"><a href="#book_issue-2">Issue #2</a></p>
      <p id="issue3"><a href="#book_issue-3">Issue #3</a></p>
      <p id="issue4"><a href="#book_issue-4">Issue #4</a></p>
      <p id="issue5"><a href="#book_issue-5">Issue #5</a></p>
      <p id="issue6"><a href="#book_issue-6">Issue #6</a></p>
    </div>
  </div>

</div>
g2ieeal7

g2ieeal72#

您可以逐个检查div的滚动位置,并在.scroll-box上附加一个srcoll事件侦听器,然后根据滚动位置分配颜色。

const gra = function (min, max) {
    return Math.random() * (max - min) + min;
};

const init = function () {
    let items = document.querySelectorAll(".scroller div");
    let positions = [];
    let itemcolors = [];
    for (let i = 0; i < items.length; i++) {
        let item = items[i];
        
        item.style.minHeight = gra(100, 100) + "vh";
        const randomColor = Math.floor(Math.random() * 16777215).toString(16);
        item.style.backgroundColor = "#" + randomColor;
        let itemColor = item.style.backgroundColor;
        
        // Arrays to hold colors and position in same index positions
        itemcolors.push(itemColor)
        positions.push(item.offsetTop)
        /* on scrolling, get the offset and check against the existing
        scroll positions of the divs */
        
        document.getElementById('scroll-box').addEventListener('scroll', function(){
            let scrolloffset = document.getElementById('scroll-box').scrollTop
            positions.forEach((position, index) => {
                // Give an allowance of + or - 5 for padding and other spacing factors
                if(position >= (scrolloffset-5) && position <= (scrolloffset+5)){
                    document.getElementById('background').style.backgroundColor = itemcolors[index];
                }
            })
        })
        
        // items[i].style.borderColor = "#" + ((1 << 24) * Math.random() | 0).toString(16);
    }
    
}
init();
@import url('https://fonts.googleapis.com/css2?family=Bangers&family=Chivo+Mono:ital,wght@1,500&family=Hanalei+Fill&family=Fredoka+One&display=swap');

html, body{
    margin: 0;
    /* font-family: Arial, Helvetica, sans-serif; */
}
::-webkit-scrollbar {
    display: none;
}

header {
    padding: 0.7em 0 0 0 ;
    color: red;
    font-family: 'Bangers';
    font-size: 25px;
}

header h2 {
    margin: 0;
}

.container {
    height: 100vh;
    display: flex;
    justify-content: space-between;
    /* border: 2px solid brown; */
}

.scroller {
    max-height: 100vh;
    overflow: scroll;
    scroll-snap-type: y mandatory;
    margin: 0 auto;
    width: 100%;
    position: absolute;
    scroll-behavior: smooth;
    z-index: 1;
 
}

.book {
    /* border: 20px solid; */
    margin: 0 auto;
    /* padding: 1em; */
    width: 300px;
    scroll-snap-align: center;
    scroll-padding-top: 300px;
    display: flex;
    flex-flow: column;
    justify-content: center;
    text-align: center;
    font-size: 4em;
}

.links {
    display: flex;
    justify-content: space-between;
    flex-direction: column;
    /* padding: 0 1em; */
}

.links h2 {
    font-family: 'Fredoka One';
    font-weight: 100;
    padding: 0;
}

.issue-list {
    width: fit-content;
    margin-left: auto;
    font-family: 'Arial';
    font-size: 18px;
    z-index: 1;
}

.issue-list p{
    margin: 0;
}

.issue-list p a {
    cursor: pointer;
    text-decoration: none;
    color: black;
}

.info {
    position: absolute;
    bottom: 0;
    /* padding: 0 1em; */
}

.info p {
    font-size: 19px;
    font-weight: bold;
    font-family: 'Chivo Mono';
}
<div id="background" class="container">
    <header>
        <h2>BACKSTAGE TALKS</h2>
    </header>
    <div class="info">
        <p> Backstage Talks is a magazine <br>
            casual, but in depth dialogues <br>
            on design and business. Our decisions <br>
            shape and influence this complex <br>
            world—to have a chance to make the <br>
            right ones, we need to talk </p>
    </div>
    <div id="scroll-box" class="scroller">
        <div class="book" id="book_issue-1">1</div>
        <div class="book" id="book_issue-2">2</div>
        <div class="book" id="book_issue-3">3</div>
        <div class="book" id="book_issue-4">4</div>
        <div class="book" id="book_issue-5">5</div>
        <div class="book" id="book_issue-6">6</div>
    </div>

    <div class="links">
        <h2>info@backstagetalks.com</h2>
        <div class="issue-list">
            <p id="issue1"><a href="#book_issue-1">Issue #1</a></p>
            <p id="issue2"><a href="#book_issue-2">Issue #2</a></p>
            <p id="issue3"><a href="#book_issue-3">Issue #3</a></p>
            <p id="issue4"><a href="#book_issue-4">Issue #4</a></p>
            <p id="issue5"><a href="#book_issue-5">Issue #5</a></p>
            <p id="issue6"><a href="#book_issue-6">Issue #6</a></p>
        </div>
    </div>

</div>
ogq8wdun

ogq8wdun3#

您可以使用Element.getBoundingClientRect()测试元素是否(完全)位于视口中,并将值与窗口w/h进行比较。

const gra = function(min, max) {
  return Math.random() * (max - min) + min;
};

const init = function() {
  let items = document.querySelectorAll(".scroller div");
  for (let i = 0; i < items.length; i++) {

    items[i].style.minHeight = gra(100, 100) + "vh";

    const randomColor = ('00000' + Math.floor(Math.random() * 16777216).toString(16)).substr(-6);
    items[i].style.backgroundColor = "#" + randomColor;
    let itemColor = items[i].style.backgroundColor;
    // items[i].style.borderColor = "#" + ((1 << 24) * Math.random() | 0).toString(16);
  }
}
init();

function isInViewport(element) {
  const { top, left, bottom, right } = element.getBoundingClientRect();
  return (
    top >= 0 &&
    left >= 0 &&
    bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
    right <= (window.innerWidth || document.documentElement.clientWidth)
  );
}
const scroller = document.querySelector(".scroller");

scroller.addEventListener("scroll", ({ target }) => {
  [...target.childNodes]
    .filter(child => child.nodeType != 3 && isInViewport(child))
    .forEach(child => background.style.backgroundColor = child.style.backgroundColor);
});
/* initial */
scroller.dispatchEvent(new Event("scroll"));
@import url('https://fonts.googleapis.com/css2?family=Bangers&family=Chivo+Mono:ital,wght@1,500&family=Hanalei+Fill&family=Fredoka+One&display=swap');
html,
body {
  margin: 0;
  /* font-family: Arial, Helvetica, sans-serif; */
}

::-webkit-scrollbar {
  display: none;
}

header {
  padding: 0.7em 0 0 0;
  color: red;
  font-family: 'Bangers';
  font-size: 25px;
}

header h2 {
  margin: 0;
}

.container {
  height: 100vh;
  display: flex;
  justify-content: space-between;
  /* border: 2px solid brown; */
}

.scroller {
  max-height: 100vh;
  overflow: scroll;
  scroll-snap-type: y mandatory;
  margin: 0 auto;
  width: 100%;
  position: absolute;
  scroll-behavior: smooth;
  z-index: 1;
}

.book {
  /* border: 20px solid; */
  margin: 0 auto;
  /* padding: 1em; */
  width: 300px;
  scroll-snap-align: center;
  scroll-padding-top: 300px;
  display: flex;
  flex-flow: column;
  justify-content: center;
  text-align: center;
  font-size: 4em;
}

.links {
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  /* padding: 0 1em; */
}

.links h2 {
  font-family: 'Fredoka One';
  font-weight: 100;
  padding: 0;
}

.issue-list {
  width: fit-content;
  margin-left: auto;
  font-family: 'Arial';
  font-size: 18px;
  z-index: 1;
}

.issue-list p {
  margin: 0;
}

.issue-list p a {
  cursor: pointer;
  text-decoration: none;
  color: black;
}

.info {
  position: absolute;
  bottom: 0;
  /* padding: 0 1em; */
}

.info p {
  font-size: 19px;
  font-weight: bold;
  font-family: 'Chivo Mono';
}
<div id="background" class="container">
  <header>
    <h2>BACKSTAGE TALKS</h2>
  </header>
  <div class="info">
    <p> Backstage Talks is a magazine <br> casual, but in depth dialogues <br> on design and business. Our decisions <br> shape and influence this complex <br> world—to have a chance to make the <br> right ones, we need to talk </p>
  </div>
  <div id="scroll-box" class="scroller">
    <div class="book" id="book_issue-1">1</div>
    <div class="book" id="book_issue-2">2</div>
    <div class="book" id="book_issue-3">3</div>
    <div class="book" id="book_issue-4">4</div>
    <div class="book" id="book_issue-5">5</div>
    <div class="book" id="book_issue-6">6</div>
  </div>

  <div class="links">
    <h2>info@backstagetalks.com</h2>
    <div class="issue-list">
      <p id="issue1"><a href="#book_issue-1">Issue #1</a></p>
      <p id="issue2"><a href="#book_issue-2">Issue #2</a></p>
      <p id="issue3"><a href="#book_issue-3">Issue #3</a></p>
      <p id="issue4"><a href="#book_issue-4">Issue #4</a></p>
      <p id="issue5"><a href="#book_issue-5">Issue #5</a></p>
      <p id="issue6"><a href="#book_issue-6">Issue #6</a></p>
    </div>
  </div>

</div>

Intersection Observer API还有一种更现代的方式。
一个一个三个一个一个一个一个一个四个一个一个一个一个一个五个一个

相关问题