javascript jQuery.appear 仅在整个元素为视口时触发

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14618913/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 22:08:03  来源:igfitidea点击:

jQuery.appear to fire only when the entire element in is viewport

javascriptjquery

提问by Lea

I'm currently using jQuery.appearto change the class of elements as they come into the viewport. The plugin works great, except that it fires right as the top of the element comes into view. I am wanting to adapt it so it only fires when the entire element is inside the viewport, or near to being.

我目前正在使用jQuery.appear来更改进入视口的元素类。该插件效果很好,只是它在元素顶部进入视野时立即触发。我想调整它,以便它仅在整个元素位于视口内或接近存在时触发。

CODE:

代码:

$('someselector').appear();
$('someselector').on('appear', function() {
    $(this).removeClass('on').addClass('off');
    $(this).siblings().removeClass('off').addClass('on');
});

采纳答案by wcraft

jQuery Waypoints plugin could be useful also. It triggers an action, when the element became to be visible on the screen.

jQuery Waypoints 插件也很有用。当元素在屏幕上可见时,它会触发一个动作。

$('.entry').waypoint(function() {
   alert('The element is appeared on the screen.');
});

There are some examples on the site of the plugin.

插件站点上有一些示例。

回答by HMR

I have changed some of the code so you can check if an element is fully visible. Removed the code that will trigger an event since it's harder to clean up using destroy (not implemented yet). I will try and make it according to the documentation: http://docs.jquery.com/Plugins/Authoring

我更改了一些代码,以便您可以检查元素是否完全可见。删除了将触发事件的代码,因为使用 destroy 更难清理(尚未实现)。我会尝试根据文档制作它:http: //docs.jquery.com/Plugins/Authoring

Here is the html page:

这是html页面:

<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<script src="appear.js"></script>
<script>
    $(document).ready(function(){
        //TODO: not sure if there is such a thing as selector
        //  namespaces but could try that to add both appear and
        //  fully-appear to same selector elements
        $('#fully').appear(function(){
            console.log("full view");
        },{fullView:true});
        $('#partly').appear(function(){
            console.log("partly visible");
        });
        $(window).scrollTop(1400).scrollLeft(1000);
    });
</script>
</head>
<body >
    <div style="width:3000px;height: 3000px"></div>
    <div id="fully" style="width:50px;height:75px;
    position: absolute;left:1500px;top:1500px;
    background: black">
    </div>
    <div id="partly" style="width:50px;height:75px;
    position: absolute;left:1450px;top:1350px;
    background: yellow">
    </div>
</body>
</html>

And the changed appear.js

和改变的出现.js

/*
* jQuery appear plugin
*
* Copyright (c) 2012 Andrey Sidorov
* licensed under MIT license.
* Edit by HRM 2013 02 01
* https://github.com/morr/jquery.appear/
*
* Version: 0.2.1
*/
(function($) {
  var selectors = [];
  var $window = $(window);
  var $document = $(document);

  function process(p) {
    p.checkLock = false;
    var $appeared = p.elements.filter(function() {
        return $(this).is(p.filterName);
    });
    if($appeared.length==0){
      return;
    }
    p.callback($appeared);
  }

  // "appeared" custom filter
  $.expr[':']['appeared'] = function(element) {
    var $element = $(element);
    if (!$element.is(':visible')) {
      return false;
    }

    var window_left = $window.scrollLeft();
    var window_top = $window.scrollTop();
    var offset = $element.offset();
    var left = offset.left;
    var top = offset.top;
    if (top + $element.height() >= window_top &&
        top - ($element.data('appear-top-offset') || 0)
          <= window_top + $window.height() &&
        left + $element.width() >= window_left &&
        left - ($element.data('appear-left-offset') || 0)
          <= window_left + $window.width()) {
      return true;
    } else {
      return false;
    }
  }

   // "in-full-view" custom filter
  $.expr[':']['fully-appeared'] = function(element) {
    var $element = $(element);
    if (!$element.is(':visible')) {
      return false;
    }
    wLeft=$window.scrollLeft();
    wTop=$window.scrollTop();
    var offset = $element.offset();
    var left = offset.left- ($element.data
      ('appear-left-offset') || 0);
    var right = (offset.left+$element.width()) -
      ($element.data('appear-left-offset') || 0);
    var top = offset.top - ($element.data
      ('appear-top-offset') || 0);
    var bottom = offset.top+$element.height();
    var window_left = wLeft;
    var window_top = wTop;
    var window_right = wLeft+ $window.width();
    var window_bottom = wTop+$window.height();

    if (window_bottom>=bottom&&
        window_top<=top&&
        window_left<=left&&
        window_right>=right ) {
      return true;
    } else {
      return false;
    }
  }

  function compare(o1,o2){
    //simple compare, assumes all properties of o1 and o2 are
    //  simple types make sure that o1 is not undefined
    //  comparing goes much further but requires writing another
    //  extension
    if(typeof o2=="undefined"){
      return false;
    }
    var i;
    for(i in o1){
      if(typeof o2[i]=="undefined"){
        return false;
      }
    }
    for(i in o1){
      if(o1[i]!=o2[i]){
        return false;
      }
    }
    return true;
  }

  function checkExist(selector){
    return !(typeof selectors[selector]=="undefined");
  }

  $.fn.extend({
    // watching for element's appearance in browser viewport
    appear: function(callback, options) {
      if(typeof callback != "function"){
        throw("Have to provide a callback: "
          +"$('selector').appear(function()....");
      }
      var defaults = {
        interval: 250
      }
      var index=this.selector;
      if(index==""){
        throw("Can't use an empty selector with this function.");
      }
      $.extend(defaults, options || {});
      var exist=checkExist(index);
      if(!exist){
        selectors[index]=defaults;
      }
      var checkBind=compare(defaults,
        selectors[index]);
      selectors[index]=defaults;
      var p={
        checkLock:false,
        filterName:(defaults.fullView)?":fully-appeared":":appeared",
        callback:callback,
        elements:this
      }
      if ((!checkBind)||(!exist)) {
        $(window).off("scroll."+index,on_check)
          .on("resize."+index,on_check);
        var on_check = function() {
          if (p.checkLock) {
            return;
          }
          p.checkLock = true;
          setTimeout(function(){
            process(p);
          }, defaults.interval);
        };

        $(window).on("scroll."+index,on_check)
          .on("resize."+index,on_check);
      }

      if (options && options.force_process) {
        setTimeout(process, defaults.interval);
      }
      return $(this.selector);
    }
  });

  $.extend({
    // force elements's appearance check
    force_appear: function() {
      if (check_binded) {
        process();
        return true;
      };
      return false;
    }
  });
})(jQuery);