【问题标题】:How to condense JavaScript Using Loops如何使用循环压缩 JavaScript
【发布时间】:2020-12-02 18:45:43
【问题描述】:

我有以下代码可以正常工作,以响应延迟加载页面上多个 div 的背景图像:

// get frames
// REFACTOR LIST:
var frame1 = document.getElementById('frame1');
var frame2 = document.getElementById('frame2');
var frame3 = document.getElementById('frame3');
var frame4 = document.getElementById('frame4');
var frame5 = document.getElementById('frame5');

// create Lazy loader
var myLazyLoad = new LazyLoad({
  elements_selector: ".lazy"
});

// load images responsively
function loadImgs() {
  
    console.log('Loading images...');
  
    if(window.matchMedia("only screen and (max-width:700px)").matches) {
    // viewport is less than or equal to 700 pixels wide
    // REFACTOR LIST:
    var src1 = frame1.getAttribute('data-src-small');
    var src2 = frame2.getAttribute('data-src-small');
    var src3 = frame3.getAttribute('data-src-small');
    var src4 = frame4.getAttribute('data-src-small');
    var src5 = frame5.getAttribute('data-src-small');
  } else {
    // viewport is greater than 700 pixels wide
    // REFACTOR LIST:
    var src1 = frame1.getAttribute('data-src-large');
    var src2 = frame2.getAttribute('data-src-large');
    var src3 = frame3.getAttribute('data-src-large');
    var src4 = frame4.getAttribute('data-src-large');
    var src5 = frame5.getAttribute('data-src-large');
  } 

  // set data-src for lazy loader
  // REFACTOR LIST:
  frame1.setAttribute('data-src', src1);
  frame2.setAttribute('data-src', src2);
  frame3.setAttribute('data-src', src3);
  frame4.setAttribute('data-src', src4);
  frame5.setAttribute('data-src', src5);
    
  // tell lazy loader that the data should be re-processed
  // REFACTOR LIST:
  frame1.removeAttribute('data-was-processed');
  frame2.removeAttribute('data-was-processed');
  frame3.removeAttribute('data-was-processed');
  frame4.removeAttribute('data-was-processed');
  frame5.removeAttribute('data-was-processed'); 

  // tell lazy loader to update
  myLazyLoad.update();
}

// load images initially
loadImgs();

// reload images when window is resized across the 700px breakpoint
var lastWindowSize = window.innerWidth;
window.onresize = function(event) {
    var currentWindowSize = window.innerWidth; 
    if((lastWindowSize <= 700 && currentWindowSize > 700) || (lastWindowSize > 700 && currentWindowSize <= 700)) {
    loadImgs();
  }
  lastWindowSize = currentWindowSize;
};
html {
  box-sizing: border-box;
}

*, *::before, *::after {
  box-sizing: inherit;
  &:focus {
    outline: none;
  }
}

* {
  font-family: monaco, courier;
}

body {
  margin: 0;
  padding: 0;
}

.wrapper {
  width: 100%;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center ;
  background: #ddd;
}

p {
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
  padding: 8px;
  color: darkslategray;
  background: gold;
}

.frame {
  width: 80vw;
  height: 200px;
  margin: 0 0 1rem 0;
  padding: 0;
  position: relative;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border: 2px solid gold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-lazyload/8.7.1/lazyload.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<!-- https://stackoverflow.com/questions/50431531/lazylaoding-css-background-not-html-img-tags -->

<main class="wrapper">

  <a href="#">
    <div id="frame1" class="frame lazy" 
      data-src-small="https://source.unsplash.com/random/400x200?sig=1"
      data-src-large="https://source.unsplash.com/random/1200x600?sig=1">
      <p>1</p>
    </div>
  </a>

  <a href="#">
    <div id="frame2" class="frame lazy" 
      data-src-small="https://source.unsplash.com/random/400x200?sig=2"
      data-src-large="https://source.unsplash.com/random/1200x600?sig=2">
      <p>2</p>
    </div>
  </a>

  <a href="#">
    <div id="frame3" class="frame lazy" 
      data-src-small="https://source.unsplash.com/random/400x200?sig=3"
      data-src-large="https://source.unsplash.com/random/1200x600?sig=3">
      <p>3</p>
    </div>
  </a>

  <a href="#">
    <div id="frame4" class="frame lazy" 
      data-src-small="https://source.unsplash.com/random/400x200?sig=4"
      data-src-large="https://source.unsplash.com/random/1200x600?sig=4">
      <p>4</p>
    </div>
  </a>

  <a href="#">
    <div id="frame5" class="frame lazy" 
      data-src-small="https://source.unsplash.com/random/400x200?sig=5"
      data-src-large="https://source.unsplash.com/random/1200x600?sig=5">
      <p>5</p>
    </div>
  </a>

</main>

CodePen here

但我想重构代码以使其干燥。我在想 for 循环可用于替换 REFACTOR LIST: 注释下的 5 个列表中的每一个。我的目标是为任何未知数量的具有frame 类的 div 启用代码。

首先,例如,我尝试使用以下循环重构开头的变量声明:

var FramesQuantity = document.getElementsByClassName("frame").length
var frameVariables = [];

function createframeVariables() {
  for (var i = 0; i <= FramesQuantity; ++i) {
    var frameIndex = 'frame' + i;
    console.log("frameIndex: " + frameIndex);
    frameVariables[i] = document.getElementById(frameIndex);
  }
  return frameVariables;
}

createframeVariables();

console.log("frameVariables[0]: " + frameVariables[0]);

但是第二个控制台日志返回null,我不确定这是否是正确的方向。

有什么想法吗?

【问题讨论】:

  • 您已经在document.getElementsByClassName("frame"); 中找到了您需要的元素列表,只需使用它...顺便说一句,您应该查看MDN's article on using matchMedia。您可以在matchMedia 的结果中添加事件侦听器,以便在触发媒体查询时得到通知。我希望大部分这些都可以单独在 CSS 中处理......
  • 想想 document.querySelectorAll('div[data-src-small]') 就像document.querySelectorAll('div[data-src-small]').forEach(div=&gt;{ console.log(div.dataset.srcSmall)} )

标签: javascript for-loop dry


【解决方案1】:

正如建议的那样,我能够重构代码,通过使用 .forEach.querySelectorAll 将其干燥,这样就无需设置变量:

// for loop demo
document.querySelectorAll('.frame[data-src-small]').forEach( (frame, index) => {
  console.log( "index: " + index);
  console.log( "frame.dataset.srcSmall: " + frame.dataset.srcSmall);
  console.log( "frame.dataset.srcLarge: " + frame.dataset.srcLarge);
})

// create Lazy loader
var myLazyLoad = new LazyLoad({
  elements_selector: ".lazy"
});

// load images responsively
function loadImgs(context) {

  console.log('Loading images ' + context);
  
  if(window.matchMedia("only screen and (max-width:700px)").matches) {
    // viewport is less than or equal to 700 pixels wide
    document.querySelectorAll('.frame[data-src-small]').forEach( (frame, index) => {
      var srcSmall = frame.dataset.srcSmall;
      // set data-src for lazy loader
      frame.setAttribute('data-src', srcSmall);
      // tell lazy loader that the data should be re-processed
      frame.removeAttribute('data-was-processed');
    })
  } else {
    document.querySelectorAll('.frame[data-src-small]').forEach( (frame, index) => {
      // viewport is greater than 700 pixels wide
      var srcLarge = frame.dataset.srcLarge;
       // set data-src for lazy loader
      frame.setAttribute('data-src', srcLarge);
      // tell lazy loader that the data should be re-processed
      frame.removeAttribute('data-was-processed');
    })
  } 
  
  // tell lazy loader to update
  myLazyLoad.update();
}

// load images initially
loadImgs("initially");

// reload images when window is resized across the 700px breakpoint
var lastWindowSize = window.innerWidth;
window.onresize = function(event) {
  var currentWindowSize = window.innerWidth; 
  if((lastWindowSize <= 700 && currentWindowSize > 700) || (lastWindowSize > 700 && currentWindowSize <= 700)) {
    loadImgs("on resize across breakpoint");
  }
  lastWindowSize = currentWindowSize;
};

原始 CodePen here 的分叉更新版本。

【讨论】:

    猜你喜欢
    • 2021-07-31
    • 2017-03-01
    • 2022-01-12
    • 2012-01-26
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    相关资源
    最近更新 更多