【问题标题】:change class in javascript by d3 select and filter通过 d3 选择和过滤更改 javascript 中的类
【发布时间】:2018-08-28 10:53:01
【问题描述】:

我有一个类似下面的函数。

首先,我将所有课程更改为“徽章徽章辅助”。 然后,检查 span 中的文本。如果它是“正确的”并单击,则更改为“badge badge-primary”。 否则,它是“错误”并单击,更改为“class”,“badge badge-danger”。

我可以让我的代码更简洁正确吗?

function updateOrderType(ansType) {
    lastAnsType = ansType;
    var ansBadge = d3.select("#anstype").selectAll("span.badge");
    ansBadge.attr("class", "badge badge-secondary");
    ansBadge.filter(function() {
        if (d3.select(this).text() == ansType) {
            return d3.select(this).text() == "right";
        }
    }).attr("class", "badge badge-primary");
    ansBadge.filter(function() { 
        if (d3.select(this).text() == ansType) {
            return d3.select(this).text() == "wrong";
        }
    }).attr("class", "badge badge-danger");
}

【问题讨论】:

    标签: javascript if-statement d3.js filter bootstrap-4


    【解决方案1】:

    我认为您的代码有点难以理解,但根据您在介绍中编写的逻辑,我建议使用以下代码:

    function updateOrderType(ansType) {
        var ansBadge = d3.select("#anstype").selectAll("span.badge");
    
        ansBadge.forEach(function() {
            var oElement = d3.select(this);
    
            if (/**CLICKED**/) {
                var sText = oElement.text();
    
                if(sText === "right") {
                    oElement.setAttribute("class", "badge badge-primary");
                } else if(sText === "wrong") {
                    oElement.setAttribute("class", "badge badge-danger");
                } else {
                    oElement.setAttribute("class", "badge badge-secondary");
                }
    
            } else {
                oElement.setAttribute("class", "badge badge-secondary");
            }
        }
    }
    

    您的代码几乎迭代了 ansBadge 数组 5 次,每轮评估 1 个 if 语句。我上面的建议迭代 1 次,顶部有 3 个 if。如果您检查元素是否被点击(在外部 if 中),您甚至可以改进这一点,因为这种情况更有可能发生。

    在这段代码中处理了四种类型的元素:

    • 点击和“右”> 主要
    • 点击&“错误”>危险
    • 点击任何文字> 次要
    • 没有点击任何文字> 次要

    【讨论】:

      【解决方案2】:

      georgina95 答案的简化

      function updateOrderType(ansType) {
          var ansBadge = d3.select("#anstype").selectAll("span.badge");
      
          ansBadge.forEach(function() {
              var oElement = d3.select(this);
              var newClass = "badge badge-secondary";
      
              if (/**CLICKED**/) {
                  var sText = oElement.text();
      
                  if(sText === "right") {
                      newClass = "badge badge-primary";
                  } else if(sText === "wrong") {
                      newClass = "badge badge-danger";
                  }
              }
              oElement.setAttribute("class", newClass);
          }
      }
      

      【讨论】:

      • forEach 中仅使用一行进一步简化为:d3.select(this).setAttribute("class", "badge badge-"+(/**CLICKED**/ ? d3.select(this).text() === 'right' ? "primary" : "danger" : "secondary"))。我是三元运算符的粉丝,所以发布了这个。 :)
      • @Shashank:使用多个? 确实需要() 来增加可读性并防止令人讨厌的错误,因为它是右关联的。
      • 是的@riov8。同意。我确实经常使用它,是的,我确实使用()
      【解决方案3】:

      感谢您的所有帮助。 首先,我不能将forEach 与 d3.select (v4) 一起使用。这是一个不使用attr 而是使用setAttribute 的对象。所以我必须更改我的代码:

      function updateOrderType(ansType) {
          d3.select("#ordertype").selectAll("span").each(function() {
              var badgeText = this.textContent;
              if(ansType === badgeText) {
                      if(ansType === "right") {
                          this.setAttribute("class", "badge badge-primary");
                      } else if (ansType === "wrong") {
                          this.setAttribute("class", "badge badge-danger");
                      } else {
                          this.setAttribute("class", "badge badge-secondary");
                      }
              } else {
                      this.setAttribute("class", "badge badge-secondary");
              } 
          });
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多