javascript级联菜单(日历)

上次考DOM,考到级联菜单,迷迷糊糊,晕晕乎乎,不知从何下手。今天冷静下来,理了理思路。

要求:

  1. “年”或“月”发生变化且为有效值时,“日”下拉选择框显示相应的项。
  2.  “年”下拉选择框为初始状态时, “月”、“日”下拉选择框一定为初始状态。
  3. “月”下拉选择框为初始状态时, “日”下拉选择框一定为初始状态。

calender

思路:

1.  当前选框选项有变化的时候,操作下一个选框。当选择年份的时候,填充月份,选择月份的时候,根据所选月份填充日期。当年份为初始化状态,将月份和日期设置为初始化状态,月份为初始化状态时,将日期也设置为初始化状态。

2. 每年的月份数相同,但每个月的天数不同,将不同天数保存在数组中,方便相应月份调用。

3. 闰年2月与平年2月天数不同,分开判断。

上代码:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Calendar</title>
</head>
<body style="text-align:center">
    <select name="year" id="year">
        <option value="0">--</option>
        <option value="2010">2010</option>
        <option value="2011">2011</option>
        <option value="2012">2012</option>
    </select> 年
    <select name="month" id="month">
        <option value="0">--</option>
    </select> 月
    <select name="date" id="date">
        <option value="0">--</option>
    </select> 日
    
    <script>
        window.onload = initSelect;
        
        function initSelect(){
            var yearSel = document.getElementById('year');
            var monthSel = document.getElementById('month');
            
            initYear(); //设置年份默认选中第一个选项
            initMonth(); //设置月份默认选中第一个选项
            initDate(); //设置日期默认选中第一个选项
            yearSel.onchange = yearFun; //当年份被选择的时候调整月份
            monthSel.onchange = monthFun; //当月份被选择的时候调整日期
            
        }
        
        function yearFun(){
            if( this.options.selectedIndex === 0 ){ //如果选中第一个,把月,日设置为也选中第一个
                initMonth();
                initDate();
            }else{ //如果选中年份,填充月份
                popMonth();
            }
        }
        
        function monthFun(){
            var dateArr = [31,28,31,30,31,30,31,31,30,31,30,31]; //储存不同月份天数的数组
            var thisValue = parseInt(this.options[this.options.selectedIndex].value); //获取当前选中的选项的值并转为数字
            
            if( this.options.selectedIndex === 0 ){ //如果选中第一个选项,初始化日期
                initDate();
            }else{ //如果选中其他选项,根据选项加载不同日期
                document.getElementById('date').options.length = 1;
                var isLeap = checkLeap(); //要使用函数返回值,可以保存为变量,或直接使用
                if ( isLeap ){
                    dateArr[1] = 29;
                }else{
                    dateArr[1] = 28;
                }
                for( var i = 0; i < dateArr[thisValue-1]; i++ ){ //根据选中选项的value值查找date数组中对应的天数值,循环出来
                    document.getElementById('date').options[i+1] = new Option( i+1 ); //因为第一个选项是横线,所以要+1,从第二个开始
                };
            }
        }
        
        function popMonth(){
            initDate(); //填充月份的时候初始化日期
            for( var i = 0; i < 12; i++ ){
                document.getElementById('month').options[i+1] = new Option(i+1,i+1); //填充月份,设置内容和值
            }
        }
        
        function checkLeap(){ //判断选中年份是否为闰年
            var yearSel = document.getElementById('year');
            var thisYearValue = parseInt(yearSel.options[yearSel.options.selectedIndex].value); //获取当前选中年份的值并转为数字
            if( (thisYearValue % 4  === 0 && thisYearValue % 100 !== 0) || thisYearValue % 400 === 0 ){ //闰年:能被4整除的同时不能被100整除,或者能被400整除,只要满足两者之一就是闰年
                return true;
            }
            return false;
        }
        
        function initYear(){
            document.getElementById('year').options.selectedIndex = 0; //设置年份选中第一个选项
        }
        
        function initMonth(){
            document.getElementById('month').options.selectedIndex = 0; //设置月份选中第一个选项
            document.getElementById('month').options.length = 1; //只保留第一个选项
        }
        
        function initDate(){
            document.getElementById('date').options.selectedIndex = 0; //设置日期选中第一个选项
            document.getElementById('date').options.length = 1; //只保留第一个选项
        }
    </script>
</body>
</html>

查看DEMO

1. select.options.selectedIndex 可以获取到被选中选项的index值。

2. new Option( ), 创建新的option

3. 函数的返回值可以保存为变量:

function myFunction()
{
var x=5;
return x;
}

可以保存为变量:

var myVar=myFunction();
console.log(myVar);

也可以直接使用:

document.getElementById("demo").innerHTML=myFunction();

关于响应式设计

响应式网页设计responsive web design(RWD)的流行已经有挺长一段时间了,过去的2012年,响应式设计已深入人心,2013年仍是网页设计的一大热门并且是将来的一种趋势。当用移动设备浏览网页看到的是普通电脑缩小版的网页并且无法使用阅读器时,多数人通常的做法是直接离开。关于响应式设计研究的文章不尽其数,比如前端观察的响应式网页设计这篇文章,是我认识响应式设计的第一篇文章,介绍得比较全面。Web designer wall 三步实现响应式设计教你快速入门。

由于工作需要,自己也做了一些响应式的web app,公司的开发模式属于快速开发,于是2012年中旬开始认识响应式设计的我目前对它的研究并不深,只是在工作中碰到不少问题,面对这些问题,google是个不错的选择,不知是否搜索技巧有问题,总觉得找的答案并不恰恰就是我想要的,于是决定把一些问题和解决方案及从别人那里学到的有用的小经验分享出来,希望能获得更大的进步。

实现响应式的网页,我主要依赖于css3的Media Queries, 虽说一些人痛恨Media Queries, 也有人提出,响应式设计不应该只是Media Queries(还有图片处理技术<img srcset>和<picture>),但不得不承认,这几乎是我展开工作的全部。

一般响应式网页设计会有一个基础html框架: header, navigation, content, aside, footer. 作为响应式设计,其核心是根据屏幕尺寸保留网页主要内容(content),相应隐藏其他非重要内容,以保证网站内容的可读性(个人意见)。而一个web app,设计感更浓重,图片更多更大,其响应的难度要远远大于一个博客式的website。

1.字体。

web app要求内容的趣味性,设计师通常会使用一些与设计风格相匹配的字形(而这些字体通常不是google web font),如果目标用户非移动用户,这个可以用图片来解决(css sprite),但如果需要一个responsive的web app,这是个非常糟糕的选择。css sprite对其背景定位和大小尺寸需要相当准确,无法适应对尺寸要求极度宽松的响应式,并且多而大的图片对加载速度影响很大。因此,建议使用google web font(上面有很多漂亮的字形,限英文)或系统默认字体。当然也有嵌入字体只说,但如果是中文,可要考虑字库大小哦~

对于字号,应至少设置为14px,通常网页上的12px在移动设备上浏览还是有些吃力的。

2.图片。

对于背景图的设计,应尽量使用可以平铺的小图案,或者规律的渐变,这些渐变可以用css3来实现,也可以使用那些即使被切掉也无关紧要的图片,以减少屏幕尺寸变换时对图片的频繁切换。

3.导航。

导航在引导用户浏览网站或者app中起着非常重要的作用,除了导航数量少,字数简短的情况下,一般导航在电脑版切换到移动版时,需要更适合的UI。这里教你如何创建合适的响应式导航。

4.移动应用的特性:touch。

不同于website, web app 在手机上的需求更高,例如浏览一个图片slider,网页上通常通过点击左右键来切换图片,而在手机上,左右滑动的手势更符合用户习惯,因此可以选择一些响应式的jquery插件,例如FlexSlider

5.禁止缩放。

<meta content=”width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0″ name=”viewport”>

width                      – viewport的宽度

height                     – viewport的高度

initial-scale          – 初始的缩放比例

minimum-scale  – 允许用户缩放到的最小比例

maximum-scale – 允许用户缩放到的最大比例

user-scalable       – 用户是否可以手动缩放

6.IOS中Safari允许全屏浏览。

<meta content=”yes” name=”apple-mobile-web-app-capable”>

7.IOS中Safari顶端状态条样式

<meta content=”black” name=”apple-mobile-web-app-status-bar-style”>

content=”black”即设置为黑色。

8.忽略将数字变为电话号码

<meta content=”telephone=no” name=”format-detection”>

9.IOS中Safari设置保存到桌面图标

<link rel=”apple-touch-icon” href=”custom_icon.png”>

添加到主屏幕UI:图标参考:

图标会自动添加高亮效果,如果不需要,可以在plist中明确指定UIPrerenderedIcon的键值去掉

57像素的普屏的iPhone图标,图标圆角的半径为10像素

114像素Retina屏的iPhone图标,图标圆角的半径为20像素

512像素的用于iTunes/App Store的图标,在实际显示是会被缩放到175像素进行显示(但提交是不可以提交175像素)

72像素的普屏iPad图标,图标圆角的半径为13像素

144像素Retina屏iPad图标,图标圆角的半径为26像素

50像素iPad的Spotlight搜索图标的最终视觉大小是48像素,原因是iOS会对图标的每个边去掉1个像素,添加阴影效果

100像素Retina屏的Spotlight搜索图标的最终视觉大小是96像素,原因同上,这次是每边减2个像素

10.关闭Input键盘默认首字母大写

autocapitalize=”off”

例如: <input type=”text” value=“” name=”” autocapitalize=”off” />

根据需要设置,因为有一些输入框还是需要首字母大写的,如姓名。

11.去除Android平台中对邮箱地址的识别

<meta content=”email=no” name=”format-detection” />

12.-webkit-box-sizing

在 移动设备开发过程中我们通常会对文本框定义为宽度100%,将其定义为块级元 素以实现全屏自适应的样式,但此时你会发现,该元素的边框(左右)各1个像 素会溢了文档,导致出现横向滚动条,为解决这一问题,我们可以为其添加一个特殊 的样式-webkit-box-sizing:border-box;用来指定该盒子的大小包括边框的宽度。

13.禁止iphone字体大小调整

html { -webkit-text-size-adjust: none; }

14.图片在retina高清屏下的显示

为了保证图片在retina下的高清显示,需要准备一张原始图和一个比原图大一倍的图。

 image{ background-image:url( image_url );/*用于普通屏幕*/
/* ———— Retina ———— */
@media only screen and (-o-min-device-pixel-ratio: 2/1), /* Opera */
only screen and (min–moz-device-pixel-ratio: 2),        /* Firefox 16 之前 */
only screen and (-webkit-min-device-pixel-ratio: 2),    /* Webkit */
only screen and (min-resolution: 240dpi),                    /* 标准 */
only screen and (min-resolution: 2dppx)                      /* 标准 */
{
image{
background-image:url( image_url );
background-size: 50% 50%;
}
}
另外,无图片(no images)是开发的趋势,圆形,三角,渐变,阴影,如果是移动应用开发,请把它们变成css代码,因为它的灵活性足够适应不同尺寸的屏幕并且图像质量不会下降。