xavier

Do the right things!

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

最近,公司需要使用jQuery mobile来构建一个移动应用,期间遇到了一个场景:需要一个可以折叠的控件,当点击这个控件header的右侧时,展开内容;左侧是不可点击的,只是一些说明性的文字或者图片。如下图所示:

jQuery mobile Collapsible

当看到这样的需求时,给我的第一感觉就是用jQuery mobile中的Collapsible控件,但是在经过研究后,发现该控件本身无法实现部分点击使其展开。于是我就想是否可以使header右侧部分向右浮动于header之上,并改变header的点击事件,使其绑定到header左侧,从而达到目的。

既然有了方案,就开始动手吧。

1、首先很简单,通过CSS,控制header右侧部分的位置, 代码如下:

<h3>
    <div class="handler">
        Search Options
    </div>
    <div style="float: right; margin-top: -20px;">
        <div style="float: right; margin: 0; padding: 0;">
            columnN
        </div>
        ……
        <div style="float: right; margin: 0 5px 0 0; padding: 0;">
            Column3
        </div>
        <div style="float: right; margin: 0 5px 0 0; padding: 0;">
            Column2
        </div>
        <div style="float: right; margin: 0 5px 0 0; padding: 0;">
            column1
        </div>
    </div>
</h3>

注:中间部分的列,可以根据需要添加多次

 

2、将h3上的单击事件,移到handler上

1)在jQuery mobile源代码中查找header的单击事件,代码如下:

collapsibleHeading
.bind( "click", function( event ) {

    var type = collapsibleHeading.is( ".ui-collapsible-heading-collapsed" ) ?
                            "expand" : "collapse";

    collapsible.trigger( type );

    event.preventDefault();
});

 

2)从源码中分析得知,只需要把click事件绑定到<div class=”handler”>上即可,改动后,代码如下:

var expandHandler = collapsibleHeading.find(o.handler).length > 0 ? collapsibleHeading.find(".handler, .ui-icon") : collapsibleHeading;
expandHandler.bind("click", function (event) {

    var type = collapsibleHeading.is(".ui-collapsible-heading-collapsed") ?
                            "expand" : "collapse";

    collapsible.trigger(type);

    event.preventDefault();
});

 

到目前为止,对Collapsible控件的修改基本已经完成。但是在使用一段时间后,发现如下一个问题:前端这个header的细节暴露过多,使用起来太麻烦。于是通过简单的封装和调整,前端的header简化为:

<h3>
    <div class="handler">
    Search Options
    </div>
    <div>column1</div><div>column2</div>
    <div>column3</div>……<div>columnN</div>
</h3>

调整后的js源码如下:

1、 在options对象中,增加一个成员:

$.widget("mobile.collapsible", $.mobile.widget, {
    options: {
    ……
    handler: ".handler"
}

2、 控制div样式的代码

var cols = collapsibleHeading.find("div").not(".handler").remove();            
for(var i = cols.length - 1; i >=0; i--){
    var style = "float: right; margin: 0 5px 0 0; padding: 0;";
    if(i== cols.length - 1){
        style = "float: right; margin: 0; padding: 0;";
    }
    collapsibleHeading.find(".ui-btn-text").append($(cols.get(i)).attr("style", style));
}
collapsibleHeading.find("div").not(".handler").wrapAll("<div style='float: right; margin-top: -20px;'></div>");

3、 事件代码:

var expandHandler = collapsibleHeading.find(o.handler).length > 0 ? collapsibleHeading.find(".handler, .ui-icon") : collapsibleHeading;
expandHandler.bind("click", function (event) {

    var type = collapsibleHeading.is(".ui-collapsible-heading-collapsed") ?
                            "expand" : "collapse";

    collapsible.trigger(type);

    event.preventDefault();
});

问题终于解决了,最终代码见附件

jQuery mobile for Collapsible

posted on 2012-04-09 13:03  Xavier Zhang  阅读(1853)  评论(2编辑  收藏  举报