转换函数以将其用作“on”事件

时间:2016-11-19 17:19:20

标签: javascript jquery

我目前有这个功能:

function isInView() {
  var windowStart = $(window).scrollTop();
  var windowEnd = windowStart + $(window).height();

  $('.box').each(function() {
    var box = $(this);
    var start = box.offset().top;
    var end = start + box.height();

    if (windowStart <= start && windowEnd >= end) {
      box.addClass('active');
    } else {
      box.removeClass('active');
    }
  });
}

$(document).scroll(isInView);

此函数检查视口中是否有整个元素可见(jsfiddle),并从元素中添加/删除active类。

但是,我希望能够将此功能用作“on”事件,以便我可以应用于许多不同的元素。这意味着以某种方式转换函数并为其分配自己的自定义事件,如isinview

换句话说,我希望能够像这样使用它:

$('.box').on('isinview', function () {
    if (elementIsInView) {
        // make the box red
    } else {
        // make the box the original color
    }
});

或者换一个不同的元素:

$('.nav').on('isinview', function () {
    if (elementIsInView) {
        // make the nav bigger
    } else {
        // make the nav the original height
    }
});

我该怎么做?

2 个答案:

答案 0 :(得分:1)

&#13;
&#13;
jQuery(function($) {
    var $window = $(window);

    function notifyElementsInView() {
        var windowStart = $window.scrollTop(),
            windowEnd = windowStart + $window.height();
		
		$('.bindInView').each(function() {
			var $element = $(this),
				start = $element.offset().top,
				end = start + $element.height();
			
			if (windowStart <= start && windowEnd >= end) {
				$element.trigger('viewEnter');
			} else {
				$element.trigger('viewExit');
			}
		});
    }
	
	$('.box')
		.on('viewEnter', function() {
			$(this).addClass('active');
		})
		.on('viewExit', function() {
			$(this).removeClass('active');
		});
	
	notifyElementsInView();
	$(document).on('scroll', notifyElementsInView);
	$window.on('resize', notifyElementsInView);
});
&#13;
body {
    margin: 50px;
}

.container {
    width: 300px;
    background: lightgrey;
    padding: 50px;
}

.box {
    display: block;
    width: 100%;
    height: 300px;
    background: grey;
}

.box:not(:last-of-type) {
    margin-bottom: 50px;
}

.box.active {
    background: red;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
    <div class="box"></div>
    <div class="box bindInView"></div>
    <div class="box bindInView"></div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您可以将其重写为插件,并触发事件

&#13;
&#13;
$.fn.isInView = function() {
  var self = this;
  $(window).on('scroll resize', function() {
    var windowStart = $(window).scrollTop();
    var windowEnd   = windowStart + $(window).height();

    self.each(function() {
      var box   = $(this);
      var start = box.offset().top;
      var end   = start + box.height();

      if (windowStart <= start && windowEnd >= end) {
        if (!box.data('inview')) box.trigger('isinview').data('inview', true);
      } else {
        if (box.data('inview') ) box.trigger('hasleftview').data('inview', false);
      }
    });
  }).trigger('scroll');
  return self;
}

$('.box')
  .on('isinview', function() {
    $(this).addClass('active');
}).on('hasleftview', function() {
    $(this).removeClass('active');
}).isInView(); // call plugin after events are bound
&#13;
body {
  margin: 50px;
}
.container {
  width: 300px;
  background: lightgrey;
  padding: 50px;
}
.box {
  display: block;
  width: 100%;
  height: 300px;
  background: grey;
}
.box:not(:last-of-type) {
  margin-bottom: 50px;
}
.box.active {
  background: red;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>
&#13;
&#13;
&#13;