基于上个任务,继续进行改进
任务描述
- 命令输入框由input变为textarea,可以允许输入多条指令,每一行一条
- textarea左侧有一列可以显示当前行数的列(代码行数列),列数保持和textarea中一致
- 当textarea发生上下滚动时,代码行数列同步滚动
- 能够判断指令是否合法,不合法的指令给出提示
- 点击执行时,依次逐条执行所有命令
- 对于GO,TRA以及MOV指令增加可以移动格子数量的参数,例如
- GO 3:向当前方向前进三格
- TRA TOP 2:向屏幕上方平移两格
- MOV RIG 4:方向转向屏幕右侧,向屏幕的右侧移动四格
整体思路
首先根据要求,修改HTML结构,并设置基本样式。
<div id="container" class="clearFix">
<div id="dispaly_box">
<canvas id="canvas_bg" width="441" height="441"></canvas>
<div id="square"></div>
</div>
<div id="control_panel">
<ol id="identifier">
<li>1</li>
</ol>
<textarea id="orders"></textarea>
<button id="btn_exe">执行</button>
</div>
</div>
<div id="instruction">
//介绍
</div>
#control_panel{
padding: 40px 0;
float: right;
width: 441px;
height: 441px;
}
#control_panel ol{
float: left;
margin: 0;
padding: 0;
width: 25px;
height: 400px;
background-color: #ccc;
overflow: hidden;
}
#control_panel li{
list-style: none;
width: 25px;
height: 25px;
line-height: 25px;
text-align: center;
color: white;
}
#orders{
padding: 0;
padding-left: 2px;
width: 410px;
height: 400px;
outline: none;
border: none;
font-size: 20px;
line-height: 25px;
vertical-align: middle;
overflow-y: auto;
background-color: rgb(43,43,43);
color: rgb(86,187,86);
resize: none;
}
.clearFix:after{
clear: both;
display: block;
visibility: hidden;
content: "";
height: 0;
line-height: 0;
}
.error{
background-color: red;
}
#instruction{
margin: 10px auto;
width: 800px;
}
下面,新增一个textArea.js,添加一个函数,帮助获取文本域中的指令行数
function getTextLine(){
var txt = $("#orders").value;
var arr = txt.split("\n");
return arr.length;
}
然后增加一个函数,以获取显示当前行数的列
function getIdentifier(){
var eleNodes = [];
var nodes = Array.prototype.slice.call($("#identifier").childNodes);
for(var i=0;i<nodes.length;i++){
if(nodes[i].nodeType == 1){
eleNodes.push(nodes[i]);
}
}
return eleNodes;
}
最后,编写一个检测指令是否合法的函数
function checkValue(value){
var order_two = ["LEF","RIG","BAC"];
var order_three = ["LEF","RIG","TOP","BOT"];
var comms = value.split(" ");
if(comms.length>3 || comms.length<0){ //如果指令组成大于3或者小于0 返回false
return false;
}else if(comms.length == 1){
if(comms[0] == "GO"){
return true;
}
return false;
}else if(comms.length == 2){
if(comms[0]=="GO" && !isNaN(comms[1])){
return true;
}else if(comms[0]=="TUN" && isMatch(comms[1],order_two)){
return true;
}else if((comms[0]=="TRA"||comms[0]=="MOV") && isMatch(comms[1],order_three)){
return true;
}else{
return false;
}
}else if(comms.length == 3){
if((comms[0]=="TRA"||comms[0]=="MOV") && isMatch(comms[1],order_three) && !isNaN(comms[2])){
return true;
}else{
return false;
}
}
function isMatch(value,arr){
for(var i=0,len=arr.length;i<len;i++){
if(value == arr[i]){
return true;
}
}
return false;
}
}
然后对文本域进行事件绑定,当用户按下回车键后,对指令进行检测,然后增加新的行数
addHandler($("#orders"),"keydown",function(e){
if(e.keyCode == 13){
//保存输入的指令并获取行数
var txt = $("#orders").value;
var arr = txt.split("\n");
var line = arr.length;
//获取最后一行的指令
var value = arr[line-1];
//获取行号节点
var indexs = getIdentifier();
//指令不正确则红色标注
if(!checkValue(value)){
indexs[line-1].className = "error";
}
//添加行数
var li = document.createElement("li");
li.innerHTML = line+1;
$("#identifier").appendChild(li);
}
});
为了实现删除某行指令后,删除前面行号的效果,需要绑定的键盘的keyup事件,检测实际指令行数和行号是否一致,不一致则删除最后一行。
addHandler($("#orders"),"keyup",function(e){
if(e.keyCode == 8){
var line = getTextLine();
var indexs = getIdentifier();
if(line !== indexs.length){
$("#identifier").removeChild(indexs[indexs.length-1]);
indexs[indexs.length-2].className = "";
}
}
});
最后实现行号列和指令列的同步滚动
addHandler($("#orders"),"scroll",function(e){
var top = $("#orders").scrollTop;
$("#identifier").scrollTop = top;
});
最终代码
两周时间一直专注于课题组的课题,今天是16年最后一天,挤出点时间,更新出今年的最后一篇 O(∩_∩)O