javascript - What's best way to run same function on multiple elements only when they're inside viewport? -


i have 3 elements background images want scale x 1. want begin when top of element inside viewport (this may vary little).

i have achieved effect long way:

function animatepanelbackgrounds() {      var $toolsbg   = $('#js-tools-bg'),          $dennysbg  = $('#js-dennys-bg'),          $verizonbg = $('#js-verizon-bg'),          $llbeanbg  = $('#js-llbean-bg');         var dennystop = math.floor( $("#js-dennys").offset().top );      var dennysgo = dennystop - window.innerheight;         var llbeantop = math.floor( $("#js-llbean").offset().top );      var llbeango = llbeantop - window.innerheight;         var verizontop = math.floor( $("#js-verizon").offset().top );      var verizongo = verizontop - window.innerheight;         var toolstop = math.floor($toolsbg.offset().top);      var toolsgo = 0;         var ratio, $that;         if ( thiswindows.offsety() >= toolsgo ) {          ratio = toolstop/(thiswindows.offsety()*10);          $that = $toolsbg;             $that.css({              "transform": "scale(" + (1.0 + thiswindows.offsety()*.0002) + ")",              "-webkit-transform": "scale(" + (1.0 + thiswindows.offsety()*.0002) + ")",              "-moz-transform": "scale(" + (1.0 + thiswindows.offsety()*.0002) + ")"          })      }         if ( thiswindows.offsety() >= dennysgo ) {          ratio = dennystop/thiswindows.offsety()*.8;          $that = $dennysbg;             if ( ratio <= 1 ) {              $that.css({                  "transform": "scale(1)",                  "-webkit-transform": "scale(1)",                  "-moz-transform": "scale(1)"              })          } else {              $that.css({                  "transform": "scale(" + ratio + ")",                  "-webkit-transform": "scale(" + ratio + ")",                  "-moz-transform": "scale(" + ratio + ")"              })          }      }         if ( thiswindows.offsety() >= verizongo ) {          ratio = verizontop/thiswindows.offsety()*.8;          $that = $verizonbg;             if ( ratio <= 1 ) {              $that.css({                  "transform": "scale(1)",                  "-webkit-transform": "scale(1)",                  "-moz-transform": "scale(1)"              })          } else {              $that.css({                  "transform": "scale(" + ratio + ")",                  "-webkit-transform": "scale(" + ratio + ")",                  "-moz-transform": "scale(" + ratio + ")"              })          }      }         if ( thiswindows.offsety() >= llbeango ) {          ratio = llbeantop/thiswindows.offsety()*.8;          $that = $llbeanbg;             if ( ratio <= 1 ) {              $that.css({                  "transform": "scale(1)",                  "-webkit-transform": "scale(1)",                  "-moz-transform": "scale(1)"              })          } else {              $that.css({                  "transform": "scale(" + ratio + ")",                  "-webkit-transform": "scale(" + ratio + ")",                  "-moz-transform": "scale(" + ratio + ")"              })          }      }  }    $(window).on('scroll', function() {    animatepanelbackgrounds();  }

i have achieved function take couple simple parameters:

function scalebackground(element, multiplier) {         var $el           = $(element),          eltop         = math.floor( $el.offset().top),          startposition = eltop - window.innerheight;         $win.on('scroll', function() {             if(thiswindows.offsety() >= startposition) {                 var ratio = eltop/thiswindows.offsety()*multiplier;                 if ( ratio <= 1 ) {                  $el.css({                      "transform": "scale(1)",                      "-webkit-transform": "scale(1)",                      "-moz-transform": "scale(1)"                  })              } else {                  $el.css({                      "transform": "scale(" + ratio + ")",                      "-webkit-transform": "scale(" + ratio + ")",                      "-moz-transform": "scale(" + ratio + ")"                  })              }          }      })     }     scalebackground('#js-dennys-bg', '.8');  scalebackground('#js-llbean-bg', '.8');  scalebackground('#js-verizon-bg', '.8');

i feel should handled in loop of sorts, haven't had luck. here's basic attempt, i've tried tweaking little things in along way 0 success:

var panels = $('.panel__bg');     ( = 0; < panels.length; i++ ) {      var $that = $(panels[i]),          begin = $that.offset().top;         if ( begin <= window.scrolly ) {          var ratio = begin/(window.scrolly * 10);             if ( ratio <= 1 ) {              $that.css({                  "transform": "scale(1)",                  "-webkit-transform": "scale(1)",                  "-moz-transform": "scale(1)"              })          } else {              $that.css({                  "transform": "scale(" + ratio + ")",                  "-webkit-transform": "scale(" + ratio + ")",                  "-moz-transform": "scale(" + ratio + ")"              })          }      }  }

my question, finally, simply: best way this. "best way", extremely concerned performance , secondly concerned readability/fewest lines of code.

here critique code. it's untested, addresses of concerns.

// .each easier understand, , cleaner looking loop $('.panel__bg').each(function(i, panel){      // name makes more sense "$that", e.g. "$panel"     var $panel = $(panel),          begin = $panel.offset().top;      if ( begin <= window.scrolly ) {         // caps ratio=1. no need if/else block         var ratio = math.min(1, begin/(window.scrolly * 10));           // on so, helps show code relevant issue         $panel.css({"transform": "scale(" + ratio + ")" });     } }); 

i assume code being run every time scroll event fired. might run trouble on ios because js execution blocked during scroll. see issue.


Popular posts from this blog