简体   繁体   中英

How can i trigger a css class when a reach to a specific div with scroll

i am new to Javascript and i would like your help. I have a code and when you scroll from the top of a page changes css of a class and zooms the images.

What i would like to do is, to put a class in a div ( lets say .start) and when i reach to that class then to start zoom the image.

$(window).scroll(function () {
    var scroll = $(window).scrollTop();

    $(".zoom").css({

        backgroundSize: (100 + scroll / 20) + "%"

    });
});

I guess this question is similar to your problem?

You will need to add your zoom class to the element via .addClass("zoom"); when it is in the viewport.

Well not that exactly.

i have this

   $(window).scroll(function () {
    $('#currentContent').bind('inview', monitor);
        function monitor(event, visible)
        {
            if(visible)
            {
                 $(window).scroll(function () {
                    var scroll = $(window).scrollTop();

                    $(".zoom").css({

                        backgroundSize: (100 + scroll / 20) + "%"

                    });
                });

            }
            else
            {
            // element has gone out of the viewport
            }
        }

    });

The "problem" is var scroll = $(window).scrollTop(); I want the scroll variable to start not from TOP but from the div where i have add a class. I have tried this var scroll = $('.currentContent').offset().top; But nothing happens

Check this: getBoundingClientRect()

HTML
<div class="wrap">
  <div class="content">A</div>
  <div class="content">B</div>
  <div id="start" class="content">C</div>
  <div class="zoom"><!-- Image --></div>
</div>


JS
$(window).scroll(function () {
var target = $('#start')[0].getBoundingClientRect(); // id="start" Element

  // Start zoom at #start element's position
  if (target.top - target.height <= 0) {
    $(".zoom").css({
      backgroundSize: (100 + (target.height - target.top) / 20) + "%"
    });
  }
});

getBoundingClientRect() is returns the size of an element and its position relative to the viewport.

You can check the target Element's position and trigger it.

Demo: https://jsfiddle.net/ghlee/uecb26ft

This is what Intersection Observer was made to do. With this you can watch elements and react when they come into view or intersect with each other.

First you set the options for the IO:

let options = {
  rootMargin: '0px',
  threshold: 1.0
}

let observer = new IntersectionObserver(callback, options);

If you leave out the root option it wall default to your browser window, so once an element that you watch comes into viewport, the callback function gets triggered.

Then you specify which elements you want to observe:

let target = document.querySelector('.zoom'); observer.observe(target);

Here we now watch every element with the class zoom.

Last step is to define the callback function:

let callback = (entries, observer) => { 
  entries.forEach(entry => {
    // Each entry describes an intersection change for one observed
    // target element:
    // like: $(element).addClass('zoom');
  });
};

You can unobserve an element if you don't need it anymore, for example if you only want to play the zoom animation only once when it comes into view.

Also check out this example on how to change bg-color depending on how much of an element is visible on screen. Edit: Maybe this example is more fitting (see comments) because it actually adds a class when user scrolls to the element.

Last point, you can use this polyfill from w3c to support older browsers.

To determine if an element with the desired class is in the viewport (ie, been scrolled to), you could calculate the offset of the .start element and compare it with the current scroll value on scroll.

If the element is in the viewport, you could then zoom the image. The below snippet will increase the image size when you reach it. Just zoom past the height of the red area. If you scroll back up, it should get smaller. You may want a different effect, but the same idea applies.

Also, see my comments in the inViewport function.

 $(window).scroll(function() { if (inViewport($(".start"))) { $(".start").css("height", "200px").css("width", "200px"); } else { $(".start").css("height", "50px").css("width", "50px"); } }); function inViewport(element) { // added extra height so you can see the element change back to smaller size // you could remove this value if you just want the element to change size when out of the viewport const extra = 50; var elementTop = element.offset().top + extra; var elementBottom = elementTop + element.outerHeight(); var viewportTop = $(window).scrollTop(); var viewportBottom = viewportTop + $(window).height(); return elementBottom > viewportTop && elementTop < viewportBottom; }; 
 #placeholder { height: 300px; background-color: red; } .start { height: 50px; width: 50px; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="placeholder"></div> <img class="start" src="https://homepages.cae.wisc.edu/~ece533/images/airplane.png" /> 

Well, you seem to be on the right path. You probably in addition need to pay attention to the background-size property. Instead of the JavaScript strongly named backgroundSize for the css background-size property, accessed through the style object of an element like this; currentElement.style.backgroundSize , you might want to do this; "background-size": (100 + scroll / 20) + "% . Here's a working example that builds upon your existing code:

 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!DOCTYPE html> <html> <head> <title>My page</title> </head> <body> <h1 id="start">My Zoom Heading</h1> <p class="zoom">My zoom area</p> <script> $(window).scroll(function() { var scroll = $(window).scrollTop(); var zoomStart = $("#start").offset().top; if (scroll >= zoomStart) { $(".zoom").css({ "background-size": (100 + scroll / 10) + "%" }); } }); </script> <style> #start { margin-top: 60px; } .zoom { margin-top: 10px; margin-bottom: 300px; width: 300px; height: 300px; background: url('{some-image-url-here}') no-repeat; } </style> </body> </html> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM