jQuery.appear只有当整个元素都是视口时才会触发

时间:2013-01-31 05:11:50

标签: javascript jquery

我目前正在使用jQuery.appear来更改元素进入视口时的类别。该插件工作得很好,除了当元素的顶部进入视图时它向右触发。我想要调整它,以便它只在整个元素在视口内或接近存在时触发。

CODE:

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

2 个答案:

答案 0 :(得分:1)

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

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

the site of the plugin上有一些例子。

答案 1 :(得分:0)

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

这是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>

改变了now.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);