共计 4461 个字符,预计需要花费 12 分钟才能阅读完成。
在最近的《微课堂》项目中,有教师录入学生成绩的需求,为了使录入成绩的功能更加便捷,采用了 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
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 真的挺神奇的,这次接触的不是很深,相信在日后的接触中,我会好好的掌握它。