搜索
首页web前端html教程(二)排行榜(定义和使用函数、对象)- 扫雷网页小游戏_html/css_WEB-ITnose

上一章我们实现了最基本的游戏界面和游戏的简单入口,这一章,我们完善和制作 排行榜 功能,并为将来游戏结束时使用、记录排行榜提供支持。

在使用 互联网 的时候,我们基本上离不开 浏览器 ( browser ) 。 浏览器其实可以看作一个 中间人,他将 用户无法理解、看不太懂的 脚本语言描述的程序,转换为 用户可以看得到的界面、接收用户的输入输出动作,并通过执行脚本程序给出对应的反馈。 一般,我们把前面的 “转换为界面” 过程称作 “渲染” (render)。 在上一章中,我们在 .html 文件中填写了代码,在浏览器中打开这个文件,看到了界面,我们姑且称这个“渲染”动作为“静态渲染”,那么这一章中,我们将会看到另外一种“动态渲染”。

接口可以理解为能够让另外的代码、模块调用的函数、对象;

分装即就是将可以重复使用或功能联系紧密的若干代码聚合在一个可以被 调用 或 访问的模块中;

在程序开发过程当中,我们一般会提到“接口”,“封装”等等概念。我理解,提出这些概念的目的,其实是在告诉我们,将程序写的更“清晰”一些。这个“清晰”一般可以描述为两方面:

  1. 功能完整 - 实现某个功能应该做些什么事情?如果要做这个事情,是不是可以有不同的做法?
  2. 分工明确 - 某个功能应该在哪里做?代码写在哪里?

定义“接口”,即就是将完整的、能够重复使用的“功能”包装(封装)成函数、对象,并供其他逻辑 或 在其他地方调用;使用者并不需要了解“接口”内部具体的实现逻辑,只需知道接口“形式”即可使用,完成对应的功能,同时使用者 不需要对其不需了解的事情加以干涉 。我们下面也会封装、实现一些简单的接口来介绍上面的概念。

排行榜的结构

按照网页的开发方式,我一般习惯按照“基本结构”->“外观润色”->“行为功能”这个流程进行进行开发。首先,在排行榜(上一章中 (3) 的位置)加入下面“基本结构”的 HTML 代码:

<!-- 标题,可以使用 h1 ~ h5,大小、颜色稍有不同 --><h4 id="排行榜">排行榜</h4><!-- table-striped 将会让表格内容变成深浅相间的行 --><table class="table table-striped">	<!-- 表头 -->	<thead class="thead-default">		<tr>			<th>#</th>			<th>姓名</th>			<th>用时</th>		</tr>	</thead>	<tbody id="rank_table">		<!-- 表格内容 -->	</tbody></table>

在 HTML 中描述一个表格,使用

标签,并用 来表示一行, 或 分别来表达 表头和表体 中的单元格。

上面元素对应的属性 class 中使用的对应内容,可暂不关心(有兴趣的同学,可以 参看 中文 或 英文 的文档)

上述代码我们建立了一个基本的“表”,并为表体元素起名为 rank_table 便于将来对其进行操作(如,加入实际展示的数据,刷新排行榜等)。

因为我们对上层

元素设置了 text-align: center 居中对齐,表格对齐(标题被设置为左对齐了,内容区域是居中对齐的)有点乱,需要加入下面 CSS 样式( minesweeper.css 文件中):
.block.rank .table tbody td { /* 排行榜表格内容居左(由于上层元素设置了 居中) */	text-align: left;  /* left - 左对齐 right - 右对齐 center - 居中 */}

CSS 中存在样式的“继承”,即父级元素设置的样式,如果适用的化,会被“继承”应用的子元素上。

所谓适用的样式有很多,例如 字体名 font-family 、字体大小 font-size 、颜色 color ,当然也存在一些特殊情况,这些属性不会被继承,例如:

这个 A 标签的颜色不继承

动态渲染

编写 minesweeper-rank.js 文件,我们使用 JavaScript 程序为表格加入内容,并“ 渲染 ”出来:

(function($) {	// 位置:(A)	var data = [		{name:"DemoUserA", time:200}, // 直接使用 XXX 秒 来描述 耗时		{name:"DemoUserB", time:300}, // 展示的时候用程序将其变为 XX 分 XX 秒的形式		{name:"DemoUserC", time:400},	]	// 我们定义 $ 开头的变脸用来记录要操作的元素	var $table = $("#rank_table")	// 排行榜的 “渲染”	function render() {		$table.empty() // 清空表格中目前的内容		for(var i=0;i<data.length;++i) { // 循环数组,依次生成每一行 tr 的各个单元格 td			// i+1 按数值形式计算,如果不加括号先和前面文本进行“连接”,不符合预期			$table.append("<tr><td>"+(i+1)+"</td><td>"+data[i].name // 一行太长,可以换行写				+"</td><td>"+renderTime(data[i].time) // this 这里指得就是当前 排行榜对象 rank 				// 调用 renderTime 函数生成 XX分XX秒 形式的文本				+"</td></tr>")			// ! 加入内容,其实就是将 HTML 代码文本 `append()` 添加到表格体中		}	}	// XXX 秒 => XX 分 XX 秒	function renderTime(time) {		return parseInt(time/60) + " 分 " + (time % 60) + " 秒"	}	// 刷新页面时立刻进行“渲染”	rank.render()	// 位置:(B)}(jQuery))

JavaScript 中可以使用 [ ... ] 形式定义数组,使用 {XXX: YYYY, XXX: YYYY} 形式定义对象;

数组一般使用 下标形式访问,例如 data[i] ;

对象一般使用 .name 形式访问,例如 data[i] 是一个对象,可以用 data[i].name 来访问其姓名属性;

持久化

为了让排行榜能够记录并保留数据(不在刷新后消失),我们参照第一章 使用 localStorage 对象提供的功能来完成。我们将 (A) 处初始化的代码改为:

// 位置: (A)var data = localStorage.getItem("rank_data")if(!data) { 	data = [ // 为演示方便,我们初始化一些数据		{name:"DemoUserA",time:200}, // 我们直接使用 XXX 秒 来描述用时		{name:"DemoUserB",time:300}, // 我们直接使用 XXX 秒 来描述用时		{name:"DemoUserC",time:400}, // 我们直接使用 XXX 秒 来描述用时	]	// 我们不能直接包数组数据保存到 localStorage 中,需要对他进行“序列化”,即将起变成文本;	localStorage.setItem( "rank_data", JSON.stringify(data) )	// 在 JavaScript 中一般使用 JSON.stringify(obj) 将 obj 变为文本形式以便存储	// 这种“变文本”的过程就是“序列化”}else{ // 保存了数据,读取出来后需要“还原”: 	// 由于我们保存的是“序列化”的数据,我们需要将它“反序列化”	data = JSON.parse(data)	// JSON.parse() 与 上面 JSON.stringify() 对应,用于还原已经“序列化”的文本到其原始值}

JSON 与 localStorage 类似,也是由浏览器提供的进行数据“序列化”、“反序列化”的函数对象。 同时 JSON 也是一种文本描述数据的形式,具体说明可以参考 http://www.json.org/json-zh.html ;

同时 JSON 是目前最流行的数据交换方式的一种,尤其在服务器端与浏览器交互的“数据型接口”中被大量应用。例如大家熟知的 微信公众平台,就提供了 JSON 形式的接口,有兴趣的同学可以看看他们的文档 https://mp.weixin.qq.com/wiki ;

我们可以在浏览器中打开网页,并按 F12 键打开调试界面,在 Resource 面板中,找到 localStorage 项,可以看到我们的程序已经将数据成功的写入了:

大家可以尝试通过这个面板修改 localStorage 的内容,刷新页面后会发现展示的内容也会随之发生变化。

接口

到这里,我们为排行榜定义的界面和基本显示功能就完成了。但是,这个排行榜还没有办法 动态的调整 ,即将来在实际游戏完成的时候,我们需要把当前名称的用户成绩“更新”或“加入”到排行榜里面。虽然是将来,我们需要先为游戏结束做进行这个功能时留下接口。

我们可能需要提供很多这些类似的“接口”,我们把这种接口统一放在一个名为 MineSweeperRank 的全局对象中(在位置 (B) 处加入下面的代码):

// 位置:(B)window.MineSweeperRank = { // window 为全局命名空间,同时也代表了浏览器当前打开网页的窗口	// 接口1. 加入用户及成绩进入榜单	appendUserRank: function(name, time) { 		// 将成绩插入到 data 中的合适位置		// 从后往前,找到用时小于当前 time 的地方		for(var i=data.length-1; i>=0; --i) {			if(data[i].time < time) {				data.splice(i + 1, 0, {"name": name, "time": time}) // 从 i + 1 这个位置开始,删除 0 个元素,加入 新增元素				break // 找到了速度更快的记录,跳出循环(这时 i 应该还小于 data.length)			}		}		if(i == data.length) { // 没有找到比当前值更小的了,直接排在第一名			data.unshift({"name": name, "time": time})		}		// 截取 data 的前 6 项(不要让排行榜太长了)		data = data.slice(0, 6)		// 数据更新了,我们需要对应更新界面,即重新渲染		render()		// 保存数据		localStorage.setItem( "rank_data", JSON.stringify(data) )	},	// 接口2. 清理(清空)榜单	clearRank: function() {		data.splice(0, data.length)		// 数据更新了,我们需要对应更新界面,即重新渲染		render()		// 保存数据		localStorage.setItem( "rank_data", JSON.stringify(data) )	},	// 接口3. }

上面函数目前没有实际的调用者,我们可以在 “开发者工具” ( F12 ) 的 Console 界面中输入调用代码(例如: MineSweeperRank.appendUserRank("Terry",450) ) 尝试调用,看看效果:

从分工明确的角度,我们也给 “入口” 增加 “接口” 功能,我们将 “获取用户输入的名字” 和 “开始游戏” 作为 “接口” 封装。 注意,前者与上述 排行榜 接口 类似,是“调用”方式的接口。而后者,则是“ 触发 ”形式的接口。

我们先将“调用”形式的接口实现(调整 minesweeper-entry.js 文件, 在结束行函数大括号内,补充如下代码):

// 位置 (C)// 对外接口window.MineSweeperEntry = {	// 接口1. 获取当前用户名	getName: function() {		return localStorage.getItem("entry_input_name") || "无名氏"	},	}// 位置 (D)

JavaScript 使用 || 表示 “逻辑或”,但与其他部分语言不同, || 返回的并非是 “布尔值”,而是条件中 第一个 值;

对应的还存在 && 标识 “逻辑与”,也同样存在上面的使用方式,返回第一个 值,例如: var a = true && 0 变量 a 的值为 0 而非 false;

从分工上说,我们将 获取姓名 接口定义在 “入口”,从 职责上说 我们将 “未输入姓名,处理为 ‘无名氏’” 这个逻辑封装在了接口内部,使用者就不用关心了。

请大家尝试使用 Chrome 浏览器提供的 开发者工具 ( F12 或菜单 三 -> 更多工具 -> 开发者工具 )。它能够提供界面元素 (HTML/CSS) 的调试、 代码(JavaScript)调试,页面性能测试,网络监控等等功能,甚至很多功能连一些正式的前端开发人员都不太了解。有兴趣的同学可以去看看 http://devtoolstips.com/ ,这个网站总结和演示了很多开发者工具的使用技巧,值得学习。

附件

本章目前完成的完整代码可以在这里下载压缩包

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
公众号网页更新缓存难题:如何避免版本更新后旧缓存影响用户体验?公众号网页更新缓存难题:如何避免版本更新后旧缓存影响用户体验?Mar 04, 2025 pm 12:32 PM

公众号网页更新缓存,这玩意儿,说简单也简单,说复杂也够你喝一壶的。你辛辛苦苦更新了公众号文章,结果用户打开还是老版本,这滋味,谁受得了?这篇文章,咱就来扒一扒这背后的弯弯绕绕,以及如何优雅地解决这个问题。读完之后,你就能轻松应对各种缓存难题,让你的用户始终体验到最新鲜的内容。先说点基础的。网页缓存,说白了就是浏览器或者服务器为了提高访问速度,把一些静态资源(比如图片、CSS、JS)或者页面内容存储起来。下次访问时,直接从缓存里取,不用再重新下载,速度自然快。但这玩意儿,也是个双刃剑。新版本上线,

如何使用HTML5表单验证属性来验证用户输入?如何使用HTML5表单验证属性来验证用户输入?Mar 17, 2025 pm 12:27 PM

本文讨论了使用HTML5表单验证属性,例如必需的,图案,最小,最大和长度限制,以直接在浏览器中验证用户输入。

HTML5中跨浏览器兼容性的最佳实践是什么?HTML5中跨浏览器兼容性的最佳实践是什么?Mar 17, 2025 pm 12:20 PM

文章讨论了确保HTML5跨浏览器兼容性的最佳实践,重点是特征检测,进行性增强和测试方法。

如何高效地在网页中为PNG图片添加描边效果?如何高效地在网页中为PNG图片添加描边效果?Mar 04, 2025 pm 02:39 PM

本文展示了使用CSS为网页中添加有效的PNG边框。 它认为,与JavaScript或库相比,CSS提供了出色的性能,详细介绍了如何调整边界宽度,样式和颜色以获得微妙或突出的效果

&lt; datalist&gt;的目的是什么。 元素?&lt; datalist&gt;的目的是什么。 元素?Mar 21, 2025 pm 12:33 PM

本文讨论了html&lt; datalist&gt;元素,通过提供自动完整建议,改善用户体验并减少错误来增强表格。Character计数:159

&lt; meter&gt;的目的是什么。 元素?&lt; meter&gt;的目的是什么。 元素?Mar 21, 2025 pm 12:35 PM

本文讨论了HTML&lt; meter&gt;元素,用于在一个范围内显示标量或分数值及其在Web开发中的常见应用。它区分了&lt; meter&gt;从&lt; progress&gt;和前

我如何使用html5&lt; time&gt; 元素以语义表示日期和时间?我如何使用html5&lt; time&gt; 元素以语义表示日期和时间?Mar 12, 2025 pm 04:05 PM

本文解释了HTML5&lt; time&gt;语义日期/时间表示的元素。 它强调了DateTime属性对机器可读性(ISO 8601格式)的重要性,并在人类可读文本旁边,增强Accessibilit

&gt; gt;的目的是什么 元素?&gt; gt;的目的是什么 元素?Mar 21, 2025 pm 12:34 PM

本文讨论了HTML&lt; Progress&gt;元素,其目的,样式和与&lt; meter&gt;元素。主要重点是使用&lt; progress&gt;为了完成任务和LT;仪表&gt;对于stati

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前By尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版