前言
昨天偶然在自己电脑上翻到一家在长沙的小公司给的笔试题,有个题是关于前端的,当时主要应聘岗位是Java后端开发,所以当时对前端知识不熟悉,只会一点HTML+CSS+JS的基础知识。最近有学习Ajax+JS+Jquery的相关知识,再看这道题,考察的是挺简单的页面渲染,练练手还是不错的,在实现的过程中,还是遇到了很多问题,花了将近一天的时间。
题目要求
编写一个html文件,从data.json文件获取数据,实现如图所示的页面及功能。要求如下:
- 通过ajax异步获取数据,并显示到界面上
- 当点击Action列的删除图标时,将本行记录从界面上删除
- 可以使用流行的开发框架及插件,如jQuery、Bootstrap、VUE等
实现过程
先准备好json数据
{ "test":[ {"id":"1","dsn":"alibaba","pn":"payfor","email":"[email protected]"}, {"id":"2","dsn":"tengxun","pn":"QQ","email":"[email protected]"}, {"id":"3","dsn":"google","pn":"sq","email":"[email protected]"} ] }
下载Action项中删除按钮的图标
可以去阿里巴巴矢量图中寻找自己喜欢并且合适的图案样式,应有尽有。
http://www.iconfont.cn/按照题目要求的界面编写HTML
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link rel="stylesheet" type="text/css" href="css/table.css" /> <script type="text/javascript" src="js/Jquery.min.js"></script> <script type="text/javascript" src="js/tableop.js"></script> <title>10JQKA</title> <style> *{margin:0;padding:0;} </style> </head> <body> 数据渲染 <table class="imagetable" id="tab"> </table> <script type="text/javascript"> $(function(){ $.ajax({ url:"data/test.json", type:"GET", dataType: "json", success:function(data){ var msg = ""; msg += "<tr>"+"<th>"+"ID"+"</th>"+"<th>"+"Datasource Name"+"</th>"+"<th>"+"Product Name"+"</th>"+"<th>"+"Email"+"</th>"+"<th>"+"Action"+"</th>"+"</tr>"; for ( var i = 0; i < data.test.length; i++) {//循环json对象,拼接tr,td的html msg += "<tr>"; msg += "<td>" + data.test[i].id + "</td>"; msg += "<td>" + data.test[i].dsn + "</td>"; msg += "<td>" + data.test[i].pn+ "</td>"; msg += "<td>" + data.test[i].email + "</td>"; msg += "<td>" + "<img id=\"imgstyle\" src=\"img/delete.png\" style=\"width:20px;heigth:20px\" onClick=\"delRow(this)\">" +"</td>"; msg += "</tr>"; } $("#tab").html(msg); //通过jquery方式获取table,并把tr,td的html输出到table中 }, error:function(){ alert("数据加载错误!"); } }); }); </script> </body> </html>
添加删除按钮的JS响应事件(借鉴的代码)
//得到行对象 function getRowObj(obj) { var i = 0; while(obj.tagName.toLowerCase() != "tr"){ obj = obj.parentNode; if(obj.tagName.toLowerCase() == "table")return null; } return obj; } //根据得到的行对象得到所在的行数 function getRowNo(obj){ var trObj = getRowObj(obj); var trArr = trObj.parentNode.children; for(var trNo= 0; trNo < trArr.length; trNo++){ if(trObj == trObj.parentNode.children[trNo]){ alert(trNo+1); } } } //删除行 function delRow(obj){ if(confirm("确定删除么?")){ var tr = this.getRowObj(obj); if(tr != null){ tr.parentNode.removeChild(tr); }else{ throw new Error("the given object is not contained by the table"); } } }
为table添加css样式
table.imagetable { font-family: verdana,arial,sans-serif; font-size:16px; color:#004080; border:1px solid #ff1a1a; border-collapse: collapse; } table.imagetable tr th { padding: 8px; border:1px solid #ff1a1a; } table.imagetable tr td { padding: 8px; border:1px solid #ff1a1a; }
运行结果演示
点击Action图标,会弹出是否确定删除的图标,选择确定,就可以在界面上删除按钮对应的一条信息。
需要说明的是该删除只是在页面显示删除,并没有删除test.json文件中的json数据,重新运行项目,json数据仍然会全部呈现。这个应该叫逻辑删除吧。
总结
虽然是一个简单的例子,并且例子中所用到的样式还是之前现成的,但是在实现过程中还是遇到不少问题,花了将近一天时间,需要记录一下。
- 首先遇到的问题是Ajax异步请求Json数据发生的跨域问题,web为了安全性考虑,提出同源的策略,同源是指,域名,协议,端口相同,当前域不能访问其他域内容。这个感觉还是比较复杂的问题,我理解的是,Ajax请求不能随意访问本地的数据资源。当在本地进行HTML和JS代码调试的时候,总会报错,后面意识到可能是之前遇到过的跨域问题,于是我将项目发布到tomcat上运行调试,这样就不存在跨域问题了。具体操作是在eclipse中创建一个web项目,将本地编写的前端代码文件夹放到web项目中的WebContent目录下即可。
JSON数据变量表示问题。代码编写完,部署到tomcat服务器上,当我在用Google浏览器调试时,我发现json数据没办法显示出来,但是表头的数据会有显示,说明我的Ajax请求是成功的,因为执行了成功回调函数,为什么json数据渲染不出来呢,我检查了json数据格式,完全没有问题,又使用Console.log(data),打印出Object,当我alert(data[1].id)时,代码出错,显示data[1]值是undefined,之前看过JS高级教程可以知道,Undefined是ECMAScript定义的五种原始数据类型之一,undefined表示一个未声明的变量,或已声明但没有赋值的变量,或一个并不存在的对象属性。这时还没有发现问题所在,最后根据错误信息,看到了stack Overflow上一个回答提示可能是变量域没理解,于是重新看了一下根据ajax返回结果调用数据,才发现少了一个json中的test变量,正确的应该是data.test[i].id引用,这样才恍然大悟,被一个小错误折腾了好久。
除了遇到的错误,这个例子还有很多可以完善的地方,如果数据条数过多,肯定需要进行分页显示处理,还有页面需要美化,现在都有多样,固定的渲染模板,还是挺容易的。