////////////////////////////////////////////////////////////////////// // CInView function CInView(){ // elements let el_control; // parameters let callback; // variables let b_run; // jQuery.offset function jqOffset(el){ var rect=el.getBoundingClientRect(); var el_body=document.documentElement; return { x:rect.left+el_body.scrollLeft, y:rect.top+el_body.scrollTop }; }; function getElementSize(el){ const cs=window.getComputedStyle(el); return { w:parseInt(cs.getPropertyValue("width")), h:parseInt(cs.getPropertyValue("height")) }; }; function getElementRect(el){ const pos=jqOffset(el); const size=getElementSize(el); return{ top:pos.y, bottom:pos.y+size.h, left:pos.x, right:pos.x+size.w }; }; function getViewPort(){ // scroll position var scrollpos={ top:document.documentElement.scrollTop, left:document.documentElement.scrollLeft }; // viewport var vp={}; vp.top=scrollpos.top; vp.bottom=vp.top+window.innerHeight; vp.left=scrollpos.left; vp.right=vp.left+window.innerWidth; // return return vp; }; function inZone(er,vp,hori,vert){ if(hori===undefined){hori=0;} if(vert===undefined){vert=0;} const center={ x:(er.left+er.right)/2, y:(er.top+er.bottom)/2 }; const ext_w=(vp.right-vp.left)*hori; const ext_h=(vp.bottom-vp.top)*vert; const zone={ top:vp.top+ext_h, bottom:vp.bottom-ext_h, left:vp.left+ext_w, right:vp.right-ext_w }; // is center of the element in strike zone? return( (center.y>=zone.top)&& (center.y<=zone.bottom)&& (center.x>=zone.left)&& (center.x<=zone.right) ); }; function action(){ document.removeEventListener("scroll",checkVisibility); if(callback){callback();} }; function checkVisibility(){ if(!b_run){ const er=getElementRect(el_control); const vp=getViewPort(); if(inZone(er,vp)){ b_run=true; action(); } } }; function run(px){ // elements el_control=px.el_control; // parameters callback=px.callback; // variables b_run=false; // set scroll event handler document.addEventListener("scroll",checkVisibility); // check visibility checkVisibility(); }; return{ run }; };