在最近的《微课堂》项目中,有教师录入学生成绩的需求,为了使录入成绩的功能更加便捷,采用了js,现在就和大家分享一下。
效果
在进行构思编写之前,我们首先要做的就是知道自己想要达成什么效果。先来看一下我们想要的效果吧(由于最后实现了想要的效果,就用成品展示一下)
这是录入成绩界面的控制按钮,点击后进入录入成绩的界面。
这是录入成绩的界面,教师在这里输入平时成绩和期末成绩后,平时成绩、期末成绩、总成绩都会保存到数据表中。
点击方框后,便可以进行编辑,点击方框之外的地方,编辑完成,立刻进行保存,而且立刻计算出总成绩。
考虑到不同的老师会按照不同的权重给平时成绩和考试成绩的分数,所以添加了选择权重的功能,又因为权重的比例一般没有个位数,所以提供给用户选择的功能,而并非输入权重,相比之下,选择更加省时、省心、省力。
实现
一、失去焦点后执行方法和对表单进行编辑
要想实现点击时进行编辑,离开后进行保存的功能,我们需要用到一个方法“onblur()”
下面是它的用法:
onblur使用方法
一般情况下,表单内容是无法进行编辑的,为了保证整体的美观性和实用性,我们采用对表单进行编辑,而非采用<input>输入框,在这我们对其属性进行了编辑,即:“contenteditable="true"”
修改属性后,便可以进行编辑了。
二、执行方法后进行保存
在我的代码中,对平时成绩和考试成绩的保存分别采用了autoSave()、 finalSave()两个方法,当然这两个方法是自己任意命名的。
平时成绩
<td style="color: white" class="list usual" contenteditable="true" onblur="autoSave(event);" id="{$score-> id}">{$score->usual_score}</td>
考试成绩
<td style="color: white" class="list exam" contenteditable="true" onblur="finalSave(event);" id="{$score-> id}">{$score->exam_score}</td>
下面来看一下js的方法
成绩的保存
function autoSave(event) {
const id = event.target.id;
const usualValue = event.target.textContent;
$.post("/index/teacher/usualScore?", { id: id, usualvalue: usualValue }, function(result) {
totalAchievements(id);
});
}
event
id 和 value 都是要传输给后台的参数值,post指的是用post方法进行传值,路径为“/index/teacher/usualScore”,所以我们要在后台构建“usualScore()”这个方法,“?”后面的都是要传输的参数。
我们再来看一下后台的方法
public function usualScore()
{
$data = Request::instance()->param();
$id = $data['id'];
$value = $data['usualvalue'];
$Score = Score::get($id);
$Score->usual_score = $value;
$Score->save();
}
$data 接收所有的参数,然后找到id所对应的对象,赋值后进行保存。
考试成绩和总成绩的写法与平时成绩的写法相同,在此也就不一一介绍了。
三、权值的选择与计算
<label class="option" style="color: white">请选择平时成绩所占权重</label>
<select name="usual" id="usual" lay-search style="height: 4%;" onchange="reload();">
<option value="0.3">30%</option>
<option value="0.1">10%</option>
<option value="0.2">20%</option>
<option value="0.4">40%</option>
<option value="0.5">50%</option>
</select>
"onchange()"方法指的是一经改变,就执行方法,此处执行的是"reload()"方法。
function reload()
{
obtainWeight();
init();
}
"reload()"方法又调用"obtainWeight()"、"init()"两个方法。
function obtainWeight(event) {
let usual = document.getElementsByClassName('usual');
let weightNode = document.getElementById("usual");
let examNode = document.getElementById('exam');
let index = weightNode.selectedIndex;
let value = weightNode.options[index].value;
//利用url跳转将term节点的值传到后台
let url = "/index/teacher/getWeight?usualScore=" + value;
ajaxGet(url, function(response) {
console.log(response);
clear(examNode);
createOption(examNode, response);
totalAchievements();
});
//调用creatOption方法
}
“document.getElementsByClassName()”是通过Class的名字获取节点,“document.getElementsById()”是指通过id获取节点,用“value”表示获取到的节点的值,之后定义url,标明方法和参数,用"ajaxGet()"方法进行跳转传值。
function ajaxGet(url, callback) {
$.ajax({
url: url,
type: "get",
//成功后调用success后面的语句
success: function(response) {
callback(response);
},
//失败后调用error后面的语句
error: function(xhr) {
console.log('server error');
}
});
url 指的是用户定义的url,如果没有参数,只写明路径即可,type指的是传值的方式,一般有“post”和“get”两种,success()和error()指的是传回的数据,如果成功,就返回参数,如果未成功,就在控制台上显示“error”中的内容。
//获取前台传入的平时成绩的权重值,计算出考试成绩的权重值后返回给前台
public function getWeight()
{
$usualScore = Request::instance()->param('usualScore');
$examScore = 100-($usualScore*100).'%';
return $examScore;
}
现在我们再来看一下后台的代码,$usualScore表示的是平时成绩的权重,计算出考试成绩的权重后返回给前台。
function createOption(node, inners, values) {
let examScore = document.createElement('option');
examScore.name = node;
examScore.innerHTML = inners;
node.appendChild(examScore);
}
在图中我们可以发现,考试成绩所占权重是没有<option>的,那么它是怎么得到的option呢?
由上面的命名可以知道,我们要用js创建一个<option>,“document.createElement()”,指的是创建节点,后面的内容便是对节点进行赋值,从而生成节点。
function init()
{
let usual = document.getElementsByClassName('usual');
for (var i = 0; i < usual.length; i++)
{
totalAchievements(usual[i].id);
}
}
通过Class的名字获取节点,然后用for循环生成id,以区分不同的usualScore的值,然后调用"totalAchievements()"方法。
function totalAchievements(id)
{
let index;
let usual = document.getElementsByClassName('usual');
let exam = document.getElementsByClassName('exam');
let total = document.getElementsByClassName('total');
let usualWeight = document.getElementById("usual").value;
for (var i = 0; i < usual.length; i++) {
if (usual[i].id === id) {
index = i;
break;
}
}
usualScore = usual[index];
examScore = exam[index];
totalScore = total[index];
if (usualScore && examScore && totalScore) {
let response = usualWeight * usualScore.innerText + (1 - usualWeight) * examScore.innerText;
totalScore.innerText = (Math.round(response*10)/10);
totalSave(id, (Math.round(response*10)/10));
}
}
获取到节点,然后取各节点的值,之后便是根据各值的含义进行运算,再把值赋予总成绩。
function clear(node) {
node.length = 0;
}
定义"clear()"方法,清除上一次的取值,否则会造成数值积累。
总结
以上便是思路以及实现的步骤,在最后要提醒大家,在权值选择改变后,要执行计算另一个权值以及计算总成绩的方法,还有就是在点击“录入”按钮跳转到录入成绩的界面时,要执行计算另一权重的方法,一般情况下,初始权重默认为是<select>标签下的第一个<option>。
这是第一次接触js,不得不说js真的挺神奇的,这次接触的不是很深,相信在日后的接触中,我会好好的掌握它。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。