【问题标题】:JavaScript refactoring - How can this code be refactored? [closed]JavaScript 重构——如何重构这段代码? [关闭]
【发布时间】:2011-06-10 08:49:06
【问题描述】:
<script type="text/javascript">
              var typeSort = document.getElementById('sortTypeUp').value;
              if(typeSort == '1'){
                 document.getElementById('bewertung').className='tab_subbox tab2 tabon';
                 document.getElementById('price').className='tab_subbox tab3';
                 document.getElementById('kategorie').className='tab_subbox tab4';
                 document.getElementById('distance').className='tab_subbox tab5';
                 document.getElementById('bypois').className='tab_subbox tab6';
                 document.getElementById('opodoTriangle').style.display='block';
                 document.getElementById('priceTriangle').style.display='none';
                 document.getElementById('reviewTriangle').style.display='none';
                 document.getElementById('distanceTriangle').style.display='none';
                 document.getElementById('bypoisTriangle').style.display='none';
              }
              else if(typeSort == '2'){
                 document.getElementById('bewertung').className='tab_subbox tab2';
                 document.getElementById('price').className='tab_subbox tab3 tabon';
                 document.getElementById('kategorie').className='tab_subbox tab4';
                 document.getElementById('distance').className='tab_subbox tab5';
                 document.getElementById('bypois').className='tab_subbox tab6';
                 document.getElementById('opodoTriangle').style.display='none';
                 document.getElementById('priceTriangle').style.display='block';
                 document.getElementById('reviewTriangle').style.display='none';   
                 document.getElementById('distanceTriangle').style.display='none';
                 document.getElementById('bypoisTriangle').style.display='none';
              } 
              else if(typeSort == '3'){
                 document.getElementById('bewertung').className='tab_subbox tab2';
                 document.getElementById('price').className='tab_subbox tab3';
                 document.getElementById('kategorie').className='tab_subbox tab4 tabon';
                 document.getElementById('distance').className='tab_subbox tab5';
                 document.getElementById('bypois').className='tab_subbox tab6';
                 document.getElementById('opodoTriangle').style.display='none';
                 document.getElementById('priceTriangle').style.display='none';
                 document.getElementById('reviewTriangle').style.display='block';      
                 document.getElementById('distanceTriangle').style.display='none';
                 document.getElementById('bypoisTriangle').style.display='none';      
              }
              else if(typeSort == '4'){
                 document.getElementById('bewertung').className='tab_subbox tab2';
                 document.getElementById('price').className='tab_subbox tab3';
                 document.getElementById('kategorie').className='tab_subbox tab4';
                 document.getElementById('distance').className='tab_subbox tab5 tabon';
                 document.getElementById('bypois').className='tab_subbox tab6';
                 document.getElementById('opodoTriangle').style.display='none';
                 document.getElementById('priceTriangle').style.display='none';
                 document.getElementById('reviewTriangle').style.display='none';      
                 document.getElementById('distanceTriangle').style.display='block';
                 document.getElementById('bypoisTriangle').style.display='none';      
              }
              else if(typeSort == '5'){
                 document.getElementById('bewertung').className='tab_subbox tab2';
                 document.getElementById('price').className='tab_subbox tab3';
                 document.getElementById('kategorie').className='tab_subbox tab4';
                 document.getElementById('distance').className='tab_subbox tab5';
                 document.getElementById('bypois').className='tab_subbox tab6 tabon';
                 document.getElementById('opodoTriangle').style.display='none';
                 document.getElementById('priceTriangle').style.display='none';
                 document.getElementById('reviewTriangle').style.display='none';      
                 document.getElementById('distanceTriangle').style.display='none';
                 document.getElementById('bypoisTriangle').style.display='block';      
              }
           </script>

【问题讨论】:

标签: javascript


【解决方案1】:

在 JavaScript、Python 和其他为核心数据结构提供 literal notation 的灵活语言中,我发现构建简单的数据结构来表示变化的部分,然后围绕结构构建逻辑很方便。

var tabs = [
  {id: 'bewertung', contentId: 'opodoTriangle'}
, {id: 'price', contentId: 'priceTriangle'}
, {id: 'kategorie', contentId: 'reviewTriangle'}
, {id: 'distance', contentId: 'distanceTriangle'}
, {id: 'bypois', contentId: 'bypoisTriangle'}
];

var activeIdx = parseInt(document.getElementById('sortTypeUp').value, 10) - 1;
for (var i = 0, l = tabs.length; i < l; i++) {
  var tab = tabs[i]
    , active = (i == activeIdx)
    , tabEl = document.getElementById(tab.id)
    , contentEl = document.getElementById(tab.contentId);
  if (active) {
    addClass(tabEl, 'tabon');
  } else {
    removeClass(tabEl, 'tabon');
  }
  contentEl.style.display = (active ? 'block' : 'none');
}

类管理实用程序方法(来自http://dean.edwards.name/IE7/caveats/ - 刚刚抓取了我找到的第一个实现):

function addClass(element, className) {
  if (!hasClass(element, className)) {
    if (element.className) element.className += ' ' + className;
    else element.className = className;
  }
};

function removeClass(element, className) {
  var regexp = new RegExp('(^|\\s)' + className + '(\\s|$)');
  element.className = element.className.replace(regexp, '$2');
};

function hasClass(element, className) {
  var regexp = new RegExp('(^|\\s)' + className + '(\\s|$)');
  return regexp.test(element.className);
};

奖励:这是一个简洁的版本,它使用类型强制、逗号运算符、for 循环赋值和退出逻辑以及作为第一类对象的函数 - 仅作为示例! :)

var activeIdx = +document.getElementById('sortTypeUp').value - 1;
for (var i = 0, tab, active; active = (i == activeIdx), tab = tabs[i]; i++) {
  (active ? addClass : removeClass)(document.getElementById(tab.id), 'tabon');
  document.getElementById(tab.contentId).style.display =
      (active ? 'block' : 'none');
}

【讨论】:

  • 代码太简洁了。 for 循环中的魔法太多了。而且通常很难阅读。
  • @Raynos 已编辑为更具可读性/可维护性的版本
  • +1 读起来好多了。简洁的版本是闭包编译器应该为你做的;)
【解决方案2】:
    <script type="text/javascript">

       var typeSort = document.getElementById('sortTypeUp').value;

       document.getElementById('bewertung').className = 'tab_subbox tab2' + ((typeSort=='1') ? ' tabon' : '');
       document.getElementById('price').className='tab_subbox tab3' + ((typeSort=='2') ? ' tabon' : '');
       document.getElementById('kategorie').className='tab_subbox tab4' + ((typeSort=='3') ? ' tabon' : '');
       document.getElementById('distance').className='tab_subbox tab5' + ((typeSort=='4') ? ' tabon' : '');
       document.getElementById('bypois').className='tab_subbox tab6' + ((typeSort=='5') ? ' tabon' : '');
       document.getElementById('opodoTriangle').style.display = ((typeSort=='1') ? 'block' : 'none');
       document.getElementById('priceTriangle').style.display=((typeSort=='2') ? 'block' : 'none');
       document.getElementById('reviewTriangle').style.display=((typeSort=='3') ? 'block' : 'none');
       document.getElementById('distanceTriangle').style.display=((typeSort=='4') ? 'block' : 'none');
       document.getElementById('bypoisTriangle').style.display=((typeSort=='5') ? 'block' : 'none');

    </script>

【讨论】:

  • 它更简洁,但那些tenaries是可怕的。
  • 可读性和可维护性确实受到影响,但正如 Raynos 所说,它更简洁。
【解决方案3】:

您可以将代码的公共部分放在函数中,如下所示:

function active(id, tab, typeSort, eq){
  document.getElementById(id).className='tab_subbox '+tab+(typeSort==eq?' tabon':'');
}

function show(id, typeSort, eq){
  document.getElementById(id).style.display=typeSort==eq?'block':'none';
}

var typeSort = parseInt(document.getElementById('sortTypeUp').value);

active('bewertung', 'tab2', typeSort, 1);
active('price', 'tab3', typeSort, 2);
active('kategorie', 'tab4', typeSort, 3);
active('distance', 'tab5', typeSort, 4);
active('bypois', 'tab6', typeSort, 5);

show('opodoTriangle', typeSort, 1);
show('priceTriangle', typeSort, 2);
show('reviewTriangle', typeSort, 3);      
show('distanceTriangle', typeSort, 4);
show('bypoisTriangle', typeSort, 5);

【讨论】:

  • 对@Sascha 答案的改进。如果使用数组而不是三元组,我会很好。
  • 真的,看起来更好...+1 :)
【解决方案4】:

也许创建一个以两个数组作为参数的方法:一个数组包含应重置其类的元素的 id,另一个数组包含相应的新样式。

function updateClasses(ids, classes) {
// implement me
}

只初始化一次元素数组:

var ids=new Array("bewertung","price","kategorie", ...);

对于每种情况:

if(typeSort == '1'){
    var classes=new Array("tab_subbox tab2 tabon","tab_subbox tab3","tab_subbox tab4", ...);
    updateClasses(ids, classes);
} else if (typeSort == '2') {
    var classes = // some other values
    updateClasses(ids, classes);
} // ...

编辑

也像约翰所说的那样使用 switch 语句。

【讨论】:

  • @Raynos 你能具体说明它有什么问题吗?我知道我对 JS 不太熟悉,所以我从 w3schools (w3schools.com/js/js_obj_array.asp) 获取了一个示例数组初始化。另外,这应该是描述我的想法的一个例子。实际的实现应该由 OP 完成。
  • 其实并没有错,抱歉。我还建议您参考 mdc 而不是 W3Schools,因为 w3schools 也有错误的习惯。
  • w3fools.com 并且首选的数组构造是使用["bewertung", "price" /* etc */]
  • @Raynos 好的,谢谢。 W3Schools 恰好是谷歌在这个主题上的第一个热门,所以我选择了那个。
【解决方案5】:

将包含 css 类分配的公共代码放在顶部 例如

document.getElementById('bewertung').className='tab_subbox tab2';

而且更有可能的是,当您将对象标记为隐藏时,这似乎也是一个通用代码...将其放在顶部并仅将那些需要的对象标记为可见

用案例语句代替 Ifs,并使用 Jquery 来改进您的代码风格。

【讨论】:

  • jQuery 不会改善你的代码风格。
【解决方案6】:
var get = document.getElementById;
var elems = ['bewertung', 'price', 'kategorie', 'distance', 'bypois'];
var triangles = ['opodoTriangle', 'priceTriangle', 'reviewTriangle', 'distanceTriangle', 'bypoisTriangle'];
var typeSort = +get('sortTypeUp').value - 1;

elems.forEach(function(v) {
    var elem = get(v);
    elem.classList.remove('tabon');
});

triangles.forEach(function(v) {
    var elem = get(v);
    elem.style.display = 'none';
});

elems[typeSort].classList.add('tabon');
triangle[typeSort].style.display = 'block';

使用 DOM3 / ES5。

使用数组并将typeSort 视为数组索引。

.classList shim, ES5 shim

【讨论】:

  • 查看类名和 ID,我怀疑访问者是否使用了这样的现代浏览器:D
  • @Lekensteyn 只需添加 ES5 垫片和类列表垫片,它应该修复它
【解决方案7】:
typeSort = parseInt( document.getElementById('sortTypeUp').value );

s = ["bewertung", "price", "kategorie", "distance", "bypois"];
for(i=0;i<s.length;i++) {
  e = document.getElementById(s[i]);
  n = i + 2;
  e.className = "tab_subbox tab" + n;
  if(typeSort == (i+1)) {
     e.className = e.className + " tabon";
  }
}

s = ["opodo", "price", "review", "distance", "bypois"];
for(i=0;i<s.length;i++) {
  e = document.getElementById( s[i] + "Triangle" );
  e.style.display = 'none';
  if(typeSort == (i+1)) {
    e.style.display = 'block';
  }
}

【讨论】:

  • 和上面的代码不一样
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多