当前位置:千赢国际官网 > 千赢网页手机版登入 > js处理前端代码文件的编码问题,三个js循环的关

js处理前端代码文件的编码问题,三个js循环的关

文章作者:千赢网页手机版登入 上传时间:2019-07-12

引用了jQuery,节省了很多鼠标点击上的判断。界面显然都是照搬Windows的扫雷啦,详细的内容注释里都有,我就不啰嗦啦~

使用 NodeJS 编写前端工具时,操作得最多的是文本文件,因此也就涉及到了文件编码的处理问题。我们常用的文本编码有 UTF8 和 GBK 两种,并且 UTF8 文件还可能带有 BOM。在读取不同编码的文本文件时,需要将文件内容转换为 JS 使用的 UTF8 编码字符串后才能正常处理。

循环的三种写法:

先上截图~

BOM 的移除 BOM 用于标记一个文本文件使用 Unicode 编码,其本身是一个 Unicode 字符("uFEFF"),位于文本文件头部。在不同的 Unicode 编码下,BOM 字符对应的二进制字节如下:

<!doctype html>
<title>js循环 by 脚本之家</title>
<meta charset="utf-8"/>
<meta name="keywords" content="js循环 by 脚本之家" />
<meta name="description" content="js循环 by 脚本之家" />
</head>
<body>
//while循环
 <script type="text/javascript">
i = 1;
while (i <= 6)
{
document.write("<h"   i ">脚本之家,这是标题" i);
document.write("</h" i ">");
i  ;
}
</script>
//do_whilel循环
<script type="text/javascript">
i = 1;
do
{
document.write("<h"   i ">jb51.net ,这是标题" i);
document.write("</h" i ">");
i  ;
}
while(i<=6);
</script>
//for循环 
 <script type="text/javascript">
for(i=1;i<=6;i  )
{
 document.write("<h" i ">脚本之家,这是标题" i);
 document.write("</h" i ">");
}
</script>
</body>
</html>

图片 1

  Bytes   Encoding
----------------------------
  FE FF    UTF16BE
  FF FE    UTF16LE
  EF BB BF  UTF8

不同类型的循环

图片 2

因此,我们可以根据文本文件头几个字节等于啥来判断文件是否包含 BOM,以及使用哪种 Unicode 编码。但是,BOM 字符虽然起到了标记文件编码的作用,其本身却不属于文件内容的一部分,如果读取文本文件时不去掉 BOM,在某些使用场景下就会有问题。例如我们把几个 JS 文件合并成一个文件后,如果文件中间含有 BOM 字符,就会导致浏览器 JS 语法错误。因此,使用 NodeJS 读取文本文件时,一般需要去掉 BOM。例如,以下代码实现了识别和去除 UTF8 BOM 的功能。

JavaScript 支持不同类型的循环:
•for - 循环代码块一定的次数
•for/in - 循环遍历对象的属性
•while - 当指定的条件为 true 时循环指定的代码块
•do/while - 同样当指定的条件为 true 时循环指定的代码块

引用了jQuery,节省了很多鼠标点击上的判断

function readText(pathname) {
  var bin = fs.readFileSync(pathname);

  if (bin[0] === 0xEF && bin[1] === 0xBB && bin[2] === 0xBF) {
    bin = bin.slice(3);
  }

  return bin.toString('utf-8');
}

For 循环

界面显然都是照搬Windows的扫雷啦

GBK 转 UTF8 NodeJS 支持在读取文本文件时,或者在 Buffer 转换为字符串时指定文本编码,但遗憾的是,GBK 编码不在NodeJS自身支持范围内。因此,一般我们借助 iconv-lite 这个三方包来转换编码。使用 NPM 下载该包后,我们可以按下边方式编写一个读取 GBK 文本文件的函数。

for 循环是您在希望创建循环时常会用到的工具。

图片 3

var iconv = require('iconv-lite');

function readGBKText(pathname) {
  var bin = fs.readFileSync(pathname);

  return iconv.decode(bin, 'gbk');
}

下面是 for 循环的语法:

详细的内容注释里都有,我就不啰嗦啦~

单字节编码 有时候,我们无法预知需要读取的文件采用哪种编码,因此也就无法指定正确的编码。比如我们要处理的某些 CSS 文件中,有的用 GBK 编码,有的用 UTF8 编码。虽然可以一定程度可以根据文件的字节内容猜测出文本编码,但这里要介绍的是有些局限,但是要简单得多的一种技术。

for (语句 1; 语句 2; 语句 3)
  {
  被执行的代码块
  }

JS部分

首先我们知道,如果一个文本文件只包含英文字符,比如 Hello World,那无论用 GBK 编码或是 UTF8 编码读取这个文件都是没问题的。这是因为在这些编码下,ASCII0~128 范围内字符都使用相同的单字节编码。

语句 1 在循环(代码块)开始前执行
语句 2 定义运行循环(代码块)的条件
语句 3 在循环(代码块)已被执行之后执行

var mineArray, //地雷数组 
lastNum, //剩余雷数 
countNum, //未被揭开的方块数 
inGame = 0, //游戏状态,0为结束,1为进行中,2为初始化完毕但未开始 
startTime; //开始时间 
//以下操作1表示揭开一个方块,操作2表示标记一个小旗,操作3表示标记一个问号,操作4表示若某个方块周围的地雷全都标记完,则将其周围剩下的方块挖开 
$(function(){ 
$('#main').mouseup(function(e) { 
var clicked = $(e.target), 
id = clicked.attr('id'), 
cX = parseInt(id.substring(1, id.indexOf('-'))), //所点击方格的X坐标 
cY = parseInt(id.substring(id.indexOf('-')   1)); //所点击方格的Y坐标 
if(inGame == 1) { 
if(e.which == 1) { 
if(clicked.hasClass('hidden') && !clicked.hasClass('flag')) { 
openBlock(cX,cY); //左键点击未揭开且未插旗方块即执行操作1 
} else if(!clicked.hasClass('hidden')) { 
openNearBlock(cX,cY); //由于同时点击左右键实现起来比较麻烦,所以改成用点击左键实现操作4 
} 
} else if(e.which == 3 && clicked.hasClass('hidden')) { //右键点击操作2,如果允许使用问号标记,则可执行操作3 
if(clicked.hasClass('flag')) { 
clicked.removeClass('flag'); 
if($('#check').attr('checked')) clicked.addClass('check'); 
lastNum   ; 
countNum   ; 
} else if(clicked.hasClass('check')) { 
clicked.removeClass('check'); 
} else { 
clicked.addClass('flag'); 
lastNum --; 
countNum --; 
} 
$('#lastnum').text(lastNum); 
} 
if(lastNum == countNum) endGame(1); //因为最后剩下的方块均为雷时应直接结束游戏,因此设置为剩余雷数和未被揭开的方块数相等的时候结束游戏 
} else if(inGame == 2) { 
if(e.which == 1) { //初始化完毕后只允许点击左键开始游戏 
openBlock(cX,cY); 
inGame = 1; 
var now = new Date(); 
startTime = now.getTime(); 
timer(); 
} 
} 
}); 
$('#main').bind('contextmenu', function(){ return false; }); //阻止默认右击事件 
}); 
//初始化 
function init(x, y, mine) { 
countNum = x * y; 
inGame = 2; 
lastNum = mine; 
mineArray = new Array(y   2); 
$.each(mineArray, function(key) { 
mineArray[key] = new Array(x   2); 
}); 
for(var i = 1; i <= y; i   ) { 
for(var j = 1; j <= x; j   ) { 
mineArray[i][j] = 0; 
} 
} 
while(mine > 0) { //随机布雷,-1为有雷 
var i = Math.ceil(Math.random() * y); 
var j = Math.ceil(Math.random() * x); 
if(mineArray[i][j] != -1) { 
mineArray[i][j] = -1; 
mine --; 
} 
} 
for(var i = 1; i <= y; i   ) { //遍历地雷数组,统计每个格子四周地雷的数量 
for(var j = 1; j <= x; j   ) { 
if(mineArray[i][j] != -1) { 
if(i > 1 && j > 1 && mineArray[i - 1][j - 1] == -1) mineArray[i][j]   ; 
if(i > 1 && mineArray[i - 1][j] == -1) mineArray[i][j]   ; 
if(i > 1 && j < x && mineArray[i - 1][j   1] == -1) mineArray[i][j]   ; 
if(j < x && mineArray[i][j   1] == -1) mineArray[i][j]   ; 
if(i < y && j < x && mineArray[i   1][j   1] == -1) mineArray[i][j]   ; 
if(i < y && mineArray[i   1][j] == -1) mineArray[i][j]   ; 
if(i < y && j > 1 && mineArray[i   1][j - 1] == -1) mineArray[i][j]   ; 
if(j > 1 && mineArray[i][j - 1] == -1) mineArray[i][j]   ; 
} 
} 
} 
var block = ''; 
for(var i = 1, row = mineArray.length - 1; i < row; i   ) { 
for(var j = 1, col = mineArray[0].length - 1; j < col; j   ) { 
block  = '<div id="b'   i   '-'   j   '" style="left:'   (j - 1) * 20   'px;top:'   (i - 1) * 20   'px;" class="hidden"></div>'; 
} 
} 
$('#main').html(block).width(x * 20   1).height(y * 20   1).show(); //绘图 
$('#warning').html(''); 
$('#submenu').show(); 
$('#lastnum').text(lastNum); 
} 
//揭开方块 
function openBlock(x, y) { 
var current = $('#b'   x   '-'   y); 
if(mineArray[x][y] == -1) { 
if(inGame == 1) { //触雷时如游戏进行中,则失败结束游戏 
current.addClass('cbomb'); 
endGame(); 
} else if(inGame == 2) { //如游戏初始化后还未开始,则重新初始化地雷阵,再揭开此方块,以保证第一次点击不触雷 
init(mineArray[0].length - 2, mineArray.length - 2, lastNum); 
openBlock(x, y); 
} else { //游戏结束时需揭开全部方块,标记地雷位置 
if(!current.hasClass('flag')) current.addClass('bomb'); 
} 
} else if(mineArray[x][y] > 0) { 
if(current.hasClass('flag')) { //若在无雷的方块上标记了小旗,如果周围的广场执行操作4时波及到此方块,则触发失败结束游戏 
current.addClass('wrong'); 
if(inGame) endGame(); 
} else { 
current.html(mineArray[x][y]).addClass('num'   mineArray[x][y]).removeClass('hidden'); //显示周边的地雷数量 
if(current.hasClass('check')) current.removeClass('check'); 
if(inGame) countNum --; 
} 
} else { 
if(current.hasClass('flag')) { //同上 
current.addClass('wrong'); 
if(inGame) endGame(); 
} else { 
current.removeClass('hidden'); 
if(current.hasClass('check')) current.removeClass('check'); 
if(inGame) { //点击到周边无雷的方块时,自动揭开周围方块 
countNum --; 
var row = mineArray.length - 2, col = mineArray[0].length - 2; 
if(x > 1 && y > 1 && $('#b'   (x - 1)   '-'   (y - 1)).hasClass('hidden')) openBlock(x - 1, y - 1); 
if(x > 1 && $('#b'   (x - 1)   '-'   y).hasClass('hidden')) openBlock(x - 1, y); 
if(x > 1 && y < col && $('#b'   (x - 1)   '-'   (y   1)).hasClass('hidden')) openBlock(x - 1, y   1); 
if(y < col && $('#b'   x   '-'   (y   1)).hasClass('hidden')) openBlock(x, y   1); 
if(x < row && y < col && $('#b'   (x   1)   '-'   (y   1)).hasClass('hidden')) openBlock(x   1, y   1); 
if(x < row && $('#b'   (x   1)   '-'   y).hasClass('hidden')) openBlock(x   1, y); 
if(x < row && y > 1 && $('#b'   (x   1)   '-'   (y - 1)).hasClass('hidden')) openBlock(x   1, y - 1); 
if(y > 1 && $('#b'   x   '-'   (y - 1)).hasClass('hidden')) openBlock(x, y - 1); 
} 
} 
} 
} 
//揭开格子邻近确认无雷的方块 
function openNearBlock(x, y) { 
var flagNum = 0, hiddenNum = 0; 
for(i = x - 1; i < x   2; i   ) { 
for(j = y - 1; j < y   2; j   ) { 
if(mineArray[i][j] != undefined) { 
if($('#b'   i   '-'   j).hasClass('flag')) flagNum   ; //统计方块周围的旗帜数和未揭开的方块数 
if($('#b'   i   '-'   j).hasClass('hidden')) hiddenNum   ; 
} 
} 
} 
if(flagNum == mineArray[x][y] && hiddenNum > flagNum) { //旗帜数和雷数相等且有未揭开方块且未插旗的方块时,则揭开它 
for(i = x - 1; i < x   2; i   ) { 
for(j = y - 1; j < y   2; j   ) { 
if(mineArray[i][j] >= 0 && $('#b'   i   '-'   j).hasClass('hidden')) openBlock(i, j); 
} 
} 
} 
} 
//计时 
function timer(){ 
if(inGame == 1) { //只在游戏进行中计时 
var now = new Date(), 
ms = now.getTime(); 
$('#time').text(Math.ceil((ms - startTime) / 1000)); 
if(inGame == 1) setTimeout(function() { timer(); }, 500); 
} else if(inGame == 2) { 
$('#time').text('0'); 
} 
} 
//结束游戏 
function endGame(isWin) { 
inGame = 0; 
for(var i = 1, row = mineArray.length - 1; i < row; i   ) { 
for(var j = 1, col = mineArray[0].length - 1; j < col; j   ) { 
if(isWin) { 
if($('#b'   i   '-'   j).hasClass('hidden') && !$('#b'   i   '-'   j).hasClass('flag')) $('#b'   i   '-'   j).addClass('flag'); 
lastNum = 0; 
$('#lastnum').text(lastNum); 
} else { 
openBlock(i, j); 
} 
} 
} 
$('#warning').text(isWin ? 'You Win!' : 'You Lose!'); 
} 

反过来讲,即使一个文本文件中有中文等字符,如果我们需要处理的字符仅在 ASCII0~128 范围内,比如除了注释和字符串以外的JS代码,我们就可以统一使用单字节编码来读取文件,不用关心文件的实际编码是 GBK 还是 UTF8。以下示例说明了这种方法。

实例

HTML部分

  1. GBK编码源文件内容:

复制代码 代码如下:

<div id="menu"> 
<a href="javascript:;" onclick="init(10,10,10);">初级</a> 
<a href="javascript:;" onclick="init(16,16,40);">中级</a> 
<a href="javascript:;" onclick="init(30,16,99);">高级</a> 
<input type="checkbox" id="check" /><label for="check">是否使用标记(?)</label> 
</div> 
<div id="submenu"> 
剩余雷数: 
时间:秒 

</div> 
<div id="main"></div> 
  var foo = '中文';

for (var i=0; i<5; i )
  {
  x=x "The number is " i "<br>";
  }

CSS部分

  1. 对应字节:

亲自试一试
 
从上面的例子中,您可以看到:

body{background:#fff;font-size:14px;} 
#submenu{display:none;} 
#warning{color:#ff0000;} 
#main{background:#ddd;border:1px solid #888;display:none;position:relative;} 
#main div{border:1px solid #888;font-weight:bold;height:19px;height:21px9;line-height:18px;cursor:default;position:absolute;text-align:center;width:19px;width:21px9;} 
.hidden{background:url(mine.gif) 0 0;} 
.flag{background:url(mine.gif) -19px 0;} 
.check{background:url(mine.gif) -38px 0;} 
.bomb{background:url(mine.gif) -57px 0;} 
.cbomb{background:url(mine.gif) -57px 0 #ff0000;} 
.wrong{background:url(mine.gif) -76px 0;} 
.num1{color:#0000ff;} 
.num2{color:#008000;} 
.num3{color:#ff0000;} 
.num4{color:#000080;} 
.num5{color:#800000;} 
.num6{color:#008080;} 
.num7{color:#000000;} 
.num8{color:#808080;} 
  76 61 72 20 66 6F 6F 20 3D 20 27 D6 D0 CE C4 27 3B

Statement 1 在循环开始之前设置变量 (var i=0)。
Statement 2 定义循环运行的条件(i 必须小于 5)。
Statement 3 在每次代码块已被执行后增加一个值 (i )。

本文由千赢国际官网发布于千赢网页手机版登入,转载请注明出处:js处理前端代码文件的编码问题,三个js循环的关

关键词: 千赢国际官网 千亿国际qy8