百度前端学院2016task2自学笔记

零基础JavaScript编码(一)
任务目的
JavaScript初体验
初步明白JavaScript的简单基本语法,如变量、函数
初步了解JavaScript的事件是什么
初步了解JavaScript中的DOM是什么
任务描述
参考以下示例代码,补充其中的JavaScript功能,完成一个JavaScript代码的编写
本任务完成的功能为:用户可以在输入框中输入任何内容,点击“确认填写”按钮后,用户输入的内容会显示在“您输入的值是”文字的右边

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>IFE JavaScript Task 01</title>
  </head>
<body>
  <label>请输入北京今天空气质量:<input id="aqi-input" type="text"></label>
  <button id="button">确认填写</button>
  <div>您输入的值是:<span id="aqi-display">尚无录入</span></div>
<script type="text/javascript">
(function() {
  /*    
  在注释下方写下代码
  给按钮button绑定一个点击事件
  在事件处理函数中
  获取aqi-input输入的值,并显示在aqi-display中
  */
})();
</script>
</body>
</html>

代码如下:

<body>
    <label>
    请输入北京今天空气质量:
    <input id="aqi-input" type="text">
    </label>
    <button id="button" onclick="f()">确认填写</button>
    <div>您输入的值是:<span id="aqi-display">尚无录入</span></div>
    <script type="text/javascript">
        function f(){
            var i=document.getElementById("aqi-input");
            var d=document.getElementById("aqi-display"); 
            d.innerHTML=i.value;
        }
    </script>
</body>

思路:简单的DOM操作和点击事件.

零基础JavaScript编码(二)
任务目的
在上一任务基础上继续JavaScript的体验
学习JavaScript中的if判断语法,for循环语法
学习JavaScript中的数组对象
学习如何读取、处理数据,并动态创建、修改DOM中的内容
任务描述
参考以下示例代码,页面加载后,将提供的空气质量数据数组,按照某种逻辑(比如空气质量大于60)进行过滤筛选,最后将符合条件的数据按照一定的格式要求显示在网页上

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>IFE JavaScript Task 01</title>
  </head>
<body>
  <h3>污染城市列表</h3>
  <ul id="aqi-list">
<!--   
    <li>第一名:福州(样例),10</li>
    <li>第二名:福州(样例),10</li> -->
  </ul>
<script type="text/javascript">
var aqiData = [
  ["北京", 90],
  ["上海", 50],
  ["福州", 10],
  ["广州", 50],
  ["成都", 90],
  ["西安", 100]
];
(function () {
  /*
  在注释下方编写代码
  遍历读取aqiData中各个城市的数据
  将空气质量指数大于60的城市显示到aqi-list的列表中
  */
})();
</script>
</body>
</html>

代码如下:

<body>
  <h3>污染城市列表</h3>
  <ul id="aqi-list">
<!--   
    <li>第一名:福州(样例),10</li>
    <li>第二名:福州(样例),10</li> -->
  </ul>
  <script type="text/javascript">
    var aqiData = [
    ["北京", 90],
    ["上海", 50],
    ["福州", 10],
    ["广州", 50],
    ["成都", 90],
    ["西安", 100]
    ];
    var cities=new Array();
    window.onload=function(){aqi();}
    function aqi() {
  /*
  在注释下方编写代码
  遍历读取aqiData中各个城市的数据
  将空气质量指数大于60的城市显示到aqi-list的列表中
  */
  for(var i=0;i<aqiData.length;i++){//将指数大于60的提取出来
    if(aqiData[i][1]>60){
      cities.push(aqiData[i]);
    }
  }
  function compare(a,b){//对数组进行降序
    return b[1]-a[1];
  }
  cities.sort(compare);
  var aiqiList=document.getElementById("aqi-list");//将数组添加进li中
  var arr=["一","二","三","四","五"];
  for(var i=0;i<cities.length;i++){
    var li=document.createElement("li");
    li.innerHTML="第"+arr[i]+"名:"+cities[i];
    aiqiList.appendChild(li);
  }
}
</script>
</body>

思路:现在回看,发现还是有一点错误,appendChild写在了循环里面,也不想改了吧,留着以后看。
这里考察了二维数组和数组排序的问题,数组排序要先创建一个compare函数,参数为a,b.如果想要升序,return a-b,降序:return b-a.因为如果return的值为负数,则a排在b前面,retrun的值为正数,则a排在后面.因为这里cities是一个二维数组,并且要进行降序,所以return的值为b[1]-a[1].

零基础JavaScript编码(三)
任务目的
在上一任务基础上继续JavaScript的体验
接触一下JavaScript中的高级选择器
学习JavaScript中的数组对象遍历、读写、排序等操作
学习简单的字符串处理操作
任务描述
参考以下示例代码,读取页面上已有的source列表,从中提取出城市以及对应的空气质量
将数据按照某种顺序排序后,在resort列表中按照顺序显示出来

<!DOCTYPE>
<html>
  <head>
    <meta charset="utf-8">
    <title>IFE JavaScript Task 01</title>
  </head>
<body>
  <ul id="source">
    <li>北京空气质量:<b>90</b></li>
    <li>上海空气质量:<b>70</b></li>
    <li>天津空气质量:<b>80</b></li>
    <li>广州空气质量:<b>50</b></li>
    <li>深圳空气质量:<b>40</b></li>
    <li>福州空气质量:<b>32</b></li>
    <li>成都空气质量:<b>90</b></li>
  </ul>
  <ul id="resort">
    <!-- 
    <li>第一名:北京空气质量:<b>90</b></li>
    <li>第二名:北京空气质量:<b>90</b></li>
    <li>第三名:北京空气质量:<b>90</b></li>
     -->
  </ul>
  <button id="sort-btn">排序</button>
<script type="text/javascript">
/**
 * getData方法
 * 读取id为source的列表,获取其中城市名字及城市对应的空气质量
 * 返回一个数组,格式见函数中示例
 */
function getData() {
  /*
  coding here
  */
  /*
  data = [
    ["北京", 90],
    ["北京", 90]
    ……
  ]
  */
  return data;
}
/**
 * sortAqiData
 * 按空气质量对data进行从小到大的排序
 * 返回一个排序后的数组
 */
function sortAqiData(data) {
}
/**
 * render
 * 将排好序的城市及空气质量指数,输出显示到id位resort的列表中
 * 格式见ul中的注释的部分
 */
function render(data) {
}
function btnHandle() {
  var aqiData = getData();
  aqiData = sortAqiData(aqiData);
  render(aqiData);
}
function init() {
  // 在这下面给sort-btn绑定一个点击事件,点击时触发btnHandle函数
}
init();
</script>
</body>
</html>

代码如下:

html:
<body>
  <ul id="source">
    <li>北京空气质量:<b>90</b></li>
    <li>上海空气质量:<b>70</b></li>
    <li>天津空气质量:<b>80</b></li>
    <li>广州空气质量:<b>50</b></li>
    <li>深圳空气质量:<b>40</b></li>
    <li>福州空气质量:<b>32</b></li>
    <li>成都空气质量:<b>90</b></li>
  </ul>
  <ul id="resort">
    <!-- 
    <li>第一名:北京空气质量:<b>90</b></li>
    <li>第二名:北京空气质量:<b>90</b></li>
    <li>第三名:北京空气质量:<b>90</b></li>
     -->
  </ul>
  <button id="sort-btn">排序</button>
<script src="task3.js"></script>
</body>

js:
/**
 * getData方法
 * 读取id为source的列表,获取其中城市名字及城市对应的空气质量
 * 返回一个数组,格式见函数中示例
 */
function getData() {
  var source=document.getElementById("source");
  var cities=source.getElementsByTagName("li");
  var data=new Array();
  for(var i=0;i<cities.length;i++){
     data[i]=new Array();
     data[i][0]=cities[i].innerHTML.substring(0,cities[i].innerHTML.indexOf("空"));
     var b=cities[i].getElementsByTagName("b");
     data[i].push(parseInt(b[0].innerHTML));
  }
   return data;
}
/**
 * sortAqiData
 * 按空气质量对data进行从小到大的排序
 * 返回一个排序后的数组
 */
function sortAqiData(data) {
  data.sort(function(a,b){
    return a[1]-b[1];
  });
  return data;
}
/**
 * render
 * 将排好序的城市及空气质量指数,输出显示到id位resort的列表中
 * 格式见ul中的注释的部分
 */
function render(data) {
  var resort=document.getElementById("resort");
  var arr=["一","二","三","四","五","六","七"];
  var str="";
  for(var i=0;i<data.length;i++){
    // var li=document.createElement("li");
    // li.innerHTML="第"+arr[i]+"名:"+data[i][0]+"空气质量:"+data[i][1];
    // resort.appendChild(li);
    str+="<li>第"+arr[i]+"名:"+data[i][0]+"空气质量:<b>"+data[i][1]+"</b></li>";
  }
  resort.innerHTML=str;
}
function btnHandle() {
  var aqiData = getData();
  aqiData = sortAqiData(aqiData);
  render(aqiData);
}
function init() {
  // 在这下面给sort-btn绑定一个点击事件,点击时触发btnHandle函数
  document.getElementById("sort-btn").onclick=btnHandle;
}
init();

思路:首先要将数据从source中剥离出来,创建一个二维数组,用substring()将城市名从cities中剥离出,然后将b标签中的数据push()进去数组.
sortAqiData中用sort排序,compare中return a[1]-b[1],将排序后的数组返回.
至于判断第几名,这里创建一个一到七的数组.
btnHandle将前面的function串起来.绑定到点击事件.

零基础JavaScript编码(四)
任务目的
在上一任务基础上继续JavaScript的体验
深入学习JavaScript的事件机制及DOM操作
学习事件代理机制
学习简单的表单验证功能
学习外部加载JavaScript文件
任务描述
参考以下示例代码,用户输入城市名称和空气质量指数后,点击“确认添加”按钮后,就会将用户的输入在进行验证后,添加到下面的表格中,新增一行进行显示
用户输入的城市名必须为中英文字符,空气质量指数必须为整数
用户输入的城市名字和空气质量指数需要进行前后去空格及空字符处理(trim)
用户输入不合规格时,需要给出提示(允许用alert,也可以自行定义提示方式)
用户可以点击表格列中的“删除”按钮,删掉那一行的数据
task.html

<!DOCTYPE>
<html>
  <head>
    <meta charset="utf-8">
    <title>IFE JavaScript Task 01</title>
    <script src="task.js"></script>
  </head>
<body>
  <div>
    <label>城市名称:<input id="aqi-city-input" type="text"></label><br>
    <label>空气质量指数:<input id="aqi-value-input" type="text"></label><br>
    <button id="add-btn">确认添加</button>
  </div>
  <table id="aqi-table">
  <!-- 
    <tr>
      <td>城市</td><td>空气质量</td><td>操作</td>
    </tr>
    <tr>
      <td>北京</td><td>90</td><td><button>删除</button></td>
    </tr>
    <tr>
      <td>北京</td><td>90</td><td><button>删除</button></td>
    </tr>
   -->
  </table>
</body>
</html>
task.js
/**
 * aqiData,存储用户输入的空气指数数据
 * 示例格式:
 * aqiData = {
 *    "北京": 90,
 *    "上海": 40
 * };
 */
var aqiData = {};
/**
 * 从用户输入中获取数据,向aqiData中增加一条数据
 * 然后渲染aqi-list列表,增加新增的数据
 */
function addAqiData() {
}
/**
 * 渲染aqi-table表格
 */
function renderAqiList() {
}
/**
 * 点击add-btn时的处理逻辑
 * 获取用户输入,更新数据,并进行页面呈现的更新
 */
function addBtnHandle() {
  addAqiData();
  renderAqiList();
}
/**
 * 点击各个删除按钮的时候的处理逻辑
 * 获取哪个城市数据被删,删除数据,更新表格显示
 */
function delBtnHandle() {
  // do sth.
  renderAqiList();
}
function init() {
  // 在这下面给add-btn绑定一个点击事件,点击时触发addBtnHandle函数
  // 想办法给aqi-table中的所有删除按钮绑定事件,触发delBtnHandle函数
}
init();

代码如下:

html:
<body>
<div>
    <label>城市名称:<input type="text" id="aqi-city-input"></label><br>
    <label>空气质量指数:<input type="text" id="aqi-value-input"></label><br>
    <button id="add-btn">确认添加</button>
</div>
<table id="aqi-table">
    <tr>
      <td>城市</td><td>空气质量</td><td>操作</td>
    </tr>   
</table>
<div title="" ></div>
<script src="task4.js"></script>
</body>
js:
//按照自己的思路写的第一种
    function addAqiData() {
        var aqiTable=document.getElementById("aqi-table");
        var btn=document.getElementById("add-btn");
        btn.onclick=function(){
            //对获取的数据进行去空格处理
            var city=document.getElementById("aqi-city-input").value.trim();
            var value=document.getElementById("aqi-value-input").value.trim();
            //输入错误字符会提示并且退出函数
            if(!(/^[\u4e00-\u9fa5a-zA-Z]+$/.test(city))){
                alert("请输入中英文");
                return;
            }
            if (!(/^\d+$/.test(value))){
                alert("请输入数字");
                return;
            }
            //更新列表中的数据,并给每一个button添加删除函数
            var aqiList=document.getElementById("aqi-table").innerHTML;
                aqiList+="<tr><td>"+city+"</td><td>"+value+"</td><td><button>删除</button></td></tr>";
                aqiTable.innerHTML=aqiList;
                del();
        };
    }
    //创建删除函数
    function del(){
        var table=document.getElementById("aqi-table");
        var btns=table.getElementsByTagName('button');
        for(var i=0,len=btns.length;i<len;i++){
            btns[i].onclick=function(){
                //获取tr
                var child=this.parentNode.parentNode;
                //获取tbody,删除tr
            this.parentNode.parentNode.parentNode.removeChild(child);
            };
        }
    }
    //执行函数
    function init(){
        addAqiData();
        del();
    }
    init();

思路:这是我当时按自己思路写的,并没有按照题目给出的过程来写,现在看来,没有利用事件代理是这种方法的缺点.
首先获取text内的value,并且进行trim()去空格处理,再使用正则进行判断,城市名只能输入中英文,空气质量只能输入数字,最后将数据添加进列表中.因为这里没有使用事件代理,所以每进行一次渲染,都要添加一次del();
使用事件代理更正后如下:

function del(){
        var child=this.parentNode.parentNode;
        this.parentNode.parentNode.parentNode.removeChild(child);
    }
function delegate(){
        var table=document.getElementById("aqi-table");
        table.addEventListener('click',function(event){
            if (event.target.tagName.toLowerCase()=='button') {
                del.call(event.target);
            }
        },false);
    }

零基础JavaScript编码(五)
任务目的
在上一任务基础上继续JavaScript的体验
接触更加复杂的表单对象
实现页面上的一个完整交互功能
用DOM实现一个柱状图图表
任务描述
参考以下示例代码,原始数据包含几个城市的空气质量指数数据
用户可以选择查看不同的时间粒度,以选择要查看的空气质量指数是以天为粒度还是以周或月为粒度
天:显示每天的空气质量指数
周:以自然周(周一到周日)为粒度,统计一周7天的平均数为这一周的空气质量数值,如果数据中缺少一个自然周的几天,则按剩余天进行计算
月:以自然月为粒度,统一一个月所有天的平均数为这一个月的空气质量数值
用户可以通过select切换城市
通过在”aqi-chart-wrap”里添加DOM,来模拟一个柱状图图表,横轴是时间,纵轴是空气质量指数,参考图(点击打开)。天、周、月的数据只根据用户的选择显示一种。
天:每天的数据是一个很细的矩形
周:每周的数据是一个矩形
月:每周的数据是一个很粗的矩形
鼠标移动到柱状图的某个柱子时,用title属性提示这个柱子的具体日期和数据
代码如下:

html:
<body>
  <fieldset id="form-gra-time">
    <legend>请选择日期粒度:</legend>
    <label>日<input name="gra-time" value="day" type="radio" checked="checked"></label>
    <label>周<input name="gra-time" value="week" type="radio"></label>
    <label>月<input name="gra-time" value="month" type="radio"></label>
  </fieldset>
  <fieldset>
    <legend>请选择查看的城市:</legend>
    <select id="city-select">
      <option>北京</option>
    </select>
  </fieldset>
  <div class="aqi-chart-wrap">
  </div>
  <script src="task5.js"></script>
</body>
css:
.aqi-chart-wrap div{
        border: 1px solid white;
        flex: 1;
      }
      .aqi-chart-wrap{
        width: 98%;
        height: 500px;
        display: flex;
        justify-content: center;/*在主轴上对齐*/
        align-items: flex-end;/*在交叉轴上底部对齐*/
        align-content: center;
        margin: 10 auto;
        padding: 10px;
        border:2px solid #000;
        cursor: pointer;
      }
js:
  /* 数据格式演示
  var aqiSourceData = {
    "北京": {
      "2016-01-01": 10,
      "2016-01-02": 10,
      "2016-01-03": 10,
      "2016-01-04": 10
    }
  };
  */

  // 以下两个函数用于随机模拟生成测试数据
  function getDateStr(dat) {
    var y = dat.getFullYear();
    var m = dat.getMonth() + 1;
    m = m < 10 ? '0' + m : m;
    var d = dat.getDate();
    d = d < 10 ? '0' + d : d;
    return y + '-' + m + '-' + d;
  }
  function randomBuildData(seed) {
    var returnData = {};
    var dat = new Date("2016-01-01");
    var datStr = '';
    for (var i = 1; i < 92; i++) {
      datStr = getDateStr(dat);
      returnData[datStr] = Math.ceil(Math.random() * seed);
      dat.setDate(dat.getDate() + 1);
    }
    return returnData;
  }

  var aqiSourceData = {
    "北京": randomBuildData(500),
    "上海": randomBuildData(300),
    "广州": randomBuildData(200),
    "深圳": randomBuildData(100),
    "成都": randomBuildData(300),
    "西安": randomBuildData(500),
    "福州": randomBuildData(100),
    "厦门": randomBuildData(100),
    "沈阳": randomBuildData(500)
  };
  //跨浏览器事件监听
  function addEventListener(element,event,func){
    if (element.addEventListener) {
      element.addEventListener(event,func,false);
    }else{
      element.attachEvent(event,func);
    }
  }
  //设置全局变量
  var formGraTime=document.getElementById("form-gra-time");
  var citySelect=document.getElementById("city-select");
  var aqiChart=document.getElementsByClassName("aqi-chart-wrap")[0];
  // 用于渲染图表的数据
  var chartData = {};

  // 记录当前页面的表单选项
  var pageState = {
      nowSelectCity:"北京",
      nowGraTime: "day"
  };
  //取得颜色的第一种方法
  function getColor(){
    var colorArray=[0,1,2,3,4,5,6,7,8,9,"a","b","c","d","e","f"];
    var color="";
    for(var i=0;i<6;i++){
      color+=colorArray[Math.floor(Math.random()*16)];
    }
    color="#"+color;
    return color;
  }
  /**
   * 渲染图表
   */
  function renderChart() {
    var text="";
    for(var item in chartData){
        //取颜色的第二种方法
      // var color="#"+Math.floor(Math.random()*0xFFFFFF).toString(16);
       var color=getColor();
      text+='<div title="'+item+'空气质量指数:'+chartData[item]+'" style="height:'+chartData[item]+'px;background:'+color+'"></div>';
      // text += '<div title="'+item+":"+chartData[item]+'" style="height:'+chartData[item]+'px; background-color:'+color+'"></div>';
    }
    aqiChart.innerHTML=text;
  }
  /**
   * 日、周、月的radio事件点击时的处理函数
   */
  function graTimeChange() {
    // 确定是否选项发生了变化 
    // 设置对应数据
    // 调用图表渲染函数
    if (pageState.nowGraTime==this.value) {
      return;
    }else{
      pageState.nowGraTime=this.value;
    }
    initAqiChartData();
    renderChart();
  }
  /**
   * select发生变化时的处理函数
   */
  function citySelectChange() {
    // 确定是否选项发生了变化 
    if (pageState.nowSelectCity==this.value) {
      return;
    }else{
      pageState.nowSelectCity=this.value;
    }
    // 设置对应数据
    initAqiChartData();
    // 调用图表渲染函数
    renderChart();
  }
  /**
   * 初始化日、周、月的radio事件,当点击时,调用函数graTimeChange
   */
  function initGraTimeForm() {
    var graTime=formGraTime.getElementsByTagName('input');
    for(var i=0;i<graTime.length;i++){
      addEventListener(graTime[i],'click',graTimeChange);
    }
  }
  /**
   * 初始化城市Select下拉选择框中的选项
   */
  function initCitySelector() {
    // 读取aqiSourceData中的城市,然后设置id为city-select的下拉列表中的选项
    var cityOptions="";
    for(var item in aqiSourceData){
      cityOptions+="<option>"+item+"</option>";
    }
    citySelect.innerHTML=cityOptions;
    // 给select设置事件,当选项发生变化时调用函数citySelectChange
    addEventListener(citySelect,'change',citySelectChange);
  }
  /**
   * 初始化图表需要的数据格式
   */
  function initAqiChartData() {
    // 将原始的源数据处理成图表需要的数据格式
    // 处理好的数据存到 chartData 中
    var nowCityData=aqiSourceData[pageState.nowSelectCity],
        nowGraTime=pageState.nowGraTime;
    if (nowGraTime=="day") {
      chartData=nowCityData;
    }
    if (nowGraTime=='week') {
      chartData={};
      var day=0,sum=0,week=0;
      for(var item in nowCityData){
        day++;
        sum+=nowCityData[item];
        if (new Date(item).getDay()==6) {
          week++;
          chartData["第"+week+"周"]=Math.round(sum/7);
          sum=0;
          day=0;
        }
      }
      if(day!==0){
        week++;
        chartData["第"+week+"周"]=Math.round(sum/day);
      }
    }
    if (nowGraTime=='month') {
      chartData={};
      var month=0,sum=0,day=0;
      for(var item in nowCityData){
        sum+=nowCityData[item];
        day++;
        if (new Date(item).getMonth()!=month) {
          month++;
          chartData["第"+month+"月"]=Math.round(sum/day);
          day=0;
          sum=0;
        }
      }
      if (day!==0) {
        month++;
        chartData["第"+month+"月"]=Math.round(sum/day);
      }
    }
  }
  /**
   * 初始化函数
   */
  function init() {
    initGraTimeForm();
    initCitySelector();
    initAqiChartData();
    renderChart();
  }
  init();  

思路:刚开始看到这题目完全是一脸茫然啊,感觉无从下手,看了下别人的代码,好歹有了点思路.先说下总体的思路:主要是利用pageState对象存储当前页面的状态(是选择的日还是周,还有选择的城市),然后chartData对象用来存储数据.
initAqiChartData()这个函数也很关键,先判断当前选择的是哪个城市,取出这个城市的数据,然后再判断当前选择的日期,通过getDay()判断当前天是不是周日,用day来计算天数,如果是周日,则week++,day清零,计算这周的平均数。还要注意要考虑到最后一周不满7天的情况,可以通过day!=0来判断,这周的平均数,week也要计算出来.month的数据的计算过程和月份的差不多.最后将计算出的数据存入charData中.平均数记得要取整.
getColor()这种是我自己写的,比较复杂一点,另外一种很简洁:color=”#”+Math.floor(Math.random()*0xFFFFFF).toString(16).
还有这里的css也挺重要的,采用flex布局,.aqi-chart-wrap设置为display:flex,.aqi-chart-wrap div设置为flex=1; align-items: flex-end;为了使div在交叉轴沿底部对齐,justify-content: center;为了在主轴上对齐。

基础JavaScript练习(一)
任务目的
学习与实践JavaScript的基本语法、语言特性
初步了解JavaScript的事件是什么
初步了解JavaScript中的DOM是什么
任务描述
如图,模拟一个队列,队列的每个元素是一个数字,初始队列为空
有一个input输入框,以及4个操作按钮
点击”左侧入”,将input中输入的数字从左侧插入队列中;
点击”右侧入”,将input中输入的数字从右侧插入队列中;
点击”左侧出”,读取并删除队列左侧第一个元素,并弹窗显示元素中数值;
点击”右侧出”,读取并删除队列又侧第一个元素,并弹窗显示元素中数值;
点击队列中任何一个元素,则该元素会被从队列中删除
代码如下:

<script type="text/javascript">
    var arr=[];
    var strr="";
    var bottomNum=document.getElementById("bottom");
    var text=document.getElementById("text");
    function change() {
        var bt1=document.getElementById("bt1");
        var bt2=document.getElementById("bt2");
        var bt3=document.getElementById("bt3");
        var bt4=document.getElementById("bt4");
        bt1.addEventListener('click',function(){
            arr.unshift(text.value);
            arrChange();
        },false);
        bt2.addEventListener('click',function(){
            arr.push(text.value);
            arrChange();
        },false);
        bt3.addEventListener('click',function(){
            arr.shift(text.value);
            arrChange();
        },false);
        bt4.addEventListener('click',function(){
            arr.pop(text.value);
            arrChange();
        },false);
    }
    function arrChange(){
        for(var i=0;i<arr.length;i++){
                strr+='<div class="bottomDiv">'+arr[i]+'</div>';
            }
        bottomNum.innerHTML=strr;
        strr="";
    }
    function start(){
        text.addEventListener('blur',function(){
            if (!(/^\d+$/.test(text.value))) {
                alert("输入有误");
                return;
            }
        },false);
        change();
    }
    start();
</script>

思路:因为是模拟队列,所以这里我选择用数组存储数据,分别用了数组的:
pop():从数组的尾部移除最后一项.
push():在数组的尾部添加任意个项.
shitf():移除数组中的第一项.
unshift():在数组前端添加任意个项.

任务十九:基础JavaScript练习(二)
任务目的
学习与实践JavaScript的基本语法、语言特性
练习使用JavaScript实现简单的排序算法
任务描述
基于任务18
限制输入的数字在10-100
队列元素数量最多限制为60个,当超过60个时,添加元素时alert出提示
队列展现方式变化如图,直接用高度表示数字大小
实现一个简单的排序功能,如冒泡排序(不限制具体算法),用可视化的方法表达出来,
代码如下:

html:
<div id="container">
<div id="top">
    <input type="text" id="text">
    <button id="bt1">左侧入</button>   
    <button id="bt2">右侧入</button>
    <button id="bt3">左侧出</button>
    <button id="bt4">右侧出</button>
    <button id="bt5">重新排序</button>
    <button id="bt6">清空</button>
    <button id="bt7">随机生成</button>
</div>
<div id="bottom" ></div>
</div>
css:
<style type="text/css">
        *{
            margin: 0px;
            padding: 0px;
        }
        #container{
            width: 900px;
            margin: 0 auto;
            text-align: center;
        }
        #top{
            margin-left: 5px;
        }
        button{
            width: 80px;
            border-radius: 5px;
            margin: 5px;
        }
        #bt2{
            margin-right: 20px;
        }
        .bottomDiv{
            flex: 1;
            color:#FFF;
            margin:0 1px;
            font-size: 10px;
            background: red;
        }
        #bottom{
            width: 98%;
            height: 200px;
            display: flex;
            justify-content:center;
            align-items: flex-end;/*在交叉轴上底部对齐*/
            margin: 10 auto;
            padding: 10px;
        }
    </style>
js:
<script type="text/javascript">
    var arr=[];
    var strr="";
    var bottomNum=document.getElementById("bottom");
    var text=document.getElementById("text");
    var timer=null;
    function change() {
        var bt1=document.getElementById("bt1");
        var bt2=document.getElementById("bt2");
        var bt3=document.getElementById("bt3");
        var bt4=document.getElementById("bt4");
        var bt5=document.getElementById("bt5");
        var bt6=document.getElementById("bt6");
        var bt7=document.getElementById("bt7");
        bt1.addEventListener('click',function(){
            inputRule();
            arr.unshift(text.value);
            arrChange();
        },false);
        bt2.addEventListener('click',function(){
            inputRule();
            arr.push(text.value);
            arrChange();
        },false);
        bt3.addEventListener('click',function(){
            arr.shift(text.value);
            arrChange();
        },false);
        bt4.addEventListener('click',function(){
            arr.pop(text.value);
            arrChange();
        },false);
        bt5.addEventListener('click',function(){
            resort();
        },false);
        bt6.addEventListener('click',function(){
            clear();
        },false);
        bt7.addEventListener('click',function(){
            randomArr();
            arrChange();
        },false);
    }
    //确定input规则
    function inputRule(){
        tex=text.value.trim();
        if (tex>100||tex<10) {
            alert("请输入10-100的数");
            text.value="";
        }
        if (/[^\d]/.test(tex)) {
            alert("请输入10-100的数");
            text.value="";
        }
        if (arr.length>60) {
            alert("数组长度不能超过60");
            text.value="";
        }
    }
    //清空数组
    function clear(){
        clearInterval(timer);
        arr=[];
        arrChange();
    }
    //随机生成20个[10-100]的数
    function randomArr(){
        clear();
        for(var i=0;i<20;i++){
            arr.push(Math.floor(Math.random()*91+10));
        }
    }
    //渲染数组
    function arrChange(){
        if (arr.length) {
            for(var i=0;i<arr.length;i++){
                    strr+='<div class="bottomDiv" style="height:'+arr[i]+'px">'+arr[i]+'</div>';
                }
        }
        bottomNum.innerHTML=strr;
        strr="";
    }
    //冒泡排序
    function resort(){
        clearInterval(timer);
        var i=0,j=0,len=arr.length;
        timer=setInterval(function(){
            if (i<len-1) {
                if (j==len-1-i) {
                    j=0;
                    i++;
                }
                if (arr[j]>arr[j+1]) {
                    var x=0;
                    x=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=x;
                }
                j++;
            }                   
            arrChange();
            if (i==arr.length-1) {
                clearInterval(timer);
            }
        },50);
    }
    function start(){
        change();
    }
    start();
</script>

思路:因为要求要实现排序可视化,所以在渲染的时候将数组中的值设置为元素的高度,实现排序可视化的重点在设置setInterval(),然后就是冒泡排序了,虽然以前学java的时候学过,但是好久没接触java了,冒泡和选择排序我有点概念不清了,直接百度查了一下,ok,但是这里要实现可视化,感觉用for循环又不太好,所有用了if判断,比for循环复杂多了.做完觉得这个Demo好有趣!

任务二十:基础JavaScript练习(三)
任务目的
实践JavaScript数组、字符串相关操作
任务描述
基于任务18进行升级
将新元素输入框从input改为textarea
允许一次批量输入多个内容,格式可以为数字、中文、英文等,可以通过用回车,逗号(全角半角均可),顿号,空格(全角半角、Tab等均可)等符号作为不同内容的间隔
增加一个查询文本输入框,和一个查询按钮,当点击查询时,将查询词在各个元素内容中做模糊匹配,将匹配到的内容进行特殊标识,如文字颜色等。举例,内容中有abcd,查询词为ab或bc,则该内容需要标识
代码如下:

html:
<textarea id="textarea" rows="2" cols="20"></textarea>
<button id="bt1">确认</button>
<input type="text" id="input">
<button id="bt2">查询</button>
<button id="bt3">清除</button>
<button id="bt4">左侧入</button>   
<button id="bt5">右侧入</button>
<button id="bt6">左侧出</button>
<button id="bt7">右侧出</button>
<div id="container"></div>
css:
#container div{
    height: 50px;
    width: 40px;
    color: white;
    background: gray;
    float: left;
    margin-right: 10px;
}
span{
    background: red;
}
js:
<script type="text/javascript">
    var text=document.getElementById("textarea"),
        input=document.getElementById("input"),
        bt1=document.getElementById("bt1"),
        bt2=document.getElementById("bt2"),
        bt3=document.getElementById("bt3"),
        bt4=document.getElementById("bt4"),
        bt5=document.getElementById("bt5"),
        bt6=document.getElementById("bt6"),
        bt7=document.getElementById("bt7"),
        container=document.getElementById("container"),
        //数组用来存储输入的数据
        arr=[];
    //适用于确认按钮,使用DOM创建子节点
    function change() {
        var str=text.value.split(/[,\s+、,\r]/g);
        for(var i=0;i<str.length;i++){
            arr.push(str[i]);
        }
        for(var j=0;j<arr.length;j++){
            var div=document.createElement("div");
            div.innerHTML=arr[j];
            container.appendChild(div);
        }   
    }
    //适用于bt4,bt5,bt6,bt7 4个按钮,使用innerHTML来渲染内容
    function arrChange(){
        var str=arr.toString().split(/[,\s+、,\r]/);
        arr=[];
        for(var i=0;i<str.length;i++){
            arr.push(str[i]);
        }
        var strr="";
        for(var j=0;j<arr.length;j++){
                strr+='<div class="bottomDiv">'+arr[j]+'</div>';
            }
        container.innerHTML=strr;
        strr="";
    }
    //遍历divs里的内容,使用search()来查询是否符合input的条件
    function search(){
        var inp=input.value;
        var divs=container.getElementsByTagName("div");
        for(var i=0;i<divs.length;i++){
                var d=divs[i].innerHTML.replace(new RegExp(inp,"g"),"<span>"+inp+"</span>");
                divs[i].innerHTML=d;
        }   
    }
    //为每个按钮添加事件监听
    function event(){
        bt1.addEventListener('click',function(){
            change();
        },false);
        bt2.addEventListener('click',function(){
            search();
        },false);
        bt3.addEventListener('click',function(){
            clear();
        },false);
        bt4.addEventListener('click',function(){
            arr.unshift(text.value);
            arrChange();
        },false);
        bt5.addEventListener('click',function(){
            arr.push(text.value);
            arrChange();
        },false);
        bt6.addEventListener('click',function(){
            arr.shift(text.value);
            arrChange();
        },false);
        bt7.addEventListener('click',function(){
            arr.pop(text.value);
            arrChange();
        },false);
    }
    //清除container内的内容
    function clear(){
        arr=[];
        container.innerHTML="";
    }
    event();
</script>

思路:主要是注意2个问题:1个是将输入的内容用split()分离为数组。
第二个是search()内使用replace()替换掉与输入内容相同的值,给这个值加上span标签,这样就可以在css中设置background使查询到的内容凸显出来.

基础JavaScript练习(四)
任务目的
学习与实践JavaScript的基本语法、语言特性
练习使用JavaScript实现拖拽功能
任务描述
基于任务20,将任务20的代码进行抽象、封装,然后在此基础上实现如图中的两个需求:Tag输入和兴趣爱好输入
如示例图上方,实现一个tag输入框
要求遇到用户输入空格,逗号,回车时,都自动把当前输入的内容作为一个tag放在输入框下面。
Tag不能有重复的,遇到重复输入的Tag,自动忽视。
每个Tag请做trim处理
最多允许10个Tag,多于10个时,按照录入的先后顺序,把最前面的删掉
当鼠标悬停在tag上时,tag前增加删除二字,点击tag可删除
如示例图下方,实现一个兴趣爱好输入的功能
通过一个Textarea进行兴趣爱好的输入,可以通过用回车,逗号(全角半角均可),顿号,空格(全角半角、Tab等均可)等符号作为间隔。
当点击“确认兴趣爱好”的按钮时,将textarea中的输入按照你设定的间隔符,拆解成一个个的爱好,显示在textarea下方
爱好不能重复,所以在下方呈现前,需要做一个去重
每个爱好内容需要做trim处理
最多允许10个兴趣爱好,多于10个时,按照录入的先后顺序,把最前面的删掉
代码如下:

html:
<body>
    <label>Tag:<input type="text" id="tagText" size="30"></label>
    <div id="tagContainer"></div>
    <textarea id="textarea" rows="3" cols="30"></textarea>
    <button id="bt">确认兴趣爱好</button>
    <div id="intrist"></div>
</body>
js:
//查找id函数
function $(id){
    return document.getElementById(id);
}
var tagText=$("tagText"),
    tagContainer=$("tagContainer"),
    flag=true,
    textarea=$("textarea"),
    bt=$("bt"),
    intrist=$("intrist"),
    arr=[];

//为tagText添加事件监听
function tagInput() {
    tagText.addEventListener('focus',function(){
        this.style.boxShadow="0 0 4px #88C5FB ";
    },false);
    tagText.addEventListener('blur',function(){
        this.style.boxShadow=null;
    },false);
    tagText.addEventListener('keyup',function(event){
        create(event);
    },false);
}
//Tag输入,创建tagDiv
function create(event){
    var value=tagText.value.trim();
    flag=true;
    if (event.keyCode==13||event.keyCode==32||event.keyCode==188) {
        check.checkRepeat();
        check.numRule();
        if (flag){
            //去掉","
            var tagDiv=document.createElement("div");
            var last=value.charAt(value.length-1);
            if (last==",") {
                tagDiv.innerHTML=value.substring(0,value.length-1);
            }else{
                tagDiv.innerHTML=value;
            }
            tagDiv.addEventListener('mouseover',mouse.mousedel,false);
            tagDiv.addEventListener('click',mouse.clickdel,false);
            tagDiv.addEventListener('mouseout',mouse.mouseout,false);
            tagContainer.appendChild(tagDiv);
            tagText.value="";
        }
    }
}
var check={
    //检查重复,如果有重复flag=false;
    checkRepeat:function(){
        var tagDivs=tagContainer.getElementsByTagName("div");
        var value=tagText.value.trim();
        var last=value.charAt(value.length-1);
        if (last==",") {
            value=value.substring(0,value.length-1);
        }
        for(var i=0;i<tagDivs.length;i++){
            if(tagDivs[i].innerHTML===value) {
                tagText.value="";
                flag=false;
            }
        }
    },
    //检查是否超过了10个,超过则删除第一个
    numRule:function(){
    var tagDivs=tagContainer.getElementsByTagName("div");
    if (tagDivs.length>9) {
        tagContainer.removeChild(tagContainer.firstChild);
    }
}
};

var mouse={
    //鼠标滑过显示删除
    mousedel:function(){
        this.style.background="#FA0300";
        this.innerHTML="点击删除"+this.innerHTML;
    },
    //移出恢复
    mouseout:function(){
        this.style.background="#88C5FB";
        this.innerHTML=this.innerHTML.substring(4);
    },
    //点击删除
    clickdel:function(){
        this.parentNode.removeChild(this);
    }
};
//兴趣输入
function inputIntrist(){
    str=textarea.value.split(/[\s+\、\,\,\r]/);
    for(var i=0;i<str.length;i++){
        arr.push(str[i].trim());
    }
    arr=uniqArray(arr);
}
//给button添加点击事件
function buttonStart(){
    bt.addEventListener('click',creIntrist,false);
}
//渲染intrist 
function creIntrist(){
    inputIntrist();
    arrNumRule();
    var strr="";
    for(var i=0;i<arr.length;i++){
        strr+="<div>"+arr[i]+"</div>";
    }
    intrist.innerHTML=strr;
    strr="";
}
//当数组大于10时,移除前面的
function arrNumRule(){
    while(arr.length>10) {
        arr.shift();
    }
}
//数组去重
function uniqArray(arr){
    var ar=[];
    var hash={};
    for(var i=0;i<arr.length;i++){
        if (!hash[arr[i]]) {
            ar.push(arr[i]);
            hash[arr[i]]=true;
        }
    }
    return ar;
}
var start=function(){
    tagInput();
    buttonStart();
}();

思路:主要分两部分:Tag输入和兴趣输入,要分开考虑.
输入空格,逗号,回车时,都自动把当前输入的内容作为一个tag放在输入框下面。
这里要用到keyup事件,还要删除内容的空格和逗号。
Tag不能有重复的,遇到重复输入的Tag,自动忽视.
这里我设置了一个flag,如果检查到有重复的value,flag值变为false.
最多允许10个Tag,多于10个时,按照录入的先后顺序,把最前面的删掉
这里设置了numRule()检测节点数量,超过9个就移除第一个,然后将输入的添加进来.
当鼠标悬停在tag上时,tag前增加删除二字,点击tag可删除
给每个div添加mouseover和mouseout,onclick事件.
确认兴趣主要是去重,可以写一个数组去重函数.

表单(一)单个表单项的检验
任务描述
如示例图中所示,在页面中实现一个输入框与按钮,要求点击验证按钮后,对输入框中内容进行格式校验,并在其下方显示校验结果
校验规则:
1.字符数为4~16位
2.每个英文字母、数字、英文符号长度为1
3.每个汉字,中文符号长度为2
代码如下:

html:
<form id="container" >
        <div id="div1">
            <label>名称</label>
            <input type="text" id="text1">
            <input type="button" id="button1" value="验证"></input>
            <span id="span">必填,长度为4-16个字符</span>
        </div>
    </form>
js:
    function $(id){
            return document.getElementById(id);
        }
        var text1=$("text1"),
            bt1=$("button1"),
            div1=$("div1"),
            length=0,
            span=$("span");
        span.style.left=text1.offsetLeft+"px";
        //检验text1是否符合要求 
        function check1() {
            length=check();
            if (length===0) {
                text1.style.border="1px solid red";
                span.style.color="red";
                span.innerHTML="姓名不能为空";
            }else if ((length>0&&length<4)||(length>14)) {
                span.style.color="#bbb";
                span.innerHTML="必填,长度为4-16个字符";
            }else{
                span.innerHTML="名称格式正确";
                span.style.color="green";
                text1.style.border="1px solid green";
            }
        }
        //计算出text1中的字符数
        function check(){
            length=0;
            var value=text1.value;
            var pattern1=/[\u4e00-\u9fa5]/g;
            var pattern2=/\w/g;
            while(pattern1.exec(value)){
                length+=2;
            }
            while(pattern2.exec(value)){
                length++;
            }
            return length;
        }
        //添加事件监听
        bt1.addEventListener('click',check1,false);
    </script>

思路:主要考察的是表单验证的知识,题目要求的是4-16个字符,注意,是字符,所以,我这里选择了一个length来存储输入的字符长度,当检测到中文时,leng+2,当检测到其他时,length+1.其实这里可以设置两个不同的样式,通过控制className来修改元素的样式,但是我之前用的是DOM直接修改style,就这样吧.

表单(二)多个表单项的动态校验
任务目的
加强对JavaScript的掌握
熟悉常用表单处理逻辑
任务描述
如示例图中所示,基于上一个任务(任务29),在页面中添加多个表单
要求:
表单获得焦点时,下方显示表单填写规则
表单失去焦点时校验表单内容
校验结果正确时,表单边框显示绿色,并在下方显示验证通过的描述文字
校验结果错误时,表单边框显示红色,并在下方显示验证错误的描述文字
点击提交按钮时,对页面中所有输入进行校验,校验结果显示方式同上。若所有表单校验通过,弹窗显示“提交成功”,否则显示“提交失败”
代码

<form method="post" action="">
        <table>
            <tr>
                <td><label for="text1">名称</label><input type="text" name="name" id="text1"></td>
                <td class="span">
                    <span id="span1"></span>
                </td>
            </tr>
            <tr>
                <td><label for="text2">密码</label><input type="password" name="password" id="text2"></td>
                <td class="span">
                    <span id="span2"></span>
                </td>
            </tr>
            <tr>
                <td><label for="text3" id="confirm">密码确认</label><input type="password" name="confirm" id="text3"></td>
                <td class="span">
                    <span id="span3"></span>
                </td>
            </tr>
            <tr>
                <td><label for="text4">邮箱</label><input type="text" name="adress" id="text4"></td>
                <td class="span">
                    <span id="span4"></span>
                </td>
            </tr>
            <tr>
                <td><label for="text5">手机</label><input type="text" name="phonenumber" id="text5"></td>
                <td class="span">   
                    <span id="span5"></span>
                </td>
            </tr>
        </table>
        <input type="submit" name="submit" value="提交" id="submit">
    </form>
js:
function $(id) {
    return document.getElementById(id);
}
var span1=$("span1"),
    span2=$("span2"),
    span3=$("span3"),
    span4=$("span4"),
    span5=$("span5"),
    text1=$("text1"),
    text2=$("text2"),
    text3=$("text3"),
    text4=$("text4"),
    text5=$("text5"),
    submit=$("submit"),
    length=0,
    flag=false;
function addEvent(elment,type,func){
    if (elment.addEventListener) {
        elment.addEventListener(type,func,false);
    }else{
        elment.attachEvent("on"+type,func,false);
    }
}
//获得焦点时的渲染
function focu(event,span,innerHTML){
    span.innerHTML=innerHTML;
    event.target.style.boxShadow="0 0 4px #88C5FB ";
    event.target.style.border="1px solid #2F79BA";
}
//失去焦点,输入正确时的渲染
function right(span){
    that.style.border="1px solid #63B775";
    span.style.color="#63B775";
    that.style.boxShadow="";
    flag=true;
}
//失去焦点,输入错误时的渲染
function wrong(span){
    that.style.border="1px solid #E3000C";
    that.style.boxShadow="";
    span.style.color="#E3000C";
    flag=false;
}
//计算字符长度
function countLength(){
    length=0;
    var value=text1.value;
    var pattern1=/[\u4e00-\u9fa5]/g;
    var pattern2=/\w/g;
    while(pattern1.exec(value)){
        length+=2;
    }
    while(pattern2.exec(value)){
        length+=1;
    }
    return length;
}
/*
*text1失去焦点时
*调用countLength计算出length,根据length判断采用哪种渲染
*/
function nameBlur(){
    that=this;
    length=countLength();
    if (length===0) {
        span1.innerHTML="名称不能为空";
        wrong(span1);
    }
    else if (length<4||length>16) {
        span1.innerHTML="长度为4~16个字符";
        wrong(span1);
    }else{
        span1.innerHTML="名称格式正确";
        right(span1);
    }
}
//text2失去焦点
function passwordBlur(){
    that=this;
    var pattern=/[0-9a-zA-Z]{6,12}/g;
    var value=text2.value;
    if (pattern.exec(value)) {
        span2.innerHTML="密码可用";
        right(span2);
    }else{
        wrong(span2);
    }
}
//text3失去焦点
function passWordConfirm(){
    that=this;
    var value=text2.value;
    if (text3.value===value&&(text3.value!=="")) {
        span3.innerHTML="密码输入一致";
        right(span3);
    }else if(text3.value===value){
        span3.innerHTML="密码不能为空";
        wrong(span3);
    }
    else{
        span3.innerHTML="密码输入不一致";
        wrong(span3);
    }
}
//text4失去焦点
function addressBlur() {
    that=this;
    var pattern=/\w+@\w+\.com/g;
    if (pattern.exec(text4.value)) {
        span4.innerHTML="邮箱格式正确";
        right(span4);
    }else{
        span4.innerHTML="邮箱格式错误";
        wrong(span4);
    }
}
//text5失去焦点
function numberBlur(){
    that=this;
    var pattern=/1\d{10}/g;
    if (pattern.exec(text5.value)) {
        span5.innerHTML="手机格式正确";
        right(span5);
    }else{
        span5.innerHTML="手机格式错误";
        wrong(span5);
    }
}
//添加监听事件
function start(){
    addEvent(text1,'focus',function(event){
        focu(event,span1,"必填,长度为4~16个字符");
    });
    addEvent(text2,'focus',function(event){
        focu(event,span2,"请输入6~12位密码(数字、英文或下划线)");
    });
    addEvent(text3,'focus',function(event){
        focu(event,span3,"请再次输入密码");
    });
    addEvent(text4,'focus',function(event){
        focu(event,span4,"请输入正确的邮箱");
    });
    addEvent(text5,'focus',function(event){
        focu(event,span5,"请输入正确的手机号");
    });
    addEvent(text1,'blur',nameBlur);    
    addEvent(text2,'blur',passwordBlur);
    addEvent(text3,'blur',passWordConfirm);
    addEvent(text4,'blur',addressBlur);
    addEvent(text5,'blur',numberBlur);
    addEvent(submit,'click',function(){
        if (flag===false) {
            alert("输入有误");
        }
    });
}
start();

思路:布局采用的是表格布局,因为这里有5个输入框,并且每个输入框的要求都不一样,所以每个输入框都要写一个验证函数,验证函数要添加到blur事件中,还要写一个right()和wrong(),当发生错误时,样式应该如何变化,还有每个输入框获得焦点时样式的渲染,要定义一个全局变量flag,在wrong()函数中令flag=false,这样在提交表单时就可以知道表单输入是否正确.

表单(三)联动
加强对JavaScript的掌握
熟悉常用表单处理逻辑
任务描述
如示例图中所示,在页面中完成两个单选框,切换单选框的不同选项时下方显示的表单随之切换。
当选择在校生时,出现两个select下拉菜单,一个选择城市,一个选择学校,当选择非在校生时,出一个文本输入框
学校下拉菜单里的学校名单均为城市下拉菜单中所选的城市中的大学,当城市发生变化时,学校一起发生变化
城市及学校的数据随意编造即可,无需真实完整

<form method="post" action="" id="form">
    <div id="top">
        <input type="radio" name="student" checked="checked" id="inSchool"><label>在校生</label>
        <input type="radio" name="student" id="outSchool"><label>非在校生</label>
        </div>
        <div id="bottom">
        <div id="left">
            <label>学校</label>
            <select id="selection">
                <option>北京</option>
                <option>上海</option>
                <option>武汉</option>
                <option>南京</option>
            </select>
        </div>
        <div id="right">
            <select id="schoolSelect">
                <option>北京大学</option>
                <option>清华大学</option>
                <option>人民大学</option>
                <option>北京邮电大学</option>
            </select>
        </div>
        </div>
        <div id="employer" class="hidden">
            <label><span>就业单位</span><input type="text"></label>
        </div>
    </form> 
<script type="text/javascript">
        function $(id) {
            return document.getElementById(id);
        }
        var inSchool=$("inSchool"),
            outSchool=$("outSchool"),
            bottom=$("bottom"),
            employer=$("employer"),
            citySelect=$("selection"),
            schoolSelect=$("schoolSelect");
        function addEvent(elment,type,func){
            if (elment.addEventListener) {
                elment.addEventListener(type,func,false);
            }else{
                elment.attachEvent(type,func);
            }
        }
        //给2个单选按钮和选择框添加事件监听
        function radioEvent(){
            addEvent(inSchool,'click',function(){
                bottom.className="display";
                employer.className="hidden";
            });
            addEvent(outSchool,'click',function(){
                bottom.className="hidden";
                employer.className="display";
            });
            addEvent(citySelect,'change',selectEvent);
        }
        //用data对象来存储学校数据
        var data={
            北京:["北京大学","清华大学","人民大学","北京航空航天大学"],
            上海:["复旦大学", "上海交通大学", "同济大学","上海财经大学"],
            武汉:["武汉大学","华中科技大学","中南财经大学","武汉理工大学"],
            南京:["南京大学","南京理工大学","南京航空航天大学","东南大学"]
        };
        //选择框改变事件
        function selectEvent(){
            var seletOption=citySelect.options[citySelect.selectedIndex];
            value=seletOption.value;
            schoolSelect.innerHTML="";
            for(var i=0;i<data[value].length;i++){
                var option=document.createElement("option");
                option.innerHTML=data[value][i];
                schoolSelect.appendChild(option);
            }
        }
        function start(){
            radioEvent();
        }
        start();
    </script>

思路:表单联动这个题目主要考察的是选择框脚本,select和option.考察了select的change事件,访问选中项的方式:varselectedOption=selectbox.options[selectbox.selectedIndex].
value如果在html中指定了则value等于指定的值,如果未指定,则等于该项的文本.

听指令的小方块(一)
任务目的
练习JavaScript在DOM、字符串处理相关知识
练习对于复杂UI,如何进行数据机构建模
任务描述
如图,实现一个类似棋盘的格子空间,每个格子用两个数字可以定位,一个红正方形的DOM在这个空间内,正方形中的蓝色边表示这是他的正面,有一个input输入框
在输入框中允许输入如下指令,按下按钮后,使得正方形做相应动作
GO:向蓝色边所面向的方向前进一格(一格等同于正方形的边长)
TUN LEF:向左转(逆时针旋转90度)
TUN RIG:向右转(顺时针旋转90度)
TUN BAC:向右转(旋转180度)
移动不能超出格子空间
代码:

<style type="text/css">
        *{
            margin: 0px;
            padding: 0px;
            font-family: "Microsoft Yahei";
            font-size: 20px;
        }
        table{
            position: relative;
            border-collapse: collapse;
        }
        td{
            width: 50px;
            height: 50px;
            border-right: 1px solid #eee;
            border-bottom: 1px solid #eee;
            text-align: center;
        }
        .background td:first-child{
            border-right: 2px solid #000;
            border-bottom: 0;
        }
        .background td:last-child{
            border-right: 2px solid #000;
        }
        .background tr:first-child td{
            border-right: 0;
            border-bottom: 2px solid #000;
        }
        .background tr:last-child td{
            border-bottom: 2px solid #000;
        }
        .background tr:first-child td:first-child{
            border-bottom: 0;
        }
        .background tr:last-child td:first-child{
            border-bottom: 0;
        }
        #square{
            top: 205px;
            left: 205px;
            position: absolute;
            width: 50px;
            height: 50px;
            background: #f00;
        }
        #square div{
            position: absolute;
            width: 50px;
            height: 10px;
            background: #00f;
        }
        input{
            width: 180px;
        }
        #bottom{
            margin-left: 50px;
        }
    </style>
html:
<body>
    <div class="container">
        <table>
            <tbody id="background" class="background">
                <div id="square">
                    <div></div>
                </div>
            </tbody>
        </table>
        <div id="bottom">
            <input type="text" id="text">
            <button id="bt1">执行</button>
            <button id="left">向左转</button>
            <button id="right">向右转</button>
            <button id="go">向前</button>
            <button id="back">掉头</button>
        </div>
    </div>
    <script src="task13.js">

    </script>
</body>
js:
function $(id) {
    return document.getElementById(id);
}
function addEvent(elment, type, func){
    if (elment.addEventListener) {
        elment.addEventListener(type,func,false);
    }else if (elment.attachEvent) {
        elment.attachEvent("on"+type,func);
    }else{
        elment["on"+type]=func;
    }
}
var bg=$("background"),
    square=$("square"),
    text=$("text"),
    bt1=$("bt1"),
    left=$("left"),
    right=$("right"),
    forward=$("go"),
    back=$("back");
//渲染列表
(function createTable(){
    for(var i=0;i<11;i++){
        var bg_tr=[];
        bg_tr[i]=document.createElement("tr");
        for(var j=0;j<11;j++){
            var bg_td=[];
            bg_td[j]=document.createElement("td");
            if (i===0&&j>0) {
                bg_td[j].innerHTML=j;
            }
            if (j===0&&i>0) {
                bg_td[j].innerHTML=i;                   
            }
            bg_tr[i].appendChild(bg_td[j]);
        }
        bg.appendChild(bg_tr[i]);
    }
})();
//存储小方块位置
var pos={
    x:4,
    y:4,
    face:0//face为0时,为初始值,正面朝上,face+1,则向右转90°
};
//前进一格
function go(){
    var face_=pos.face;
    face_=face_%4+(face_%4<0?4:0);
    if (face_===0&&pos.y>0) {//正面朝上
        pos.y--;
    }
    else if (face_===1&&pos.x<9) {//正面朝右
        pos.x++;
    }else if (face_===2&&pos.y<9) {//正面朝下
        pos.y++;
    }else if (face_===3&&pos.x>0) {//正面朝左
        pos.x--;
    }else{
        return false;
    }
}
//向左转90°
function turnLeft(){
    pos.face--;
}
//向右转90°
function turnRight(){
    pos.face++;
}
//向右转180°
function turnback(){
    pos.face+=2;
}
//小方块的移动渲染
function change(){
    pos.face=pos.face%4+(pos.face%4<0?4:0);
    square.style.left=pos.x*51+52+"px";
    square.style.top=pos.y*51+52+"px";
    square.style.transform=square.style.webkitTransform=square.style.msTransform="rotate("+pos.face*90+"deg)";
}
//事件监听程序
function event(){
    if (text.value.toLowerCase()==="go") {
        go();
        change();
    }
    if (text.value.toLowerCase()==="tunlef") {
        turnLeft();
        change();
    }
    if (text.value.toLowerCase()==="tunrig") {
        turnRight();
        change();
    }
    if (text.value.toLowerCase()==="tunbag") {
        turnback();
        change();
    }
}
//给按钮添加事件监听
function buttonEvent(){
    addEvent(left,'click',function(){
        turnLeft();
        change();
    });
    addEvent(right,'click',function(){
        turnRight();
        change();
    });
    addEvent(forward,'click',function(){
        go();
        change();
    });
    addEvent(back,'click',function(){
        turnback();
        change();
    });
}
(function start(){
    change();
    buttonEvent();
    addEvent(bt1,'click',event);
})();

思路:首先用createTable()创建一个11x11表格,消除最上面一行和最左边一行的边界,用pos对象存储小方块的位置,x,y代表横纵坐标,face代表方向.go()表示前进一格,要根据小方块的方向分情况考虑,还要考虑小方块不能超出边界。向右向左转这里用了transform属性.这里的face方向确定我是用了别人的方法,对4进行取余.pos.face=pos.face%4+(pos.face%4<0?4:0);但是感觉还是有点不好,在后面的任务2和任务3就有点bug了,但是我也不会更好的方法了.

听指令的小方块(二)
任务目的
练习JavaScript在DOM、字符串处理相关知识
练习对于复杂UI,如何进行数据机构建模
任务描述
对于正方形的移动增加相应动画,包括移动和旋转
每个指令的执行时间是1s(可以自己调整)
增加新的指令如下:
TRA LEF:向屏幕的左侧移动一格,方向不变
TRA TOP:向屏幕的上面移动一格,方向不变
TRA RIG:向屏幕的右侧移动一格,方向不变
TRA BOT:向屏幕的下面移动一格,方向不变
MOV LEF:方向转向屏幕左侧,并向屏幕的左侧移动一格
MOV TOP:方向转向屏幕上面,向屏幕的上面移动一格
MOV RIG:方向转向屏幕右侧,向屏幕的右侧移动一格
MOV BOT:方向转向屏幕下面,向屏幕的下面移动一格
代码如下:

function $(id) {
    return document.getElementById(id);
}
function addEvent(elment, type, func){
    if (elment.addEventListener) {
        elment.addEventListener(type,func,false);
    }else if (elment.attachEvent) {
        elment.attachEvent("on"+type,func);
    }else{
        elment["on"+type]=func;
    }
}
var bg=$("background"),
    square=$("square"),
    text=$("text"),
    bt1=$("bt1"),
    left=$("left"),
    right=$("right"),
    forward=$("go"),
    back=$("back");
//渲染列表
(function createTable(){
    for(var i=0;i<11;i++){
        var bg_tr=[];
        bg_tr[i]=document.createElement("tr");
        for(var j=0;j<11;j++){
            var bg_td=[];
            bg_td[j]=document.createElement("td");
            if (i===0&&j>0) {
                bg_td[j].innerHTML=j;
            }
            if (j===0&&i>0) {
                bg_td[j].innerHTML=i;                   
            }
            bg_tr[i].appendChild(bg_td[j]);
        }
        bg.appendChild(bg_tr[i]);
    }
})();
//存储小方块位置
var pos={
    x:4,
    y:4,
    face:0//face为0时,为初始值,正面朝上,face+1,则向右转90°
};
//前进一格
function go(){
    var face_=pos.face;
    face_=face_%4+(face_%4<0?4:0);
    if (face_===0&&pos.y>0) {//正面朝上
        pos.y--;
    }
    else if (face_===1&&pos.x<9) {//正面朝右
        pos.x++;
    }else if (face_===2&&pos.y<9) {//正面朝下
        pos.y++;
    }else if (face_===3&&pos.x>0) {//正面朝左
        pos.x--;
    }else{
        return false;
    }
}
//向屏幕的左侧移动一格,方向不变
function tralef(){
    if (pos.x>0) {
        pos.x--;
    }
}
//向屏幕的上面移动一格,方向不变
function tratop(){
    if (pos.y>0) {
        pos.y--;
    }
}
//向屏幕的右侧移动一格,方向不变
function trarig(){
    if (pos.x<9) {
        pos.x++;
    }
}
//向屏幕的下面移动一格,方向不变
function trabot(){
    if (pos.y<9) {
        pos.y++;
    }
}
/*
*MOV LEF:方向转向屏幕左侧,并向屏幕的左侧移动一格
*MOV TOP:方向转向屏幕上面,向屏幕的上面移动一格
*MOV RIG:方向转向屏幕右侧,向屏幕的右侧移动一格
*MOV BOT:方向转向屏幕下面,向屏幕的下面移动一格
*/
function movlef(){
    pos.face=3;
    tralef();
}
function movtop(){
    pos.face=0;
    tratop();
}
function movrig(){
    pos.face=1;
    trarig();
}
function movbot(){
    pos.face=2;
    trabot();
}
//向左转90°
function turnLeft(){
    pos.face--;
}
//向右转90°
function turnRight(){
    pos.face++;
}
//向右转180°
function turnback(){
    pos.face+=2;
}
//小方块的移动渲染
function change(){
        pos.face=pos.face%4+(pos.face%4<0?4:0);
        square.style.left=pos.x*51+52+"px";
        square.style.top=pos.y*51+52+"px";
        square.style.transform="rotate("+pos.face*90+"deg)";
}
//判断text的值
function valueConfirm(value,func){
    if (text.value.toLowerCase()===value) {
        func();
        change();
    }
}
//事件监听程序
function event(){
    valueConfirm("tunbag",turnback);
    valueConfirm("tunrig",turnRight);
    valueConfirm("tunlef",turnLeft);
    valueConfirm("go",go);
    valueConfirm("tralef",tralef);
    valueConfirm("tratop",tratop);
    valueConfirm("trarig",trarig);
    valueConfirm("trabot",trabot);
    valueConfirm("movlef",movlef);
    valueConfirm("movtop",movtop);
    valueConfirm("movrig",movrig);
    valueConfirm("movbot",movbot);
}
//给按钮添加事件监听
function buttonEvent(){
    addEvent(left,'click',function(){
        turnLeft();
        change();
    });
    addEvent(right,'click',function(){
        turnRight();
        change();
    });
    addEvent(forward,'click',function(){
        go();
        change();
    });
    addEvent(back,'click',function(){
        turnback();
        change();
    });
}
(function start(){
    change();
    buttonEvent();
    addEvent(bt1,'click',event);
})();

思路:增加了几个函数,因为要求方向不变,所以只需要更改x,y的坐标就可以了.
因为要添加动画,所以需要在css中给小方块添加transition属性,一般只要写上transition-property,transition-duration就可以了,这里设置为all 2s.
听指令的小方块(三)
任务目的
练习JavaScript在DOM、字符串处理相关知识
练习对于复杂UI,如何进行数据机构建模
任务描述
如图,命令输入框由input变为textarea,可以允许输入多条指令,每一行一条
textarea左侧有一列可以显示当前行数的列(代码行数列),列数保持和textarea中一致
当textarea发生上下滚动时,代码行数列同步滚动
能够判断指令是否合法,不合法的指令给出提示(如图)
点击执行时,依次逐条执行所有命令
对于GO,TRA以及MOV指令增加可以移动格子数量的参数,例如
GO 3:向当前方向前进三格
TRA TOP 2:向屏幕上方平移两格
MOV RIG 4:方向转向屏幕右侧,向屏幕的右侧移动四格
代码如下:

function $(id) {
    return document.getElementById(id);
}
function addEvent(elment, type, func){
    if (elment.addEventListener) {
        elment.addEventListener(type,func,false);
    }else if (elment.attachEvent) {
        elment.attachEvent("on"+type,func);
    }else{
        elment["on"+type]=func;
    }
}
var bg=$("background"),
    square=$("square"),
    text=$("panel"),
    bt1=$("bt1"),
    bt2=$("bt2"),
    leftDiv=$("leftDiv");
//渲染列表
(function createTable(){
    for(var i=0;i<11;i++){
        var bg_tr=[];
        bg_tr[i]=document.createElement("tr");
        for(var j=0;j<11;j++){
            var bg_td=[];
            bg_td[j]=document.createElement("td");
            if (i===0&&j>0) {
                bg_td[j].innerHTML=j;
            }
            if (j===0&&i>0) {
                bg_td[j].innerHTML=i;                   
            }
            bg_tr[i].appendChild(bg_td[j]);
        }
        bg.appendChild(bg_tr[i]);
    }
})();
//存储小方块位置
var pos={
    x:4,
    y:4,
    face:0//face为0时,为初始值,正面朝上,face+1,则向右转90°
};
//前进一格
function go(){
    var face_=pos.face;
    face_=face_%4+(face_%4<0?4:0);
    if (face_===0&&pos.y>0) {//正面朝上
        pos.y--;
    }
    else if (face_===1&&pos.x<9) {//正面朝右
        pos.x++;
    }else if (face_===2&&pos.y<9) {//正面朝下
        pos.y++;
    }else if (face_===3&&pos.x>0) {//正面朝左
        pos.x--;
    }else{
        return false;
    }
}
//向屏幕的左侧移动一格,方向不变
function tralef(){
    if (pos.x>0) {
        pos.x--;
    }
}
//向屏幕的上面移动一格,方向不变
function tratop(){
    if (pos.y>0) {
        pos.y--;
    }
}
//向屏幕的右侧移动一格,方向不变
function trarig(){
    if (pos.x<9) {
        pos.x++;
    }
}
//向屏幕的下面移动一格,方向不变
function trabot(){
    if (pos.y<9) {
        pos.y++;
    }
}
/*
*MOV LEF:方向转向屏幕左侧,并向屏幕的左侧移动一格
*MOV TOP:方向转向屏幕上面,向屏幕的上面移动一格
*MOV RIG:方向转向屏幕右侧,向屏幕的右侧移动一格
*MOV BOT:方向转向屏幕下面,向屏幕的下面移动一格
*/
function movlef(){
    pos.face=3;
    tralef();
}
function movtop(){
    pos.face=0;
    tratop();
}
function movrig(){
    pos.face=1;
    trarig();
}
function movbot(){
    pos.face=2;
    trabot();
}
//向左转90°
function tunlef(){
    pos.face--;
}
//向右转90°
function tunrig(){
    pos.face++;
}
//向右转180°
function tunbag(){
    pos.face+=2;
}
//小方块的移动渲染
function change(){
        pos.face=pos.face%4+(pos.face%4<0?4:0);
        square.style.left=pos.x*51+52+"px";
        square.style.top=pos.y*51+52+"px";
        square.style.transform="rotate("+pos.face*90+"deg)";
}
function firstrows(){
    if (leftDiv.innerHTML==="") {
        var rowsdiv=document.createElement("div");
        rowsdiv.innerHTML="<div>"+(1)+"</div>";
        leftDiv.appendChild(rowsdiv);
    }
}
var i=1;
function rowsConfirm(event){
    if (event.keyCode==13) {
        var rowsdiv=document.createElement("div");
        rowsdiv.innerHTML="<div>"+(++i)+"</div>";
        leftDiv.appendChild(rowsdiv);
    }
}
function check(){
    var value=panel.value,
        arr=[],
        str="",
        i=0;
        arr=value.split("\n");
    var rows=arr.length;
    console.log(arr);
    var timer=setInterval(function(){
        if (i<rows) {
            var index=i;
            col(arr[i],index);
            i++;
        }else if (i==rows) {
            clearInterval(timer);
        }
    },500);
}
function col(arr,index){
    var colArr=arr.split(" ");
    var lastWord=colArr[colArr.length-1];
    if (/\d+/.test(lastWord)) {
        colArr.pop();
        var colValue=colArr.join("").toLowerCase();
        valueConfirm(colValue,lastWord,index);
    }else{
        var colValue=colArr.join("").toLowerCase();
        valueConfirm(colValue,1,index);
    }
}
//判断text的值
function valueConfirm(value,num,index){
    var divs=leftDiv.getElementsByTagName("div");
    for(var i=0;i<num;i++){
        switch(value){
            case "go":
                go();
                change();
                break;
            case "tralef":
                tralef();
                change();
                break;
            case "trarig":
                trarig();
                change();
                break;
            case "tratop":
                trarig();
                change();
                break;
            case "trabot":
                trabot();
                change();
                break;
            case "tunrig":
                tunrig();
                change();
                break;
            case "tunbag":
                trarig();
                change();
                break;
            case "tunlef":
                trarig();
                change();
                break;
            case "movbot":
                movbot();
                change();
                break;
            case "movlef":
                movlef();
                change();
                break;
            case "movrig":
                movrig();
                change();
                break;
            case "movtop":
                movtop();
                change();
                break;
            default:
                divs[index].style.background="red";
        }
    }
}
function event(){
    addEvent(panel,'keyup',function(event){
        event=event;
        rowsConfirm(event);
    });
    addEvent(panel,'focus',firstrows);
    addEvent(bt1,'click',check);
    addEvent(bt2,'click',function(){
        leftDiv.innerHTML="";
        panel.value=null;
    });
}
//事件监听程序
(function start(){
    change();
    event();
})();

思路:这个demo我写的bug太多了,只能说实现了基本的功能,我说一下整体的思路:因为要实现多条命令,每行一条,所以可以使用split(/\n/)将命令分割,因为每条命令又必须按顺序执行,所以要设置一个setInterval(),每一行的命令可能又执行多次,再将每行命令按照空格split,提取出lastWrod,根据lastWord是否为数字进行判断,如果为数字则进行多次循环,如果不是则循环1次.但是左边的代码行数我实在是控制不好,而且也做不到滚动.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值