【问题标题】:Is there a more elegant solution than an if-statement with no else clause?有没有比没有 else 子句的 if 语句更优雅的解决方案?
【发布时间】:2011-02-05 21:39:37
【问题描述】:

在下面的代码中,如果Control(触发Toggle的第一个OL的元素)不是Visible,则应该设置Visible和所有其他Controls(Controls[i])所以是Hidden。

.js

function Toggle(Control){
    var Controls=document.getElementsByTagName("ol",document.getElementById("Quote_App"));
    var Control=Control.getElementsByTagName("ol")[0];
    if(Control.style.visibility!="visible"){
        for(var i=0;i<Controls.length;i++){
            if(Controls[i]!=Control){

                Reveal("hide",20,0.3,Controls[i]);

            }else{

                Reveal("show",20,0.3,Control);

            };
        };
    }else{

        Reveal("hide",20,0.3,Control);

    };
};

虽然函数 [Toggle] 工作正常,但它实际上将 Controls[i] 设置为 Hidden,即使它已经设置了。

这很容易通过添加If 语句来纠正,如下面的代码,肯定有更优雅的解决方案,也许是复杂的If 条件?

.js

function Toggle(Control){
    var Controls=document.getElementsByTagName("ol",document.getElementById("Quote_App"));
    var Control=Control.getElementsByTagName("ol")[0];
    if(Control.style.visibility!="visible"){
        for(var i=0;i<Controls.length;i++){
            if(Controls[i]!=Control){

if(Controls[i].style.visibility=="visible"){

                Reveal("hide",20,0.3,Controls[i]);

};

            }else{

                Reveal("show",20,0.3,Control);

            };
        };
    }else{

        Reveal("hide",20,0.3,Control);

    };
};

我们永远感谢您的帮助。

【问题讨论】:

  • 第 3 行的错误? Control.getElementsByTagName("ol")[0];应该是 Controls.getElementsByTagName("ol")[0]; ?
  • 没有错误。 Toggle 的参数 Control 是触发 Toggle 的元素。变量 Control 是自变量 Control 的第一个子 OL(自变量 Control 的选项)。

标签: javascript if-statement


【解决方案1】:

在丑陋的纯 javascript 代码世界中,您的解决方案很好。但只是因为你说“优雅”,我的回答是使用 jQuery。

我将使用基于行为的代码而不是基于事件的代码来编写它可能更接近实际情况,因此这与您的代码不完全匹配。但是,它看起来像:

$('#Quote_app ol').click(function() { 
  if ($(this).is(':visible')) {
    $(this).fadeOut();
  } else {
    $(this).fadeIn();
    $('ol', $(this).parent()).not(this).fadeOut();
  }
});

这会将点击事件附加到 ID=Quote_app 的某个东西下面的每个 ol 元素,如果它当前可见,则隐藏它,否则,显示它并隐藏所有其他 ol 元素。

【讨论】:

  • 一个库对于这个应用程序来说太过分了,尽管我知道它对某些人来说是强项。
  • 或者你喜欢的任何其他框架,因为有很多好的框架。
  • 如果你找到合适的函数来使用,jQuery 是完美的。它消除了混乱并为您提供(几乎)易于阅读的代码,因此您可以更好地遵循您的逻辑/想法。
  • 我在说交通过度杀伤力。它超过 20 KB,而我的整个应用程序到目前为止只有 2 KB,没有 miniforcation。这个应用程序是专门为网络托管公司设计的,所以网站需要快速加载。一个缓慢的网站会引起一个糟糕的印象,并且不会过多地谈论他们的服务(或服务器)。不过,这是针对不同地方的讨论。
  • -1 因为“优雅”是主观的,根据经验,没有唯一且唯一真正的答案。
【解决方案2】:
if(Controls[i]!=Control && Controls[i].style.visibility=="visible") {
    Reveal("hide",20,0.3,Controls[i]);
}

【讨论】:

  • 赞,你的代码很干净。不幸的是,这里看到的任何解决方案都需要将元素的样式设置为内联或通过 Javascript 从关闭开始工作,除非专门设置样式。style.visibility 将返回未定义。我需要查看 getComputedStyle 或在其他地方专门设置元素的可见性。
  • @Jay 刚刚检查了.style.visibility == '',最初的案例似乎适用于 Chrome、Safari 和 Firefox。没有测试过 IE,我也无权访问它。
【解决方案3】:

不确定您的代码中的含义。策略是先对所有项目执行默认操作,然后对选定项目执行特定操作。像这样的:

for(var i=0;i<Controls.length;i++){
     if(Controls[i].style.visibility=="visible"){

         Reveal("hide",20,0.3,Controls[i]);

     };
}
Reveal("show",20,0.3,Control);

【讨论】:

  • 我认为这只是个人风格,更重要的是,你认为是默认的。隐藏的元素多于要显示的单个元素,因此隐藏元素应该(在我看来)是默认设置。
【解决方案4】:
if( Controls[i] != Control ) {
  if( Controls[i].style.visibility == "visible" ){
    Reveal( "hide", 20, 0.3, Controls[i] );
  };
} else {
  Reveal( "show", 20, 0.3, Control );
};

可以改写为:

if ( Controls[i] == Control ) {
  Reveal( "show", 20, 0.3, Control );
} else if ( Controls[i].style.visibility == "visible" ) {
  Reveal( "hide", 20, 0.3, Controls[i] );
}

【讨论】:

    【解决方案5】:

    继续 jQuery 建议 -

    jQuery 通常有一个切换功能,在这种情况下它变得更有吸引力,因为它可以将你的代码减少到几行。目前还没有 toggleFade 功能,但可以轻松添加,引用 Karl Swedberg 的话:

    您可以像这样编写自定义动画:

      jQuery.fn.fadeToggle = function(speed, easing, callback) { 
        return this.animate({opacity: 'toggle'}, speed, easing, callback); 
      }; 
    

    然后,你可以这样做:

      $(".bio-toggler").click(function () { 
        $("#bio-form").fadeToggle();
      })
    

    ;

    【讨论】:

      【解决方案6】:

      假设您的 Reveal("hide", ...) 函数将可见性设置为隐藏,这将在您不必使用 getComputedStyle 的情况下工作。

      if(Controls [i] !== Control && Controls[i].style.visibility !== "hidden") {
          Reveal("hide", 20, 0.3, Controls[i]);
      }
      

      【讨论】:

      • 确实如此,但 Toggle 是由 Click 事件触发的,因此 Reveal 只会隐藏 Controls[i] 如果它首先可见。我现在在初始化期间将脚本设置为隐藏控件[i]。
      • 您能否接受我的回答,因为它以适用于所有浏览器的方式回答问题(IE 不支持getComputedStyle)?
      【解决方案7】:

      通过一点猴子补丁,您可以在不使用任何外部框架的情况下使其更简洁。我还冒昧地根据动画的顺序(如果有的话)不重要的假设重新调整了逻辑。

      if Control is hidden
          loop through Controls as C
              hide if C != Control
              show if C = Control
      else
          hide Control
      

      另一种解释这个算法的方法是 - 只要Controls 包含至少一个元素(不管是哪个元素),Control 的可见性就会被切换。并且所有(Controls minus Control) 都将被隐藏。所以我再次冒昧地假设在 Controls 中总会有一个控件,并且 Control 将始终被切换。

      这是它的猴子补丁++代码(也在jsfiddle上)。这消除了函数中的所有 if 和 else。

      Toggle 函数现在看起来像这样:

      function Toggle(Control) {
          var Controls = document.getElementsByTagName("ol" ..
          var Control = Control.getElementsByTagName("ol")[0];
      
          Control.toggle();
          Controls.filter(function(c) { 
              return c != Control && c.isVisible();
          }).hide();
      };
      

      这里是代码隐藏。对元素列表应用属性的 NodeList 和 Array:

      ​NodeList.prototype.forEach = function(f) {
          for(var i = 0; i <​ this.length; i++) {
              f.apply(null, [this[i]]);
          }
      };
      Array.prototype.forEach = NodeList.prototype.forEach;
      
      NodeList.prototype.filter = function(f) {
          var results = [];
          for(var i = 0; i < this.length; i++) {
              if(f.apply(null, [this[i]])) {
                  results.push(this[i]);
              }
          }
          return results;
      };
      Array.prototype.filter = NodeList.prototype.filter;  
      
      NodeList.prototype.hide = function() {
          this.forEach(function(e) {
              e.hide();
          });
      };
      Array.prototype.hide = NodeList.prototype.hide;
      
      NodeList.prototype.show = function() {
          this.forEach(function(e) {
              e.show();
          });
      };
      Array.prototype.show = NodeList.prototype.show;
      

      这些方法将属性应用于单个元素:

      Element.prototype.isVisible = function() {
          return this.style.visibility == 'visible' || this.style.visibility == '';
      };
      
      Element.prototype.show = function() {
          this.style.visibility = 'visible';
      };
      
      Element.prototype.hide = function() {
          this.style.visibility = 'hidden';
      };
      
      Element.prototype.toggle = function() {
          this.isVisible() ? this.hide() : this.show();
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-18
        • 2023-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多