- 一、页面设计
- 题目列表页
- 题目详情页
 
- 二、获取到后台数据
- 实现思路
- 遇到换行问题
- 小结
- 引入 ace.js
 
- 三、项目总结
接下来将实现 online-oj 项目的前端界面。
先随便从各大网站上下载网页模板~
 因为好看的前端网页设计需要美工的,我们只是程序员…
一、页面设计
但是我们可以自己思考一下,一共需要几个页面,每个页面都是干什么的,大概什么样子。
题目列表页
功能:展示出当前都有哪些项目。点击某个题目就可以跳转到题目的详情页。

题目详情页
功能:展示题目的具体信息~

接下来我们引入下载好的网页模板代码,调整出自己需要的页面。

当前是通过写死页面的方式,来显示题目的。
 真实情况是需要让页面通过 Ajax 的方式从服务器来获取数据。
JS 中原生的 Ajax 是基于 XMLHttpRequest 类来实现的,用起来比较麻烦。我们使用第三方库提供的封装版本 jQuery 提供的 Ajax 函数即可。
JS 中安装第三方库非常简单,一行代码引入即可。

二、获取到后台数据
通过 makeProblemTable 函数把后台数据转换成 HTML 页面片段。
// 通过这个函数来把数据转换成 HTML 页面片段
function makeProblemTable(data) {
    // 获取到前台列表中的元素
    let problemTable = document.querySelector("#problemTable");
    //
    for (let problem of data) {
        let tr = document.createElement("tr");
        // id
        let tdId = document.createElement("td");
        tdId.innerHTML = problem.id;
        tr.appendChild(tdId);
        // 题目
        let tdTitle = document.createElement("td");
        let a = document.createElement("a");
        a.innerHTML = problem.title;
        // 跳转到 problemDetail.html 页面
        a.href = 'problemDetail.html?id=' + problem.id;
        // 跳转到新页面
        a.target = '_blank';
        tdTitle.appendChild(a);
        tr.appendChild(tdTitle);
        // 难度
        let tdLevel = document.createElement("td");
        tdLevel.innerHTML = problem.level;
        tr.appendChild(tdLevel);
        problemTable.appendChild(tr);
    }
}
验证题目列表页,测试网页成功显示

点击题目标题,我们将跳转到题目详情页。
 这时候需要再加一个页面 problemDetail.html
实现思路
在题目列表页的 a 标签里填地址,problemDetail.html 的路径,同时把题目 id 通过 query string 传递过去。

完成题目详情页的代码
        <!--components-->
        <section class="my-5 pt-5">
            <div class="container">
                <!-- 题目详情  -->
                <div class="jumbotron jumbotron-fluid">
                    <div class="container" id="problemDesc">
<!--                        <h1>Container fluid size jumbotron</h1>-->
<!--                        <p>Think BIG with a Bootstrap Jumbotron!</p>-->
                    </div>
                </div>
                <!-- 代码编辑框  -->
                <div class="form-group">
                    <label for="codeEditor">代码编辑框</label>
                    <div id="editor" style="min-height:400px">
                        <textarea class="form-control" id="codeEditor" style="width: 100%; height: 400px;"></textarea>
                    </div>
                </div>
                <!-- 提交按钮  -->
                <div>
                    <button type="button" class="btn btn-primary" id="submitButton"> 提 交 </button>
                </div>
                <label></label>
                <!-- 提交的结果  -->
                <div class="jumbotron jumbotron-fluid">
                    <div class="container">
                        <pre id="problemResult">
                        </pre>
<!--                        <h1>Container fluid size jumbotron</h1>-->
<!--                        <p>Think BIG with a Bootstrap Jumbotron!</p>-->
                    </div>
                </div>
            </div>
        </section>
修改 index.html 的跳转页面
// 跳转到 problemDetail.html 页面
                    a.href = 'problemDetail.html?id=' + problem.id;
                    // 跳转到新页面
                    a.target = '_blank';
遇到换行问题
从服务器获取的题目详情没有换行,HTML 不识别 \n。
有两种解决方法:
① 把返回的数据中的 \n 都替换成 <br>
② 给页面的标签里面套一层 <pre> 标签,让其能够识别 \n
我们选择了第二种.
// 语法就像开好一个容器,把东西放进去,最后把容器封起来。
function makeProblemDetail(problem) {
    // 1. 获取到 problemDesc,把题目详情填写进去
    // # 号表示定位到前端 id 为 problemDesc 的 div 中,准备往里面添加数据
    let problemDesc = document.querySelector("#problemDesc");
    // 题目的标题
    let h3 = document.createElement("h3");
    h3.innerHTML = problem.id + "." + problem.title + "_" + problem.level;
    problemDesc.appendChild(h3);
    // 题目的详情,pre 能识别从 Java 中的 \n 换行
    let pre = document.createElement("pre");
    let p = document.createElement("p");
    p.innerHTML = problem.description;
    pre.appendChild(p);
    problemDesc.appendChild(pre);
}
getProblem();
小结
通过 Ajax 的方式获取到后端数据;
 再把数据填充到前端页面里面,根据不同数据填充不同的模块;
 给提交按钮注册回调函数;
 在回调函数里面,根据得到的响应决定如何显示编辑运行结果。
引入 ace.js
这是一个前端版本的代码编辑器,让代码编辑框更加好看。
直接引入对应的地址即可安装。
    <!-- 引入 ace.js -->
        <script src="https://cdn.bootcdn.net/ajax/libs/ace/1.2.9/ace.js"></script>
        <script src="https://cdn.bootcdn.net/ajax/libs/ace/1.2.9/ext-language_tools.js"></script>
        <script>
三、项目总结
-  了解要做的项目的基本要求 
 1)题目列表页
 2)题目详情页
 3)代码编辑框
 4)提交给服务器编译运行
 5)展示结果
-  介绍了多进程编程,基于多进程编程。封装了一个 CommandUtil 类,就可以创建进程执行一个具体的任务,同时把输出结果记录到指定的文件中。 
-  创建了一个 Task 类,调用 CommandUtil 封装了一个完整的 编译-运行 过程。后面又给 Task 类扩充了一个基于黑名单的安全代码校验。 
-  设计了数据库,封装了数据库操作。Problem 和 ProblemDAO。 
-  设计了前后端交互的接口。 
 1)获取题目列表
 2)获取题目详情
 3)编译运行
-  基于 Servlet 实现了这几个接口。 
-  引入前端网页代码模板,基于代码模板进行修改,创建出了两个页面 
 1)题目列表页 index.html
 2)题目详情页 problemDetail.html
-  通过 js 代码,实现了前端调用 HTTP API 的过程。 
-  引入 ace.js 让代码编辑框变得更加好用。 
ps.后续可能完成的功能
1. 部署到云服务器上。
2. 实现题目管理页面:录入题目,删除题目。
3. 实现用户注册登录页面。
4. 实现提交记录保存功能。
5. 实现通过率的统计。
6. 实现点赞收藏题目功能。
......
最后附上项目的源码~ 在线OJ项目.





![[强网杯 2019]高明的黑客](https://img-blog.csdnimg.cn/9ccb67b989494987be07d745ed7bff20.png)











