简体   繁体   English

将函数应用于所有具有相同类的元素

[英]apply function on all elements with same class

I have a simple function which detects if an element is in the viewport or that it is visible. 我有一个简单的函数,可以检测元素是否在视口中或可见。 If that element is visible, on every scroll I move that element down with .css() and change the top property to achieve some parallax effect. 如果该元素可见,则在每次滚动时,我都使用.css()将其向下移动,并更改top属性以获得某种视差效果。 This element on which I check is in the viewport and when it moves it is repeated X times on the page. 我检查的该元素在视口中,并且在其移动时在页面上重复X次。 Everything works but only on the first element has this problem, all other elements inherit top position from the first. 一切正常,但仅在第一个元素上有此问题,所有其他元素都从第一个继承顶部位置。

Demo: http://codepen.io/riogrande/pen/RRVVwq (scroll down for effect). 演示: http : //codepen.io/riogrande/pen/RRVVwq (向下滚动以获取效果)。

EDIT: Some who answered had the wrong idea what I want, so I want the title (element) to move on scroll but only when its in viewport(visible). 编辑:有些回答的人有一个错误的主意我想要什么,所以我希望标题(元素)在滚动时移动,但仅当其在视口(可见)中时才能移动。 So when the first element with same class is visible its moving with scroll, then when you scroll below it its not visible anymore it should not move but the other one which is visible should be moving etc etc. 因此,当第一个具有相同类的元素可见时,它会随着滚动而移动,然后当您在其下滚动时,它不再可见,它就不应移动,而另一个可见的元素应在移动等。

Jquery: jQuery:

(function($) {

  'use strict';

  $.prototype.isVisible = function() {
    var rect = this[0].getBoundingClientRect();
    return (
      (rect.height > 0 || rect.width > 0) &&
      rect.bottom >= 0 &&
      rect.right >= 0 &&
      rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
      rect.left <= (window.innerWidth || document.documentElement.clientWidth)
    );
  };

  function doCheck() {
    var elementToDetect = $('.text');
    var scrolled = $(window).scrollTop();
    if (elementToDetect.isVisible()) {
      elementToDetect.css('top', (-100 + (scrolled * 0.2)) + 'px');
    }
  }

  $(document).ready(function() {
    doCheck();
  });

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

})(jQuery);

jQuery applies operations like css() on each element matching the selector. jQuery在与选择器匹配的每个元素上应用css()类的操作。

So if you iterate the jQuery object, you get this: 因此,如果您迭代jQuery对象,则会得到以下信息:

  function doCheck() {
    var elementToDetect = $('.text');
    var scrolled = $(window).scrollTop();
    for (var index = 0; index < elementToDetect.length; index++) {
      var element = $(elementToDetect[index]);
      if (element.isVisible()) {
        element.css('top', (-100 + (scrolled * 0.2)) + 'px');
      }
    }
  }

Which still has a problem, in that all the text maintain the same top relative to their image. 这仍然有一个问题,因为所有文本相对于其图像都保持相同的顶部。

Edit: Actually, the way I understand what you're doing, you want to let them all move in the same way as you scroll, so each starts above the image when it comes into view. 编辑:实际上,按照我了解您的操作方式,您想让它们全部以与滚动相同的方式移动,因此每当它们出现在视图上方时,它们都从图像上方开始。 This is closer to what you need: 这更接近您的需求:

  function doCheck() {
    var elementToDetect = $('.text');
    for (var index = 0; index < elementToDetect.length; index++) {
      var text = elementToDetect[index];
      var parent = text.parentElement;
      var parentTop = parent.getBoundingClientRect().top;
      var scrolled = (window.innerHeight - parentTop);
      if (scrolled < 0) {
        scrolled = 0;
      }
      if (parentTop < window.innerHeight) {
        $(text).css('top', (-100 + (scrolled * 0.2)) + 'px');
      }
    }
  }

Basically, looking at scrollTop() is wrong, because you really want the position of the parent div to determine the placement of your text. 基本上,查看scrollTop()是错误的,因为您确实希望父div的位置确定文本的位置。

Here you need to check for each .text on the scroll: 在这里,您需要检查滚动条上的每个.text

function doCheck() {
  var elementToDetect = $('.text');
  var scrolled = $(window).scrollTop();
  elementToDetect.each(function(i, txtEl) {
    if (txtEl.isVisible()) {
      txtEl.css('top', (-100 + (scrolled * 0.2)) + 'px');
    }
  });
}

And most likely you want to have a debouce there in the window.scroll : 而且最有可能您想在window.scroll中放一个消音器:

var timer;
$(window).scroll(function() {
    if(timer){ clearTimeout(timer); }
    timer = setTimeout(function(){
       doCheck();
    }, 900);
});

$('.text') returns an array of elements. $('.text')返回元素数组。 You need to apply the css transform to each item rather than the array of items. 您需要将css转换应用于每个项目,而不是项目数组。 The below code may require an update to get the output you would like but I think it should get you going. 下面的代码可能需要更新才能获取您想要的输出,但是我认为它应该可以使您顺利进行。

function doCheck() {
  var scrolled = $(window).scrollTop();
  $('.text').each(function() {
    if($(this).isVisible()) {
      $(this).css('top', (-100 + (scrolled * 0.2)) + 'px');
    }
  })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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