【问题标题】:Having difficuly using a switch statement with classess and for loops在使用带有类和 for 循环的 switch 语句时遇到困难
【发布时间】:2019-11-30 01:06:38
【问题描述】:

我正在尝试创建类似于 pintrest 的照片视图显示,但有一个首选项 checkbox,您可以在其中选择您看到的图像类型。

我遇到的问题是其中一些图像属于多个类别,例如,城市中可能有驾驶镜头,所以我希望该特定图像显示城市 checkbox 或驾驶图像checkbox 被点击。

目前我有这样的说法,例如,城市checkbox 被点击并变成unchecked,然后所有带有城市class 的图像都会得到一个displayNone 的类,这很明显。但我想这样做,如果它还有另一个class,目前是checked,那么它不会得到displayNone的class,只有当那个特定图像的所有类都是unchecked时,那个图像才会得到displayNone 的class

我知道 switch 语句非常适合这种情况,但我似乎无法确切地弄清楚我将如何实现它。

  HTML

  <!--PREFERENCE CHECKBOX-->
                      <div class = "preferanceCheckbox">
                          <form class ="formBox">
                              <div>
                            <input type="checkbox" class = "cBDrivingShot">
                              Driving Shots <br>
                              </div>
                            <input type="checkbox" class = "cBCyberPunkShot">
                              Cyberpunk <br>
                            <input type="checkbox" class = "cBcityRelated">
                              city related <br>
                           </form>
                       </div>


      <div class ="photoSectionAlignment pintrestView imgZ displayNone">

 <!-- CYBERPUNK SHOTS -->
          <img src="cyberPunkOne.jpg" class = "pImgCyberPunk pImgDrivingShot displayNone">                                     

          <img src="cyberPunkTwo.jpg" class = "pImgCyberPunk pImgCity displayNone">

          <img src="cyberPunkTwo.jpg" class = "pImgCyberPunk pImgtext displayNone">

 <!-- DRIVING SHOTS -->
         <img src="drivingShotOne" class = "pImgDrivingShot pImgCity displayNone">

         <img src="drivingShotTwo" class = "pImgDrivingShot pImgCity displayNone">

         <img src="drivingShotThree" class = "pImgDrivingShot pImgCyberPunk displayNone">

 <!-- CITY SHOTS -->
         <img src="cityShotOne" class = "pImg pImgCity displayNone">
    </div>


 CSS

 img {
 width: 200px;
 }

 .displayNone {
 display: none;
 }


  JAVASCRIPT  

  //GLOBAL VARIABLES
  //....................................................................

  var pintrestView = document.querySelector(".pintrestView");

  var dnPintrest = pintrestView.classList.contains("displayNone");


  // GLOBAL PREFERANCES CODE
  //..................................................................
  var drivingCheckBox = document.querySelector(".cBDrivingShot");
  var cyberPunkCheckBox = document.querySelector(".cBCyberPunkShot");
  var cityCheckBox = document.querySelector(".cBcityRelated");

  //PREFERANCES CODE
  //..................................................................

  // pintrest class variables
  var pImgDrivingShot = document.querySelectorAll(".pImgDrivingShot");
  var pImgCyberPunk = document.querySelectorAll(".pImgCyberPunk");
  var pImgCity = document.querySelectorAll(".pImgCity");

  //DRIVING SHOT FUNCTIONALITY
  drivingCheckBox.addEventListener("click",drivingShotImgFunctionPintrest);

 function drivingShotImgFunctionPintrest(){

     if (drivingCheckBox.checked === true){
         for (var i = 0; i < pImgDrivingShot.length; i++){
             if (pImgDrivingShot[i].classList.contains("displayNone")) {
                 pImgDrivingShot[i].classList.remove("displayNone");
             }
         }
     }else{
         if (drivingCheckBox.checked === false) {
             for (var i = 0; i < pImgDrivingShot.length; i++){ 
                 if (pImgDrivingShot[i].classList.contains("displayNone") === false) {
                     pImgDrivingShot[i].classList.add("displayNone");
                 }

             }
         }  
     }
 }

  //CYBERPUNK FUNCTIONALITY
  cyberPunkCheckBox.addEventListener("click",cyberPunkImgFunctionPintrest);

  function cyberPunkImgFunctionPintrest(){

     if (cyberPunkCheckBox.checked === true){
         for (var i = 0; i < pImgCyberPunk.length; i++){
             if (pImgCyberPunk[i].classList.contains("displayNone")) {
                 pImgCyberPunk[i].classList.remove("displayNone");
             }
         }
     }else{
         if (cyberPunkCheckBox.checked === false) {
             for (var i = 0; i < pImgCyberPunk.length; i++){ 
                 if (pImgCyberPunk[i].classList.contains("displayNone") === false) {
                     pImgCyberPunk[i].classList.add("displayNone");
                 }

             }
         }  
     }
 }

  //CITY FUNCTIONALITY
  cityCheckBox.addEventListener("click",cityImgFunctionPintrest);

  function cityImgFunctionPintrest(){

      if (cityCheckBox.checked === true){
          for (var i = 0; i < pImgCity.length; i++){
              if (pImgCity[i].classList.contains("displayNone")) {
                  pImgCity[i].classList.remove("displayNone");
              }
          }
      }else{
          if (cityCheckBox.checked === false) {
              for (var i = 0; i < pImgCity.length; i++){ 
                  if (pImgCity[i].classList.contains("displayNone") === false) {
                      pImgCity[i].classList.add("displayNone");
                  }

              }
          } 
      }
  }

【问题讨论】:

    标签: javascript loops class switch-statement


    【解决方案1】:

    这是另一种使用 CSS 规则和一个事件侦听器的方法:

    <!-- Place this inside your <head> -->
    <style id="preferences"></style>
    <!--PREFERENCE CHECKBOX-->
    <div class = "preferanceCheckbox">
      <form class ="formBox">
          <input id="drive" type="checkbox" value=".pImgDrivingShot">
          <label for="drive">Driving Shots</label><br>
          <input id="cyber" type="checkbox" value=".pImgCyberPunk">
          <label for="cyber">Cyberpunk</label><br>
          <input id="city" type="checkbox" value=".pImgCity">
          <label for="city">City Related</label>
      </form>
    </div>
    
    <div class ="photoSectionAlignment pintrestView imgZ">
      <!-- CYBERPUNK SHOTS -->
      <img src="https://picsum.photos/id/1018/100/50" class = "pImgCyberPunk pImgDrivingShot displayNone">     <img src="https://picsum.photos/id/1022/100/50" class = "pImgCyberPunk pImgCity displayNone">
      <img src="https://picsum.photos/id/1023/100/50" class = "pImgCyberPunk pImgtext displayNone">
      <!-- DRIVING SHOTS -->
      <img src="https://picsum.photos/id/1041/100/50" class = "pImgDrivingShot pImgCity displayNone">
      <img src="https://picsum.photos/id/1015/100/50" class = "pImgDrivingShot pImgCity displayNone">
      <img src="https://picsum.photos/id/1019/100/50" class = "pImgDrivingShot pImgCyberPunk displayNone">
      <!-- CITY SHOTS -->
      <img src="https://picsum.photos/id/1080/100/50" class = "pImg pImgCity displayNone">
    </div>
    
    
     .displayNone {
      display: none;
     }
    
    const selected = {};
    document.querySelector("form").addEventListener("click",(e)=>{
       if ( e.target.type === "checkbox" ){
         const cssClass = e.target.value;
         if (e.target.checked){
           selected[cssClass] = true;
         } else {
           delete selected[cssClass];
         };
         const cssRules = `${Object.keys(selected).join(",")}{ display: block !important; }`;
         document.querySelector("style#preferences").textContent = cssRules;
       }
    });
    

    Codepen

    代码更容易扩展:您只需在表单中为每个新的图像类别添加一对标签/输入:复选框(2 行)。

          <input id="summer" type="checkbox" value=".pImgSummer">
          <label for="summer">Summer Related</label>
    

    【讨论】:

    • 这通过您的 codepen 示例非常有效,但是无论出于何种原因,当我将它复制到我的项目的代码中时它不起作用,我也已经阅读了所有内容 3 次 :( 这绝对是与您编写的公式完全相同。知道为什么它不起作用吗?
    • 是的,我最终得到了它@KostaX,对于选择表单框的 querySelector,我必须使用完美工作的 form.formbox。我现在唯一的问题是我实际上有几种不同的查看模式,并且希望将相同的逻辑应用于每种模式,但它仅适用于 pintrest 视图.. idk 也许我会再发一篇文章,让你知道我什么时候做什么?
    • 当然。只要确保您自己尝试解决它,然后将其发布在 S.O.只有当你觉得卡住了。 @JoshMcIntosh
    【解决方案2】:

    第一次使用更改事件而不是单击复选框。

    JS

    var pintrestView = document.querySelector(".pintrestView");
    
    var dnPintrest = pintrestView.classList.contains("displayNone");
    
    
    // GLOBAL PREFERANCES CODE
    //..................................................................
    var drivingCheckBox = document.querySelector(".cBDrivingShot");
    var cyberPunkCheckBox = document.querySelector(".cBCyberPunkShot");
    var cityCheckBox = document.querySelector(".cBcityRelated");
    
    //PREFERANCES CODE
    //..................................................................
    
    // pintrest class variables
    var pImgDrivingShot = document.querySelectorAll(".pImgDrivingShot");
    var pImgCyberPunk = document.querySelectorAll(".pImgCyberPunk");
    var pImgCity = document.querySelectorAll(".pImgCity");
    
    //DRIVING SHOT FUNCTIONALITY
    drivingCheckBox.addEventListener("change", drivingShotImgFunctionPintrest);
    
    function drivingShotImgFunctionPintrest() {
        for (var i = 0; i < pImgDrivingShot.length; i++) {
            if (this.checked) {
                pImgDrivingShot[i].classList.remove('displayNone')
    
            } else {
                pImgDrivingShot[i].classList.add('displayNone');
    
            }
        }
    }
    
    //CYBERPUNK FUNCTIONALITY
    cyberPunkCheckBox.addEventListener("change", cyberPunkImgFunctionPintrest);
    
    function cyberPunkImgFunctionPintrest() {
        for (var i = 0; i < pImgCyberPunk.length; i++) {
            if (this.checked) {
                pImgCyberPunk[i].classList.remove("displayNone")
    
    
            } else {
                pImgCyberPunk[i].classList.add("displayNone");
            }
        }
    
    }
    
    //CITY FUNCTIONALITY
    cityCheckBox.addEventListener("change", cityImgFunctionPintrest);
    
    function cityImgFunctionPintrest() {
    
    
        for (var i = 0; i < pImgCity.length; i++) {
            if (!this.checked) {
                pImgCity[i].classList.remove("displayNone");
            } else {
                pImgCity[i].classList.add("displayNone");
            }
        }
    
    }
    

    HTML:为你的父 div 移除不显示

                   <div class = "preferanceCheckbox">
                              <form class ="formBox">
                                  <div>
                                <input type="checkbox" class = "cBDrivingShot">
                                  Driving Shots <br>
                                  </div>
                                <input type="checkbox" class = "cBCyberPunkShot">
                                  Cyberpunk <br>
                                <input type="checkbox" class = "cBcityRelated">
                                  city related <br>
                               </form>
                           </div>
    
    
          <div class ="photoSectionAlignment pintrestView imgZ">
    
     <!-- CYBERPUNK SHOTS -->
              <img src="cyberPunkOne.jpg" class = "pImgCyberPunk pImgDrivingShot displayNone">                                     
    
              <img src="cyberPunkTwo.jpg" class = "pImgCyberPunk pImgCity displayNone">
    
              <img src="cyberPunkTwo.jpg" class = "pImgCyberPunk pImgtext displayNone">
    
     <!-- DRIVING SHOTS -->
             <img src="drivingShotOne" class = "pImgDrivingShot pImgCity displayNone">
    
             <img src="drivingShotTwo" class = "pImgDrivingShot pImgCity displayNone">
    
             <img src="drivingShotThree" class = "pImgDrivingShot pImgCyberPunk displayNone">
    
     <!-- CITY SHOTS -->
             <img src="cityShotOne" class = "pImg pImgCity displayNone">
        </div>
    

    【讨论】:

      【解决方案3】:

      我会尝试减少 Javascript 代码中的循环数。我认为您确实想要相同的逻辑,但是样式中有一些变量。如果您可以识别变量,那么循环可以在一个地方处理。以下是我解决问题的方法:

      // GLOBAL PREFERENCES CODE
      //..................................................................
      var drivingCheckBox = document.querySelector(".cBDrivingShot");
      var cyberPunkCheckBox = document.querySelector(".cBCyberPunkShot");
      var cityCheckBox = document.querySelector(".cBcityRelated");
      
      drivingCheckBox.addEventListener("click", updateFromCheckbox);
      cyberPunkCheckBox.addEventListener("click", updateFromCheckbox);
      cityCheckBox.addEventListener("click", updateFromCheckbox);
      function updateFromCheckbox(evt) {
          console.log('In updateFromCheckbox');
          var selector = "";  // The class that corresponds to the current checkbox
          var otherSelectors = [];    // Array of classes that correspond to the OTHER checkboxes
          var otherCheckboxes = [];   // The boolean settings of the OTHER checkboxes
          if (evt.currentTarget === drivingCheckBox) {
              selector = "pImgDrivingShot";
              otherSelectors = ["pImgCyberPunk", "pImgCity"];
              otherCheckboxes = [cyberPunkCheckBox.checked, cityCheckBox.checked];
          } else if (evt.currentTarget === cyberPunkCheckBox) {
              selector = "pImgCyberPunk";
              otherSelectors = ["pImgDrivingShot", "pImgCity"];
              otherCheckboxes = [drivingCheckBox.checked, cityCheckBox.checked];
          } else if (evt.currentTarget === cityCheckBox) {
              selector = "pImgCity";
              otherSelectors = ["pImgDrivingShot", "pImgCyberPunk"];
              otherCheckboxes = [drivingCheckBox.checked, cyberPunkCheckBox.checked];
          }
      
          // Safety check
          if (otherSelectors.length != otherCheckboxes.length) {
              console.log("otherSelectors AND otherCheckboxes ARE PARALLEL ARRAYS AND SHOULD BE THE SAME LENGTH!");
          }
      
          var images = document.querySelectorAll("img");
          for (var i = 0; i < images.length; i++) {
              var image = images[i];
              var isDisplayed = false;
              if (image.classList.contains(selector) && evt.currentTarget.checked) {
                  isDisplayed = true;
              } else {
                  for (var j = 0; j < otherSelectors.length; j++) {
                      var otherSelector = otherSelectors[j];
                      var otherCheckboxIsChecked = otherCheckboxes[j];
                      if (image.classList.contains(otherSelector) && otherCheckboxIsChecked) {
                          isDisplayed = true;
                          break;
                      }
                  }
              }
              if (isDisplayed) {
                  image.classList.remove("displayNone");
              } else {
                  image.classList.add("displayNone");
              }
              console.log('Got one ', image.src, 'isDisplayed = ', isDisplayed, 'classList = ', image.classList);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-16
        • 1970-01-01
        • 2018-08-05
        • 1970-01-01
        相关资源
        最近更新 更多