• 杂谈Bootstrap页面框架时间选择器datetimepicker


    Prologue . Bug And Analysis

      开心就好~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^_^

      写这篇文章助助兴,调剂下最近繁重的工作。是的,我现在化身成一个打杂的。

      最近项目准备上线,系统稳定性和业务逻辑稳定性逐步提升后,可爱的小测试提出一个惊为天人的二类BUG——

        Bootstrap页面框架的时间选择框选择困难

      作为一只萌萌哒后台狗,这种疑难杂症一般解决思路是:不予解决

      可是架构师让我顺便仔细考虑下此问题,尽量不去切换页面组件。T.T

      好吧~~~那首先让我们首先分析下问题!这是Datetimepicker官方给出的示例。

      

      当页面当前位置在靠近下端时,选择框向下弹出:

       

      妹!子!说!她!选!的!很!不!舒!服!

      炸裂=。=

      好吧看看我能做什么。T.T

    Chapter one . Purpose

      预设目标:

        1. Datetimepicker时间选择框尽量放弃使用累赘的页面配置(我初步设想是通过css样式控制。)提高开发效率。

        2. 当选择框在页面上部时,往下弹出。反之往上弹出。

        3. 当输入框为只读时,去掉禁止输入的悬停事件手势。(这是顺便解决的另外一个BUG=。=)

    Chapter two . Used Source Code

      Bootstrap是一款推特公司推出的页面开发框架。许多运营商都为它提供了js组件,比如页面验证,树,选择器,富文本等等等。

      Bootstrap的核心理念是将扁平式交互设计并将终端屏幕分为12等分。我们这里讲的是它的一个常用的时间选择器datetimepicker。

      在页面上使用datetimepicker我们一般需要这样搞:

      HTML:

     1 <div class="form-group">
     2     <label class="col-sm-2 control-label" for="dtp_input2">
     3         海贼王下次多会断更:
     4         <span style="color: red;">*</span>
     5     </label>
     6     <div class="col-md-10">
     7         <div class="input-group date col-sm-5 ">
     8             <input id="date1" class="form-control" type="text" size="16" readonly=readonly
     9                     value="<fmt:formatDate value="${date}" pattern="yyyy-MM-dd HH:mm"/>" />
    10                 <span class="input-group-addon"><span class="glyphicon glyphicon-remove"></span></span> 
    11                 <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
    12         </div>
    13     </div>
    14 </div>

      备注:页面需要声明JS CSS引用。

      JS:

    1 $("#date1").datetimepicker({
    2     language : 'zh-CN',
    3     format : "yyyy-mm-dd hh:ii",
    4     todayBtn : 1,    autoclose : 1,
    5     todayHighlight : 1,
    6     startDate : (new Date()).formate("yyyy-MM-dd HH:mm"),
    7     pickerPosition : 'bottom-right'
    8 });

      这里使用了(new Date()).formate("yyyy-MM-dd HH:mm")是对JS原型Date对象formate()方法的的一个简单原型拓展。

     1 /**
     2  * JS原型初始化拓展
     3  */
     4 var formatPrototype = function() {
     5     ...
     6     /**
     7      * 对Date的扩展,将 Date 转化为指定格式的String
     8      * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q) 可以用 1-2 个占位符 年(y)可以用 1-4
     9      * 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字) eg: (new Date()).formate("yyyy-MM-dd
    10      * hh:mm:ss.S") ==> 2006-07-02 08:09:04.423 (new Date()).formate("yyyy-MM-dd
    11      * E HH:mm:ss") ==> 2009-03-10 二 20:09:04 (new Date()). formate("yyyy-MM-dd
    12      * EE hh:mm:ss") ==> 2009-03-10 周二 08:09:04 (new Date()).formate("yyyy-MM-dd
    13      * EEE hh:mm:ss") ==> 2009-03-10 星期二 08:09:04 (new Date()).formate("yyyy-M-d
    14      * h:m:s.S") ==> 2006-7-2 8:9:4.18
    15      */
    16     Date.prototype.formate = function(fmt) {
    17         var o = {
    18             "M+" : this.getMonth() + 1, // 月份
    19             "d+" : this.getDate(), // 日
    20             "h+" : this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, // 小时
    21             "H+" : this.getHours(), // 小时
    22             "m+" : this.getMinutes(), // 分
    23             "s+" : this.getSeconds(), // 秒
    24             "q+" : Math.floor((this.getMonth() + 3) / 3), // 季度
    25             "S" : this.getMilliseconds()
    26         // 毫秒
    27         };
    28         var week = {
    29             "0" : "u65e5",
    30             "1" : "u4e00",
    31             "2" : "u4e8c",
    32             "3" : "u4e09",
    33             "4" : "u56db",
    34             "5" : "u4e94",
    35             "6" : "u516d"
    36         };
    37         if (/(y+)/.test(fmt)) {
    38             fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "")
    39                     .substr(4 - RegExp.$1.length));
    40         }
    41         if (/(E+)/.test(fmt)) {
    42             fmt = fmt
    43                     .replace(
    44                             RegExp.$1,
    45                             ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "u661fu671f"
    46                                     : "u5468")
    47                                     : "")
    48                                     + week[this.getDay() + ""]);
    49         }
    50         for ( var k in o) {
    51             if (new RegExp("(" + k + ")").test(fmt)) {
    52                 fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k])
    53                         : (("00" + o[k]).substr(("" + o[k]).length)));
    54             }
    55         }
    56         return fmt;
    57     };
    58     ...
    59 };
    View Code

      页面加载成功后,会加载JS将id为date1的输入框datetimepicker初始化,当你单击输入框时,向下弹出时间选择框。

    Chapter Three . Mine Design

      首先建立一个公共类并引入。

      enDatetimepicker.js

      

    $(function(e) {
        ...
        formatPrototype();        //JS原型初始化拓展
        initDatetimepicker();      //初始化时间选择器
        ...
    });
    
    /**
     * JS原型初始化拓展
     */
    var formatPrototype = function() {
        ...//上面已经贴出
    };
    
    /**
     * 自定义元素初始化拓展,自适应屏幕高度并限制当前时间。IE click时间选择器页面跳动,完美即时自适应屏幕高度。
     */
    var initDatetimepicker = function() {
        // bootstap datetimepicker need
        $('.sapphire_date').addClass('date');
        // mounse on in hand
        $('input', $('.sapphire_date')).css("cursor", "pointer");
        // init datetimepicker by offset
        $(".sapphire_date").click(function() {
            var allHeight = $(document).height();
            offset01 = $(this).offset();
            offsettop01 = offset01.top;
            offsetbottom01 = allHeight - offsettop01;
            if (offsetbottom01 <= 500) {
                $(this).datetimepicker({
                    language : 'zh-CN',
                    format : "yyyy-mm-dd hh:ii",
                    todayBtn : 1,
                    autoclose : 1,
                    todayHighlight : 1,
                    forceParse : 0,
                    startDate : (new Date()).formate("yyyy-MM-dd HH:mm"),
                    pickerPosition : 'top-right'
                }).on("hide", function() {
                    $(this).datetimepicker('remove');
                });
            } else {
                $(this).datetimepicker({
                    language : 'zh-CN',
                    format : "yyyy-mm-dd hh:ii",
                    todayBtn : 1,
                    autoclose : 1,
                    todayHighlight : 1,
                    forceParse : 0,
                    startDate : (new Date()).formate("yyyy-MM-dd HH:mm"),
                    pickerPosition : 'bottom-right'
                }).on("hide", function() {
                    $(this).datetimepicker('remove');
                });
            }
            $(this).datetimepicker('show');
        });
    };

      大功告成~!@当你加载该js时,并且声明该输入框class="... sapphire_date ..."就可以实现上述目标了。

      让我感受下它强大的气场。

      当输入框出现在当前页面下部的时候。

      当输入框出现在当前页面上部的时候。

      而且当鼠标悬停时,选择手势变成一只小手。呵呵哒。

    Chapter Four. End

      压压惊,这下我可以心安理得的关闭这几个BUG了吧!

      如果你有更好的解决方式请指教我^_^。


    作者:牧伯流水
    World need ur smile O(∩_∩)O Copyright ©2015 Galaxias.Sapphi.REN

  • 相关阅读:
    SVN的安装与配置
    nginx之location配置详解及案例
    查看三种MySQL字符集的方法(转)
    JAVA_OPTS设置
    vi/vim 添加或删除多行注释
    Linux 下查看字体
    linux 安装中文字体
    Linux 压缩某个文件夹命令
    Navicat Premium 12.1.16.0安装与激活
    Rsync + sersync 实时同步备份
  • 原文地址:https://www.cnblogs.com/Galaxias-Sapphi-REN/p/4641306.html
Copyright © 2020-2023  润新知