jQuery 清理

jQuery Clean Up

总的来说,我对 jQuery 和 JavaScript 还很陌生。

我为一个简单的推送菜单编写了这段代码,但我觉得可能有更好的方法来编写它,因为其中一些似乎是重复的。

任何建议都很好。

完整代码可见here

//Mobile Push menu

// Open or close menu using menu bar icon or clicking outside of the menu
$('.menu-icon').click(function() {
    $('.main-content').toggleClass('push-open push-close');  
    $('.menu-icon').toggleClass('push-open push-close');
});

// Close menu with X icon
$('.close-icon').click(function() {
  $('.main-content').toggleClass('push-open push-close'); 
  $('.menu-icon').toggleClass('push-open push-close');
});

//Close menu on link click
$('.menu a').click(function() {
  $('.main-content').toggleClass('push-open push-close'); 
  $('.menu-icon').toggleClass('push-open push-close');
});

// Close with esc key
$(document).keyup(function(e) {
  if (e.keyCode == 27) { // escape key maps to keycode `27`
    if( $('.main-content').hasClass('push-open') ){
      $('.main-content').addClass('push-close');
      $('.main-content').removeClass('push-open');
    }
    if( $('.menu-icon').hasClass('push-open') ){
      $('.menu-icon').removeClass('push-open');         
      $('.menu-icon').removeClass('push-close');
    }
  }
});

看看这个:

(function(){

    //Mobile Push menu

    //var $mainContent = $('.main-content');
    //var $menuIcon = $('menu-icon');
    var $toggleContent = $('.main-content, .menu-icon');

    $('.menu-icon, .close-icon, .menu a').on('click', function() {
        toggleOpen(); 
    });

    // Close with esc key
    $(document).keyup(function(e) {
      var keyCode = e.which || e.keyCode || e.code;
      if (keyCode === 27) { // escape key maps to keycode `27`
          toggleOpen(); 
      }
    });

    function toggleOpen(){
        if($toggleContent.hasClass('push-open') ){
            $toggleContent.removeClass('push-open').addClass('push-close');
        }else{
            $toggleContent.removeClass('push-close').addClass('push-open');
        }
    }

})(); // End mobilePush

我喜欢模块风格的一点是,它允许您在函数和事件的范围之外声明变量,例如 $toggleContent,它可以在该模块的整个内部使用,而不会弄乱全局命名空间。

使用 jQuery,您还可以将操作和方法链接在一起,例如 $toggleContent.removeClass('push-open').addClass('push-close');,这绝对有助于提高可读性和消除冗余代码行。

我使用自己的 'toggle' 函数的原因是您同时切换了 'push-open''push-close'。当我在控制台中观看时,它同时是 adding/removing 和 类。我怀疑你想删除一个并添加另一个。此外,使用您自己的函数,您可以添加一个可能会派上用场的回调。

希望对您有所帮助

已更新

完全删除了 mobilePush,因为它没有必要,并添加了 .which

"The event.which property normalizes event.keyCode and event.charCode. It is recommended to watch event.which for keyboard key input."

我正在阅读的一件事是 KeyboardEvent.which 已经贬值,现在 event.key(获取字符)或 event.code 可以使用。建议这样做:

var keyCode = e.which || e.keyCode || e.code

如果您仍然必须支持 IE9 以下的任何东西 - 上帝保佑 -,.keyCode 可以工作,但不能 .which

您的解决方案效果不佳,在滚动时您丢失了两个图标。页面滚动时的菜单图标,菜单滚动时的关闭图标。
您使用的是通用 class,这会给您的样式添加混乱。
您正在切换两个 class,而您只需要一个默认样式和一个 "toggled" class.

完全没有 JS 怎么办?

  • 0 行 JS
  • 用于切换状态的复选框
  • label 个元素来切换我们的复选框
  • 根据复选框的 :checked 状态设置动画
  • 在 CSS 中使用通用兄弟组合器 ~ 来定位所有需要的元素,例如 #over#menu#page...复选框的下一个兄弟姐妹。

给你

@import url("//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css");

/*QuickReset*/ *{margin:0;box-sizing:border-box;} /* Don't transition on "*" !! */
html,body{height:100%;font:14px/1.4 sans-serif;}

/* === CLOSED STYLES === (in order of HTML apperance :D ) */

/* CHECKBOX USED AS MENU TOGGLER */
#ckb { display: none; } /* Hide checkbox button */

/* MENU-BUTTON - notice it's placement in HTML */
#bttn {
  position: fixed;
  z-index: 2;
  top: 0px;
  left: 0px;
  padding: 12px;
  cursor: pointer;
  font-size: 1.3em;
  transition: left .3s, transform .8s; /* will animate left and rotation */
}

/* OVERLAY - To overlay the page and on click closes the menu */
#over{
  position: fixed;
  z-index:1;
  top: 0; 
  left: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(0,0,0,0.6);
  cursor: pointer;
  visibility: hidden;      /* hidden initially */
  opacity: 0;
  transition: opacity .8s; /* we'll transition opacity */
}

/* MENU */
#menu {
  position: fixed;
  overflow-y: auto;
  z-index: 1;
  top: 0;
  left: -285px;
  width: 285px;
  height: 100%;
  background: #fff;
  transition: left .3s;
}
#menu ul {list-style: none; padding: 32px 24px;}
#menu li > * {padding: 5px 10px; display: inline-block; text-decoration: none; color:#f0b; }

/* PAGE AND CONTAINER */
#page {
  position: relative;
  overflow: hidden;
  background: #bbb;
}

.container {
  position: relative;
  left: 0; /* needed since we'll transition this prop */
  background: #eee;
  padding: 32px 56px;
  transition: left .3s;
}

/* === OPEN STYLES === (in order of HTML apperance :D ) */

#ckb:checked ~ #bttn {left: 248px; transform: rotate(180deg);}
#ckb:checked ~ #bttn:before {content: "\f00d";} /* the fa-close character */
#ckb:checked ~ #over {visibility: visible; opacity: 1;}
#ckb:checked ~ #menu {left: 0px;}
#ckb:checked ~ #page > .container {left: 285px;}
<input id="ckb" type="checkbox">
<label for="ckb" id="bttn" class="fa fa-bars"></label>
<label for="ckb" id="over"></label>

<div id="menu">
  <ul>
    <li><label for="ckb">CLICK ME :)</label></li>
    <li><a href="#!">Link One</a></li>
    <li><a href="#!">There's more</a></li>
  </ul>
</div>

<section id="page">
  <div class="container">
    <h1>H1</h1>
    <p style="height:1000px; border:2px dashed gray;">Lorem</p>
  </div>
</section>