分享
 
 
 

jscript模拟的“控制台”程序

王朝html/css/js·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

无聊的时候想到用jscript模拟Console程序,结果试了一下,觉得还蛮好玩的:P

实现了一个jscript“控制台”类

在读代码前先放出三个Demo:

http://akira.bigwww.com/Silver%20Luna/Demos/ConsoleDemo.html

通过“控制台”输入两个数求和

http://akira.bigwww.com/Silver%20Luna/Demos/ConsoleDemo2.html

通过“控制台”输入一个句子,统计字符类型和数量

http://akira.bigwww.com/Silver%20Luna/Demos/ConsoleDemo3.html

一个可以通过键盘敲入命令回车执行的模拟,还支持

begin

Codes...

end

的模式 :)

下面是程序代码:

//控制台类,模拟运行在控制台上的程序,可以控制“标准输入输出流”(程序模拟)

//使用方法:在页面上包含Console.js文件,构造Console对象,定义Main()函数,在Main函数中写控制命令

//版本:1.00

//作者:Akira

//编写日期:2004-11-19

function Console(page, consoleName)

{

//静态成员

Console.KEY_ENTER = 13; //回车键

Console.KEY_RETURN = 13; //回车

Console.KEY_NEWLINE = 10; //换行

Console.KEY_TAB = 9; //TAB键

Console.KEY_BACKSPACE = 8; //退格键

Console.KEY_LEFT = 37; //左移

Console.KEY_RIGHT = 38; //右移

Console.KEY_UP = 39; //上移

Console.KEY_DOWN = 40; //下移

//初始化Page

if (page == null)

{

page = self;

}

if (page != self)

{

//do sth here...

throw new Error("参数错误:目前版本不支持为其他窗体对象初始化控制台\n请使用self参数");

}

this.page = page;

//输入输出流属性,用字符串数组模拟流

this.stream = new Object();

this.stream.stdin = new Array(); //标准输入流

this.stream.stdout = new Array(); //标准输出流

this.stream.stderr = new Array(); //标准错误流

this.stream.stdin.opened = false; //判断当前输入流是否开启,开启=允许写入

this.stream.stdin.ReadOffset = 0; //判断当前输入流偏置,Read()方法使用

this.stream.semaphores = 0; //流信号量,用来控制输出流显示,当调用输入函数时,信号量增加,

//当信号量大于stdin成员数目的时候,抛出异常阻塞标准输出流,用以模拟输入等待

Console.prototype.Signal = function()

{

if(this.stream.semaphores == this.stream.stdin.length)

{

return true;

}

if(this.stream.semaphores > this.stream.stdin.length)

{

throw new WaitForInput(); //抛出异常阻止程序往下执行,用以等待输入

}

return false;

}

this.body = page.document.body;

if (this.body == null)

{

throw new Error("控制台缺初始化失败,检查主体文档是否缺少BODY标记");

}

this.page.document.title += "——Javascript控制台";

this.page.PageLoadEventSender = this;

this.body.onload = function(){this.PageLoadEventSender.PageLoad(this.PageLoadEventSender,this.PageLoadEventSender.page.event);} //定义PageLoad事件

this.page.ResizeEventSender = this;

this.body.onresize = function(){this.ResizeEventSender.OnResize(this.ResizeEventSender,this.ResizeEventSender.page.event);}

this.ConsoleMain = page.document.getElementById(consoleName); //可以通过参数指定初始化对象TEXTAREA的名称,这样可以把控制台

//主窗口嵌入在网页中

//如果没有指定获得TEXTAREA对象,则建立控制台主窗口,并让窗口占据整个页面

if (this.ConsoleMain == null)

{

this.body.style.background = "#000000";

this.page.document.bgColor = "#000000";

this.ConsoleMain = page.document.createElement("textarea");

page.document.body.appendChild(this.ConsoleMain);

this.ConsoleMain.style.width="100%";

this.ConsoleMain.style.height="100%";

this.ConsoleMain.style.overflowX="hidden";

this.ConsoleMain.style.overflowY="hidden";

this.ConsoleMain.style.border="0px";

this.ConsoleMain.style.background="#000000";

this.ConsoleMain.style.color="C0C0C0";

}

if (this.ConsoleMain.tagName.toUpperCase() != "TEXTAREA")

{

throw new Error("控制台主窗口类型错误,主窗口对象必须为TEXTAREA类型");

}

this.ConsoleMain.KeyPressSender = this; //KeyPress事件

this.ConsoleMain.onkeypress = function(){this.KeyPressSender.ConsoleMain_KeyPress(this.KeyPressSender, this.KeyPressSender.page.event);}

this.ConsoleMain.KeyUpSender = this; //KeyUp事件

this.ConsoleMain.onkeyup = function(){this.KeyUpSender.ConsoleMain_KeyUp(this.KeyUpSender, this.KeyUpSender.page.event);}

this.ConsoleMain.KeyDownSender = this; //KeyDown事件

this.ConsoleMain.onkeydown = function(){return(this.KeyDownSender.ConsoleMain_KeyDown(this.KeyDownSender, this.KeyDownSender.page.event));}

this.ConsoleMain.ClickSender = this; //Click事件,用来避免光标位置随鼠标点击而改变

this.ConsoleMain.onclick = function(){this.ClickSender.ConsoleMain_Click(this.ClickSender, this.ClickSender.page.event);}

//Event Handlers

Console.prototype.PageLoad = function(sender, event) //PageLoad事件处理,调用this.Main()方法用来初始化控制台

{

//create frameConsole

this.Main();

}

Console.prototype.OnResize = function(sender, event) //Resize事件处理,将文字正确显示在控制台顶部

{

this.SetCursor();

}

Console.prototype.ConsoleMain_KeyDown = function(sender, event)

{

if (event.keyCode == Console.KEY_TAB) //处理TAB键,避免主窗口失去焦点

{

this.ConsoleMain.value += "\t";

if (!this.stream.stdin.opened)

{

this.stream.stdin.push("\t");

this.stream.stdin.opened = true;

}

else

{

this.stream.stdin[this.stream.stdin.length - 1] += "\t";

}

return false;

}

if (event.keyCode == Console.KEY_LEFT

||event.keyCode == Console.KEY_RIGHT

||event.keyCode == Console.KEY_UP

||event.keyCode == Console.KEY_DOWN) //忽略方向键,锁定光标

{

return false;

}

return true;

}

Console.prototype.ConsoleMain_KeyUp = function(sender, event)

{

if (event.keyCode == Console.KEY_ENTER) //处理回车键结束流的写入

{

if(!this.stream.stdin.opened) //忽略空行和连续回车

return;

else

{

this.stream.stdin.opened = false;

this.Main(); //结束流的写入,并让程序继续往下执行

}

}

if (event.keyCode == Console.KEY_BACKSPACE) //处理退格键

{

if (!this.stream.stdin.opened) //忽略当前流为空时的退格键

{

return;

}

else

{

if (this.stream.stdin[this.stream.stdin.length - 1].length == 0)

{

return;

}

this.stream.stdin[this.stream.stdin.length - 1] = this.stream.stdin[this.stream.stdin.length - 1].substr(0, this.stream.stdin[this.stream.stdin.length - 1].length - 1);

if (this.stream.stdin[this.stream.stdin.length - 1].length == 0)

{

this.stream.stdin.length--;

this.stream.stdin.opened = false;

}

}

}

}

Console.prototype.ConsoleMain_KeyPress = function(sender, event) //键盘事件,将字符写入流

{

if (!this.stream.stdin.opened) //New Stream

{

if (event.keyCode != Console.KEY_ENTER)

{

this.stream.stdin.push(String.fromCharCode(event.keyCode));

this.stream.stdin.opened = true;

}

}

else

{

if (event.keyCode != Console.KEY_ENTER)

this.stream.stdin[this.stream.stdin.length - 1] += String.fromCharCode(event.keyCode);

}

}

Console.prototype.ConsoleMain_Click = function(sender, event)

{

this.SetCursor();

}

//Methods

Console.prototype.init = function() //初始化方法,在this.Main()中被调用

{

//this.ConsoleMain.value="控制台初始化完成...\n";

this.ConsoleMain.contentEditable = true;

this.stream.semaphores = 0;

this.stream.stdin.ReadOffset = 0;

this.stream.stdin.opened = false;

}

Console.prototype.WriteLine = function(msg) //写入一行文本到标准输出流

{

if (this.Signal())

{

this.ConsoleMain.value+=msg+"\n";

this.stream.stdout.push(msg+"\n");

}

}

Console.prototype.Write = function(msg) //写入一个字符串到标准输出流

{

if (this.Signal())

{

this.ConsoleMain.value+=msg;

this.stream.stdout.push(msg);

}

}

Console.prototype.Error = function(msg) //写入错误信息到标准错误流

{

if (this.Signal())

{

this.ConsoleMain.value+=msg;

this.stream.stderr.push(msg);

}

}

Console.prototype.ReadLine = function() //从标准输入流读取一行

{

if (this.Signal())

{

this.SetCursor(); //光标移至输入位置

throw new WaitForInput(); //抛出异常阻止程序往下执行,用以等待输入

}

this.stream.semaphores++;

if (this.stream.semaphores <= this.stream.stdin.length)

{

if (isNaN(this.stream.stdin[this.stream.semaphores - 1])) //非数字返回对象

{

return this.stream.stdin[this.stream.semaphores - 1];

}

else

{

return this.stream.stdin[this.stream.semaphores - 1] - 0; //数字返回数值

}

}

}

Console.prototype.SetCursor = function()

{

this.ConsoleMain.focus();

var range = this.ConsoleMain.createTextRange();

range.moveStart('character',this.ConsoleMain.value.lenght);

range.collapse(false);

range.select();

}

Console.prototype.Read = function() //从标准输入流读取下一个字符

{

if (this.Signal() && this.stream.stdin.ReadOffset == 0)

{

this.ConsoleMain.focus();

var range = this.ConsoleMain.createTextRange();

range.moveStart('character',this.ConsoleMain.value.lenght);

range.collapse(false);

range.select();

this.stream.stdin.push("");

this.stream.stdin.opened=true;

throw new WaitForInput(); //抛出异常阻止程序往下执行,用以等待输入

}

else if (this.stream.semaphores <= this.stream.stdin.length)

{

if (this.stream.stdin.ReadOffset == 0) //读取流的第一个字符,信号量增加

{

this.stream.semaphores++;

}

if (this.stream.stdin.ReadOffset < this.stream.stdin[this.stream.semaphores - 1].length)

{

return this.stream.stdin[this.stream.semaphores - 1].charCodeAt(this.stream.stdin.ReadOffset++);

}

else if(this.stream.stdin.ReadOffset == this.stream.stdin[this.stream.semaphores - 1].length) //恢复在流的末尾被忽略的回车和换行

{

this.stream.stdin.ReadOffset++;

return Console.KEY_RETURN;

}

else if(this.stream.stdin.ReadOffset == this.stream.stdin[this.stream.semaphores - 1].length + 1)

{

this.stream.stdin.ReadOffset=0;

return Console.KEY_NEWLINE;

}

else

{

throw new Error("Stack over flow! Read Error!");

}

}

}

Console.prototype.Main = function()

{

this.init();

try

{

Main();

if (this.Signal())

{

this.Dispose();

}

}

catch(e)

{

if (e instanceof WaitForInput)

{

}

else

{

this.Error("错误:" + e.number + "," + e.name + ":" + e.message); //将错误信息写入标准错误流

this.Dispose();

}

}

}

Console.prototype.Dispose = function() //结束控制台流程,按任意键关闭窗口

{

this.ConsoleMain.contentEditable = false;

this.ConsoleMain.focus();

this.Write("\nPress any key to continue...\n");

this.ConsoleMain.KeyDownSender = this;

this.ConsoleMain.onkeydown = function(){this.KeyDownSender.page.close();return false;}

}

}

//等待输入的“异常”类,用来在要求用户输入的时候阻塞程序的运行。

function WaitForInput()

{

}WaitForInput.prototype = new Error();

//调试控制台——可运行和调试javascript程序段

//版本:0.01 Demo

//作者:Akira

//日期:2004-11-19

function DebugConsole()

{

DebugConsole.prototype.RunCommand = function(command)

{

if (this.Signal())

{

var regexp = new RegExp("document.writeln","g");

command = command.replace(regexp, "this.WriteLine");

regexp = new RegExp("document.write","g");

command = command.replace(regexp, "this.Write");

try

{

eval(command);

}

catch(e)

{

this.Error("指令无效:" + e.number + "," + e.name + ":" + e.message + "\n");

}

}

}

DebugConsole.prototype.Start = function()

{

this.WriteLine("调试控制台初始化...完成!");

var command = "";

var process = "";

var runProc = false;

while ((command = this.ReadLine()) != "stop")

{

if (command == "begin")

{

process="";

runProc = true; //执行一组命令

continue;

}

if (command == "end")

{

this.RunCommand(process);

runProc = false;

continue;

}

if (command.charAt(0) == "=")

{

command = "this.WriteLine(" + command.substring(1) + ");";

}

if (!runProc)

{

this.RunCommand(command); //执行一条命令

}

else

{

process += command;

}

}

}

}DebugConsole.prototype = new Console();

//这个控制台目前的缺点是:1)异常信息无法显示行号 2)不能在新开窗口中动态建立控制台

//有待改进......

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有