YIXUNFE / blog

文章区
151 stars 25 forks source link

整站侧边栏开发实践(二)——内容 #54

Open YIXUNFE opened 8 years ago

YIXUNFE commented 8 years ago

整站侧边栏开发实践(二)——内容

上一节我们了解了侧边栏实现过程中利用栏目类实现侧边栏栏目的添加。这一节我们讲讲栏目展开后的内容区域的处理。


消息提示设计

在内容区域的交互过程中,涉及到许多提示消息,比如异步加载过程中的 loading 提示,删除收藏、添加购物车等提示。所以在编写栏目的充填方法之前需要先定义好一套简易的消息 api。

先在模板中埋一个 DOM 节点:

<div class="msg-box"></div>

然后我们使用这个节点展示/隐藏提示消息。

var tipTimer
function _showMsgTip (txt, type) {
  tipTimer && clearTimeout(tipTimer)
  var box = dom.find('.msg-box')
  box.removeClass('success error warning')
  type && box.addClass(type) //type 值应该是上述三个中的一个
  box.addClass('show').html(txt)
  tipTimer = setTimeout(function () {
    box.removeClass('show')
  }, 3000)
}

_showMsgTip 方法提供两个参数,第一个是消息文案,第二个是消息提示框的类型,不同类型具有不同的样式。另外这里也使用 CSS3 动画做过渡效果,IE8 就不多考虑了。

.msg-box {
  position: absolute; 
  top: -100px; 
  left: 50%; 
  margin-left: -60px; 
  width: 100px; 
  padding: 20px; 
  border-radius: 5px; 
  background: #bbb; 
  color: #333; 
  font-size: 14px; 
  opacity: 0; 
  text-align: center; 
  -webkit-transition: opacity 0.3s ease-out; 
  transition: opacity 0.3s ease-out;
}

.msg-box.show {opacity: 0.9; top: 40%}


滚动条设计

由于一般页面右侧已经有一个垂直滚动条了,在内容区域再出现一条垂直滚动条会影响美观,所以我们采用 div 模拟滚动条,类似组件网上已经有很多了,这里我们使用了自己编写的简易版滚动条组件。

这个简易组件提供了两个更新方法用于不同的情况:

方法名 描述
refresh 更新滚动条组件并重新计算内容区域高宽,滚动条重置回初始位置(0, 0)
update 更新滚动条组件并重新计算内容区域高宽,滚动条位置保持不变

目前这个组件没有开源出来,相关 API 会在该组件的开源项目中罗列。

由于所有栏目共用一个内容区,所以滚动条组件在每次内容区展示之前需要调用上述两个方法之一。

这两个方法都会重新计算可滑动区域的高度,以便调整滚动条长度。


委托事件设计

各个栏目所展开的内容,在交互上有相当多的事件需要处理,通过一堆的 bindon 方法绑定好像有点糟糕。所以我使用了以前就经常使用的委托方式,统一处理事件。

这种方式简单描述就是将需要调用的事件处理函数存放在一个标记字典中,在 document 对象上绑定 click 事件,所有触发元素带有标记的都执行对应标记的处理函数。

比如“我的收藏”栏目的内容区域,每个商品都有“删除”和“添加购物车”按钮,绑定方式是这样的:

<i class="del actBtn" action="delFavor">删除</i> 
<a class="add actBtn" action="addFavor2Cart">加入购物车</a>
actionList.extend({
  'addFavor2Cart': function () {...},
  'delFavor': function () {...}
})

由于是委托在 document 对象上,我们也不用担心每次内容区域更新时候需要重新绑定事件的问题。

它的实现也十分简单:

var actionList = {}
$(document).delegate('.actBtn', 'click', function (e) {
  var name = $(this).attr('action')
  actionList[name] && actionList[name].apply(this)
})
actionList.extend = function (data) {
  var item
  for (item in data) {
    this[item] = data[item]
  }
}

希望这些内容对你有所帮助。


Thanks