2012 騰訊校招Web前端筆試的一道題,很值得懷念。。。

      2011 年10月15日,我參加了北京地區騰訊校招Web 前端的筆試,關於前端的題只用兩道題,其他爲基礎題,可就是這兩道題就足足花了我將近兩個小時,以致最終其他基礎題目我一道未答,雖然題目並不是很難,但確實其中有一道題的確令人懷念,究其原因,就是自己學藝不精,雖然筆試結束後我把這道題完成了,但裏面的陷阱之多非筆試時所能想到。現在騰訊的校招基本業已結束,這道題也可大膽的公佈在日誌中了,另外本人技術有限,希望各位JS高手多多指教。(因爲只有ie6 ,所以兼容性沒有測試)

題目如下:

1. 雙擊學號*, 高數*, 英語*可按照相應列進行正序排序,再次雙擊進行逆序排序;

2. 單擊任意數據行改變背景色爲灰色,再次單擊同一行回覆原來背景色白色;

3. 在選中某一數據行爲灰色情況下,敲擊鍵盤A鍵使得數據行下滑一行,同時背景下調;

4. 在選中某一數據行爲灰色情況下,敲擊鍵盤Z鍵使得數據行上升一行,同時背景上升;

 

     筆試的時候,剛看了一問,以爲很簡單,就直接下手開寫,誰成想接下的幾問越寫越複雜,只能將前問構架推翻重寫,基本上是寫了又劃,劃了又寫,代價慘痛不已。本人自問歷經多場筆試,早已成竹於胸,亦未出現如此狼狽。真應該審題仔細後再下筆。


<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<title>表格排序</title>
		 <style type="text/css">
		  table th, table tr
		  {
		   cursor: pointer;
		  }
		  .currentStyle
		  {
		   background: #ccc;
		  }
		 </style>
	</head>

	<body>
		<table border="1" cellspacing="0">
		  <tr>
		   <th>姓名</th>
		   <th class="sortedTable_th">學號 * </th>
		   <th class="sortedTable_th">高數 * </th>
		   <th class="sortedTable_th">英語 * </th>
		  </tr>
		  <tr class="sortedTable_tr">
		   <td>張三</td>
		   <td>20091234</td>
		   <td>88</td>
		   <td>99</td>
		  </tr>
		  <tr class="sortedTable_tr">
		   <td>李四</td>
		   <td>20092345</td>
		   <td>85</td>
		   <td>92</td>
		  </tr>
		  <tr class="sortedTable_tr">
		   <td>王二</td>
		   <td>20094567</td>
		   <td>79</td>
		   <td>100</td>
		  </tr>
		 </table>
		 <script type="text/javascript">
		 	 // 組件方法
			 var GLOBAL = {};
			 GLOBAL.DOM = {};
			 // 1. getElementsByClassName
			 GLOBAL.DOM.getElementsByClassName = function(str, root, tag){
			  root = root || document;
			  tag = tag || "*";
			  var results =[];
			  var elements = root.getElementsByTagName(tag);
			  for(var i = 0, len = elements.length; i < len; i++)
			  {
			   for(var j = 0, classNames = elements[i].className.split(" "), len2 = classNames.length; j < len2; j++)
			   {
			    if(str == classNames[j])
			    {
			     results.push(elements[i]);
			     break;
			    }
			   }
			  }
			  return results;
			 }
			 // 2. addClass 
			 GLOBAL.DOM.addClass = function(node, str)
			 {
			  var temp = node.className;
			  if(!new RegExp("(\\s)*" + str).test(temp))
			  {
			   node.className = temp + " " + str;
			  }
			 }
			 // 3. removeClass
			 GLOBAL.DOM.removeClass =function(node, str)
			 {
			  node.className = node.className.replace(new RegExp("(\\s)*" + str),"");
			 }
			 function SortedTable()
			 {
			  // 類sortedTable 的私有數據
			  var sortedTable_ths = GLOBAL.DOM.getElementsByClassName("sortedTable_th");
			  var sortedTable_trs =GLOBAL.DOM.getElementsByClassName("sortedTable_tr");
			  var results = [];
			  //  類sortedTable 的內部類,用於表示表格數據項
			  function Data(name,stuNo,math,english)
			  {
			   this.name = name;
			   this.stuNo = stuNo;
			   this.math = math;
			   this.english = english;
			   this.getPropertyNameByIndex = function(i)
			   {
			    var propertyName = null;
			    switch(i)
			    {
			     case 1 : propertyName = "stuNo"; break;
			     case 2 : propertyName = "math"; break;
			     case 3 : propertyName = "english"; break;
			    }
			    return propertyName;
			   }
			  }
			  // 表格數據項的排序方法
			  function compare(propertyName, flag)
			  {
			   return function(obj1, obj2)
			   {
			    var value1 = obj1[propertyName];
			    var value2 = obj2[propertyName];
			    // 正序
			    if(flag == 1)
			     return value1 - value2;
			    // 逆序
			    else if(flag == 2)
			     return value2 - value1;
			   }
			  }
			  // 排序或滑動後重置表格數據
			  function setTableContent(results)
			  {
			   var sortedTable_tds = null;
			   for(var i=0,len=results.length; i < len; i++)
			   {
			    sortedTable_tds = sortedTable_trs[i].cells;
			    sortedTable_tds[0].innerHTML = results[i].name;
			    sortedTable_tds[1].innerHTML = results[i].stuNo;
			    sortedTable_tds[2].innerHTML = results[i].math;
			    sortedTable_tds[3].innerHTML = results[i].english;
			   }
			  }
			 
			  // 公共方法 1 填充數據
			  this.setData = function()
			  {
			   var tempArr = [];
			   for(var i = 0, len = sortedTable_trs.length; i < len; i++)
			   {
			    for(var j = 0, sortedTable_tds = sortedTable_trs[i].getElementsByTagName("td"), len2 = sortedTable_tds.length; j < len2; j++)
			    {
			     tempArr.push(j == 0 ? sortedTable_tds[j].innerHTML : parseInt(sortedTable_tds[j].innerHTML));
			    }
			    results.push(new Data(tempArr[0],tempArr[1],tempArr[2],tempArr[3]));
			    tempArr.length = 0;
			   }
			  }
			  // 公共方法2 設定排序
			  this.setSorted = function()
			  {
			   var tempArr = [];
			   for(var i = 0, len = sortedTable_ths.length; i<len; i++)
			   {
			    // 避免閉包所帶來的問題
			    (function(_i)
			    {
			     // 正序逆序標誌
			     var flag = 1;
			     var data = new Data();
			     sortedTable_ths[_i].ondblclick = function(event)
			     {
			      event = event || window.event;
			      var target = event.target || event.srcElement;
			      // index 從1 開始,因爲姓名項不可排序
			      results.sort(compare(data.getPropertyNameByIndex(_i + 1),flag));
			      if(flag == 1)
			      {
			       flag = 2;
			      } else if(flag == 2)
			      {
			       flag = 1;
			      }
			      setTableContent(results);
			      // 重置背景顏色
			      var currentTrs = GLOBAL.DOM.getElementsByClassName("currentStyle");
			      if(currentTrs.length != 0)
			       GLOBAL.DOM.removeClass(currentTrs[0], "currentStyle");
			     }
			    })(i);
			   }
			  }
			  //公共方法3 更改表格顏色及觸發鍵盤事件
			  this.toggleTableColorAndLocation = function()
			  {
			   for(var i =0, len = sortedTable_trs.length; i < len ; i++)
			   {
			    (function(_i)
			    {
			     sortedTable_trs[_i].onclick = function()
			     {
			      var currentTrs = GLOBAL.DOM.getElementsByClassName("currentStyle");
			      if(currentTrs.length == 0)
			      {
			       GLOBAL.DOM.addClass(this,"currentStyle");
			       // 只有在選中的情況下才可能觸發移動
			       moveTable(this, _i);
			      } else if(currentTrs[0] != this)
			      {
			       GLOBAL.DOM.removeClass(currentTrs[0],"currentStyle");
			       GLOBAL.DOM.addClass(this,"currentStyle");
			       // 只有在選中的情況下才可能觸發移動
			       moveTable(this, _i);
			      } else
			      {
			       GLOBAL.DOM.removeClass(this, "currentStyle");
			      }
			     }
			    })(i);
			   }
			  }
			  // 移動表格的私有方法,通過單擊事件進行觸發;
			  function moveTable(tr, index)
			  {
			   // 採用事件委託機制,因爲ff 不支持 tr 下的onkeydown 事件
			   document.onkeydown = function(event)
			   {
			    var currentTrs = GLOBAL.DOM.getElementsByClassName("currentStyle");
			    if(currentTrs.length != 0)
			    {
			        event = event || window.event;
			        var item = null,
			            len = sortedTable_trs.length,
			            code = event.keyCode || event.which || event.charCode;
			        if(code == 65)
			        {
			         item = results.pop();
			         results.unshift(item);
			         (index + 1) % len == 0 ? index = 0 : index ++;
			        } else if(code == 90)
			        {
			         item = results.shift();
			         results.push(item);
			         (index - 1 < 0) ? index = len -1 : index --;
			        }
			        setTableContent(results);
			        GLOBAL.DOM.removeClass(currentTrs[0],"currentStyle");
			        GLOBAL.DOM.addClass(sortedTable_trs[index],"currentStyle");
			    }
			   }
			  }
			 }
			 window.onload = function()
			 {
			  var table = new SortedTable();
			  // 1. 填充數據
			  // 2. 綁定排序事件
			  // 3. 綁定更改顏色及鍵盤事件
			  table.setData();
			  table.setSorted();
			  table.toggleTableColorAndLocation();
			 }
		 </script>
	</body>
</html>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章