Skip to content

Instantly share code, notes, and snippets.

@mach3
Last active December 21, 2015 00:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mach3/6221328 to your computer and use it in GitHub Desktop.
Save mach3/6221328 to your computer and use it in GitHub Desktop.
表示領域に要素が入ったら何かするための係の人。
(function($, win, doc){
$.peekaboo = {
DATA_INIT: "peekabooInit",
DATA_MODE_FULL: "peekabooFullMode",
DATA_SHOW: "peekabooShow",
EVENT_SHOW: "peekabooShow",
EVENT_HIDE: "peekabooHide",
defaults: {
full: true,
show: null,
hide: null
},
onScroll: function(el){
var node, offset, scroll, show;
node = $(el);
offset = this.getOffset(el);
scroll = this.getScroll();
if(node.data(this.DATA_MODE_FULL)){
show = offset.top >= scroll.top
&& offset.left >= scroll.left
&& offset.right <= scroll.right
&& offset.bottom <= scroll.bottom;
} else {
show = offset.bottom >= scroll.top
&& offset.right >= scroll.left
&& offset.left <= scroll.right
&& offset.top <= scroll.bottom;
}
if(show !== node.data(this.DATA_SHOW)){
node.trigger(show ? this.EVENT_SHOW : this.EVENT_HIDE);
node.data(this.DATA_SHOW, show);
}
},
getOffset: function(el){
var node, offset, o;
node = $(el);
offset = node.offset();
o = {
top: offset.top,
left: offset.left,
width: node.prop("offsetWidth"),
height: node.prop("offsetHeight")
};
o.right = o.left + o.width;
o.bottom = o.top + o.height;
return o;
},
getScroll: function(){
var o = {
top : $(win).scrollTop(),
left : $(win).scrollLeft(),
height : win.innerHeight || doc.documentElement.clientHeight,
width : win.innerWidth || doc.documentElement.clientWidth
};
o.right = o.left + o.width;
o.bottom = o.top + o.height;
return o;
}
};
$.fn.peekaboo = function(options){
var my = $.peekaboo;
options = $.extend({}, my.defaults, options);
this.each(function(){
var node = $(this);
node.data(my.DATA_MODE_FULL, options.full);
if(! node.data(my.DATA_INIT)){
node.data(my.DATA_SHOW, null);
node.on(my.EVENT_SHOW, options.show);
node.on(my.EVENT_HIDE, options.hide);
$(win).on("scroll", $.proxy(my.onScroll, my, this));
my.onScroll(this);
node.data(my.DATA_INIT, true);
}
});
return this;
};
}(jQuery, window, document));
(function($, win, doc){
/**
* Peekaboo
* --------
* @class
*/
$.Peekaboo = function(el, options){
this.initialize(el, options);
};
$.extend($.Peekaboo.prototype, {
/**
* Constants:
* - EVENT_SHOW = Event name when element get shown
* - EVENT_HIDE = Event name when element get hidden
*/
EVENT_SHOW: "peekabooShow",
EVENT_HIDE: "peekabooHide",
/**
* Attributes:
* - full:Boolean = "full" mode or not
* - show:Function = Handler for EVENT_SHOW
* - hide:Function = Handler for EVENT_HIDE
*/
defaults: {
full: true,
show: null,
hide: null
},
attrs: {},
/**
* Properties:
* - el:HTMLElement = Target element
* - $el:jQueryObject = $() for `el`
* - visible:Boolean = Element is visible or not
*/
el: null,
$el: null,
visible: null,
/**
* Constructor
* Set element, configure options, add event handler
* @constructor
* @param HTMLElement el
* @param Object options
*/
initialize: function(el, options){
this.el = el;
this.$el = $(el);
this.attrs = $.extend({}, this.defaults, options);
$(win).on("scroll", $.proxy(this.onScroll, this));
this.$el.on(this.EVENT_SHOW, this.attrs.show);
this.$el.on(this.EVENT_HIDE, this.attrs.hide);
this.onScroll();
},
/**
* Update options
* @param Object options
*/
config: function(options){
$.extend(this.attrs, options);
},
/**
* Handler for scroll event on document
* If the visible status of the element is changed,
* trigger EVENT_SHOW/EVENT_HIDE on the element
*/
onScroll: function(){
var v = this.getVisible();
if(this.visible !== v){
this.$el.trigger(v ? this.EVENT_SHOW : this.EVENT_HIDE);
this.visible = v;
}
},
/**
* Get whether the element is visible in client window
* If "full" mode, element is regarded as visible when all contents is displayed
* If not, triggered when part of the element is displayed
* @return Boolean
*/
getVisible: function(){
var scroll, offset, visible;
scroll = $.Peekaboo.getScroll();
offset = $.Peekaboo.getOffset(this.el);
if(this.attrs.full){
visible = offset.top >= scroll.top
&& offset.left >= scroll.left
&& offset.right <= scroll.right
&& offset.bottom <= scroll.bottom;
} else {
visible = offset.bottom >= scroll.top
&& offset.right >= scroll.left
&& offset.left <= scroll.right
&& offset.top <= scroll.bottom;
}
return visible;
}
});
/**
* Helper: Get offset object
* which contains top, left, right, bottom, width, height
*/
$.Peekaboo.getOffset = function(el){
var node, offset, o;
node = $(el);
offset = node.offset();
o = {
top: offset.top,
left: offset.left,
width: node.prop("offsetWidth"),
height: node.prop("offsetHeight")
};
o.right = o.left + o.width;
o.bottom = o.top + o.height;
return o;
};
/**
* Helper: Get scroll object
* which contains top, left, right, bottom, width, height
*/
$.Peekaboo.getScroll = function(){
var o = {
top : $(win).scrollTop(),
left : $(win).scrollLeft(),
height : win.innerHeight || doc.documentElement.clientHeight,
width : win.innerWidth || doc.documentElement.clientWidth
};
o.right = o.left + o.width;
o.bottom = o.top + o.height;
return o;
};
/**
* Interface for jQuery
*/
$.fn.peekaboo = function(options){
this.each(function(){
var node, inst;
node = $(this);
inst = node.data("peekaboo");
if(! inst){
inst = new $.Peekaboo(this, options);
node.data("peekaboo", inst);
} else {
inst.config(options);
}
});
return this;
};
}(jQuery, window, document));
/* Example:
var $el = $(element);
$el.peekaboo({
full: true, // with "full" mode or not
show: function(){
// do something when it get shown in client window
},
hide: function(){
// do something when it get hidden
}
});
// after initializing, some events get available
$el.on("peekabooShow", function(){
// same as "show" in options
});
$el.on("peekabooHide", function(){
// same as "hide" in options
});
*/
@mach3
Copy link
Author

mach3 commented Aug 13, 2013

書き方を変えてみた。(02)
実質20行くらい減った。コストも低くなったかしら…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment