10月底从昆山回到苏州。直到11月底才找到工作,跑到哪都是有没有工作经验,没有。。。好吧,回去等通知吧。
2009年11月19日来到苏州热线面试(苏州比较大的门户网站)
面试结束后带回去了一个题、
要求:
1.任何语言 任何形式(web,winform,flash,flex,silverlight)等等。。
2.实现内容
a.初始化一个面板,面板内随机分布着一些按钮 按钮上有一些随机的数字。
b.有一个按钮 名字叫“新增节点” 点击 该按钮后 可以向面板内随机添加新的 按钮。
c.任意顺序点击面板内的按钮。按顺序将所点按钮用线条连接。并且将按钮的 数值进行累加 显示到 文本框。
d.回放 功能。 有一个名叫 “回放的按钮” 点击该按钮后 将所有操作慢动作回放。
包括增加节点 和 连接 的一切操作。完整再现。
这题拿回家做了3个班小时。水平不行啊。。花了很长时间在想用什么技术好。结果用了 JavaScript (jQuery)
在中间遇到了一些难点。
1.画线问题。一开始想到的是 vml 但是由于浏览器兼容问题。最后在网上找啊找。
使用了别人写的一个函数 用JavaScript 画线 主要思路是 利用三角函数 画出该线的每一个像素点(非常占资源)
2.记录和回放问题。如何记录下每一个操作并回放,这个问题也想了很久
记录:最后是这样的。在全局存放一个对象,该对象是一个 button 的 dom 。用来保存上一次点击的按钮对象。
当点击一个按钮时。首先将该按钮存放到一个array(存放Button对象)中,再将判断上一次是否存在点击。如果存在,则将这两个按钮连接。
当添加按钮时 首先将随机产生的按钮添加至 array 中 。
回放:当点击回放时 首先是要初始化板面中的按钮和线条等。 策略是:线条全部删除。中途添加的按钮 全部隐藏。
回放的过程实际是 一个 array 的遍历过程。
判断 array 中 Button的 状态。当Button 为显示时。调用 Button的 click 方法。否则 将Button设置为可见。
这就是基本思路。
贴出我的实现代码。
Test.js
/**
* @author 汤晓华
*
* @copyright 2009 汤晓华
*
*
*/
/***
* 用于绘制线条
* @param {Object} x1 第一点的X坐标
* @param {Object} y1 第一点的Y坐标
* @param {Object} x2 第二点的X坐标
* @param {Object} y2 第二点的Y坐标
* @param {Object} color 颜色
*/
function line(x1, y1, x2, y2, color){
var html = "";
var tmp
if (x1 >= x2) {
tmp = x1;
x1 = x2;
x2 = tmp;
tmp = y1;
y1 = y2;
y2 = tmp;
}
for (var i = x1; i <= x2; i++) {
x = i;
y = (y2 - y1) / (x2 - x1) * (x - x1) + y1;
html += " <img border='1' class='line' style='border-color: "+color+";position:absolute;left:" + (x + 20) + "px;top:" + (y + 20) + "px;background-color:" + color + "' width=1 height=1>";
}
return html;
}
/**
* 全局变量
*/
//容器对象
var container = null;
//被点击过的按钮
var clickedBtn = null;
//初始化按钮数量
var InitBtnNum = 5;
//按钮最大的ID
var maxId = InitBtnNum;
//存放依次点击的按钮的Id的Array对象
var BtnArray = new Array();
//是否在回放
var IsPlayBack = false;
/**
* 产生随机数函数
* @param {Object} min
* @param {Object} max
*/
var random = function(min, max){
max = max == null ? 50 : max;
min = min == null ? 1 : min;
return Math.floor(Math.random() * max + min);
}
/**
* 初始化容器中的按钮
*/
function InitButton(){
for (var i = 0; i < InitBtnNum; i++) {
CreateBtn(i);
}
}
/**
* 创建按钮
* @param {Object} id
*/
function CreateBtn(id){
var value = random();
var top = random(60, 400);
var left = random(60, 700);
var button = "<button id=\"btn" + id + "\" isClick=\"false\" class=\"btn\" οnclick=\"BtnClick(this)\" style=\"top: " + top + "px;left: " + left + "px;\">" + value + "</button>";
container.append(button);
}
/**
* 容器中按钮的点击事件
* @param {Object} obj
*/
function BtnClick(obj){
var nowBtn = $(obj);
if (nowBtn.attr("isClick") != "false") {
return;
}
if (!IsPlayBack) {
//将当前的按钮对象推入BtnArray中
BtnArray.push(nowBtn);
}
//设置按钮的颜色
nowBtn.css("background", "blue");
if (clickedBtn != null) {
var _x1 = nowBtn.css("left");
var x1 = _x1.substring(0, _x1.indexOf("px"));
x1 = parseInt(x1) - 5;
var _y1 = nowBtn.css("top");
var y1 = _y1.substring(0, _y1.indexOf("px"));
y1 = parseInt(y1) - 8;
var _x2 = clickedBtn.css("left");
var x2 = _x2.substring(0, _x2.indexOf("px"));
x2 = parseInt(x2) - 5;
var _y2 = clickedBtn.css("top");
var y2 = _y2.substring(0, _y2.indexOf("px"));
y2 = parseInt(y2) - 8;
var _line = line(x1, y1, x2, y2, "red");
//将联系追加到容器中
container.append(_line);
}
//计算文本框的值
CountValue(nowBtn);
//将按钮的属性设置为已点击
nowBtn.attr("isClick", "true");
//将当前按钮设置为最后一个点击过的按钮
clickedBtn = nowBtn;
}
/**
* 累加结果
* @param {Object} obj 按钮对象
*/
function CountValue(obj){
var txtBox = $("#countResult");
txtBox.val(parseInt(txtBox.val()) + parseInt(obj.html()))
}
/**
* 回放
*/
function Playback(){
if (IsPlayBack) {
return;
}
IsPlayBack = true;
//将结果归0
$("#countResult").val(0);
//移除连接
$(".line").remove();
//将按钮的isClick属性设置成 false
$(".btn").attr("isClick", "false");
//先全部隐藏按钮
$(".btn").css("display", "none");
//现实初始化时就存在的按钮
for (var i = 0; i < InitBtnNum; i++) {
$("#btn" + i).css("display", "block");
}
//颜色全部设置成初始色
$(".btn").css("background", "#ff8901");
//最后点击的按钮设置为Null
clickedBtn = null;
//1秒后开始回放连接过程
setTimeout("DoPlayBack(0)", "1000");
}
/**
* 执行回放动作
*/
function DoPlayBack(index){
if (index < BtnArray.length) {
var display = BtnArray[index].css("display");
if (display == "none") {
BtnArray[index].css("display", "block")
}
else {
BtnArray[index].click();
}
index += 1;
}
else {
IsPlayBack = false;
alert("回放结束");
return;
}
setTimeout("DoPlayBack(" + index + ")", "300");
}
/**
* 页面DOM载入完毕后执行函数
*/
jQuery(function(){
InitBtnNum = random(3, 4);
$("#countResult").val(0);
///为增加按钮增加点击事件
$("#AddButton").click(function(){
maxId += 1;
CreateBtn(maxId);
if (!IsPlayBack) {
//将当前的按钮对象推入BtnArray中
var id = "#btn" + maxId;
BtnArray.push($(id));
}
});
///为回放按钮增加点击事件
$("#Playback").click(function(){
Playback();
});
//获取container对象
container = $("#container");
//初始化容器中的按钮
InitButton();
});
index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>面试题</title>
<script type="text/javascript" src="lib/jquery/jquery-1.3.2.min.js">
</script>
<script type="text/javascript" src="lib/Test.js">
</script>
<style type="text/css">
div#container {
width: 800px;
height: 500px;
border: 1px red solid
}
button.btn {
position: absolute;
BACKGROUND: #ff8901;
PADDING-BOTTOM: 0px;
CURSOR: pointer;
COLOR: #fff;
BORDER-TOP-STYLE: none;
LINE-HEIGHT: 20px;
PADDING-TOP: 0px;
BORDER-RIGHT-STYLE: none;
BORDER-LEFT-STYLE: none;
LETTER-SPACING: 1px;
BORDER-BOTTOM-STYLE: none;
width: 30px;
height: 20px;
}
button.btn1 {
position: relative;
BACKGROUND: #ff8901;
PADDING-BOTTOM: 0px;
CURSOR: pointer;
COLOR: #fff;
BORDER-TOP-STYLE: none;
LINE-HEIGHT: 20px;
PADDING-TOP: 0px;
BORDER-RIGHT-STYLE: none;
BORDER-LEFT-STYLE: none;
LETTER-SPACING: 1px;
BORDER-BOTTOM-STYLE: none;
width: 80px;
height: 24px;
}
</style>
</head>
<body>
<div>
累加结果:<input type="text" readonly="true" id="countResult" style="width:70px" value="0" />
<button id="AddButton" class="btn1">
增加节点
</button>
<button id="Playback" class="btn1">
回 放
</button>
</div>
<div id="container">
</div>
</body>
</html>
效果图