JS是基于对象的(Object-Based)脚本语言,而不是面向对象(Object-Oriented)中所使用的那个对象,之所以说JS是一门基于对象的编程语言,是因为它没有提供抽象,继承,封装等面向对象语言的很多功能,而是把其他语言所创建的复杂对象统一起来,从而形成一个非常强大的对象系统.
对象是编程语言中很重要的特征之一,JS是基于对象的编程语言,所以支持面向对象的所有特性,灵活使用这些对象能够实现丰富而强大的功能,下面我们首先来看如何创建一个自定义类,代码如下:
<body>
<script type="text/javascript">
function MyClass(name,age){ //定义类,类名MyClass
this.name = name;
this.age = age;
this.print = function(name,age){ //定义的一个函数体
document.write("姓名: " + this.name + "年龄: " + this.age);
}
}
var temp = new MyClass("lyshark",22); //实例化一个对象
temp.print() //调用对象中的函数体
</script>
</body>
上述代码执行后会打印出姓名和年龄,但是这种写法在实例化对象时,系统会为每个对象中均保存了一个相同的print()
函数,从而浪费内存,使用原型写法可以解决该问题,改进代码如下:
<body>
<script type="text/javascript">
function MyClass(name,age){
this.name = name;
this.age = age;
}
MyClass.prototype = {
print:function(){
document.write("姓名: " + this.name + "年龄: " + this.age);
}
}
var temp = new MyClass("lyshark",22); //实例化一个对象
temp.print() //调用对象中的函数体
</script>
</body>
Date对象用于处理日期和时间,提供了很多高级的处理方法,可以用来帮助网站制作人员读取和设置日期和时间以及定义日期和时间的显示格式等,在JS中使用Date对象前需要先创建对象实例,然后才可以使用.
读取日期方法: 下面是几个常用的日期获取方法和说明信息,设置日期一般不会用到.
<body>
<script type="text/javascript">
var now = new Date();
document.write("当前年份: " + now.getFullYear() + "<br>");
document.write("当前月份: " + now.getMonth() + "<br>");
document.write("当前日期: " + now.getDate() + "<br>");
document.write("当前周几: " + now.getDay() + "<br>");
document.write("当前小时: " + now.getHours() + "<br>");
document.write("当前分钟: " + now.getMinutes() + "<br>");
document.write("当前秒数: " + now.getSeconds() + "<br>");
document.write("当前时间戳: " + now.getTime() + "<br>");
</script>
</body>
data对象转换: 将获取到的日期时间戳,通过不同的方式展示出来.
<body>
<script type="text/javascript">
var now = new Date();
document.write("采用UTC时区表示: " + now.toUTCString(now.getTime()) + "<br>");
document.write("采用本地时区表示: " + now.toLocaleString(now.getTime()) + "<br>");
document.write("采用本地时区表示日期: " + now.toDateString(now.getTime()) + "<br>");
document.write("采用本地中国标准时间: " + now.toTimeString(now.getTime()) + "<br>");
document.write("采用本地时区表示2019/02/21: " + now.toLocaleDateString(now.getTime()) +"<br>");
document.write("采用本地时区表示4:01:55 : " + now.toLocaleTimeString(now.getTime()) +"<br>");
</script>
</body>
Math对象的方法是编程过程中经常使用的数学函数,如三角函数、平方根、四舍五入等,对象的方法同Math对象的属性一样,属于Math对象本身,在引用这些方法时,直接使用Math而不用使用Math对象的实例名称.
Math常用方法: 一些常用的Math数值计算方法.
<body>
<script type="text/javascript">
document.write("产生随机数[0-9]: " + parseInt(10 * Math.random()) + "<br>");
document.write("产生随机数[任意数字]: " + String.fromCharCode(97 * Math.random()) + "<br>");
document.write("返回数值的绝对值: " + Math.abs(3.161592654) + "<br>");
document.write("返回x和y中较大的一个数: " + Math.max(10,87) + "<br>");
document.write("返回x和y中较小的一个数: " + Math.min(10,87) + "<br>");
document.write("返回x的y次方根: " + Math.pow(10,87) + "<br>");
document.write("对x进行四舍五入: " + Math.round(12.425) + "<br>");
document.write("返回x的平方根: " + Math.sqrt(10) + "<br>");
</script>
</body>
正则表达式并非一门专用语言,但也可以看作是一种语言,它可以让用户通过使用一系列普通字符和特殊字符构建能明确描述文本字符串的匹配模式.除了简单描述这些模式之外,正则表达式解释引擎通常可用于遍历匹配,并使用模式作为分隔符来将字符串解析为子字符串,或以智能方式替换文本或重新设置文本格式.正则表达式为解决与文本处理有关的许多常见任务提供了有效而简捷的方式.
正则匹配: 一些常用的正则匹配函数,正则表达式是通用的,请自行百度.
<body>
<script type="text/javascript">
var string = "hello123world567mynames;"
document.write("Match全局匹配: " + string.match(/\d+/g) + "<br>");
document.write("Search取出第一个结果的索引值: " + string.search(/\d+/g) + "<br>");
document.write("Split取出第一个结果的索引值: " + string.split(/\d+/g) + "<br>");
var reg = RegExp("\d+",g);
document.write("测试字符是否存在: " + reg.test("names123123lyshark456,789") + "<br>");
</script>
</body>
Window 对象称之为窗口对象,位于浏览器对象模型的最顶层,代表整个浏览器窗口,是Web浏览所有内容的主容器,只要打开一个浏览器窗口,就创建了一个Window对象,即使没有在窗口上显示任何内容.
打开关闭窗口: 利用window.open()
打开网页,window.close()
关闭打开的网页.
msg.html
<body bgcolor="#bc8f8f">
<table width="300" height="200" border="0" cellpadding="0" cellspacing="0">
<tr>
<td valign="top"> 网页通知
<p> 这是一个通知信息,您可以忽略掉</p>
</td>
</tr>
</table>
</body>
index.html
<body>
<input type="button" value="弹出通知" onclick="msg()">
<input type="button" value="关闭通知" onclick="msg_close()">
<script type="text/javascript">
function msg(){
open("msg.html","通知",height=50,width=30,top=20,left=10);
}
function msg_close() {
close()
}
</script>
</body>
弹出提示框: 点击按钮自动弹出Window.alert()
提示消息框.
<body>
<input type="button" value="点击弹窗" onclick="msg()">
<script type="text/javascript">
function msg(){
alert("这是一个提示框...")
}
</script>
</body>
弹出选择框: Window.confirm()
弹出一条信息让用户确认,包括确认和取消按钮.
<body>
<input type="button" value="弹窗口" onclick="msg()">
<script type="text/javascript">
function msg(){
if(confirm("请输入你的选项..")){
alert("感谢您的参与..") //确认按钮执行语句
}else{
alert("取消语句..") //取消按钮执行语句
}
}
</script>
</body>
弹出输入框: window.prompt()
用于弹出一个输入框,可以让用户输入一些信息.
<body>
<script type="text/javascript">
var passwd = prompt("请输入密码(密码是123): ","");
while(passwd !="123"){
passwd = prompt("密码错误,请重新输入: ");
}
if(passwd =="123"){alert("密码正确...")}
</script>
</body>
设置单次定时器: 以下案例,实现当点击删除按钮时,屏幕提示删除成功,在5秒后自动的隐藏标签.
<body>
<div id="status" style="color: red;"> </div>
<input type="button" value="删除定时" onclick="DeleteStatus()">
<script type="text/javascript">
function DeleteStatus(){
var temp = document.getElementById("status");
temp.innerText = "删除成功了...";
setTimeout(function(){
temp.innerText = "";
},50000); //设置5秒后执行清空标签
}
</script>
</body>
设置循环定时器: setIntercal()设置定时器
,clearInterval()清除定时器
,定时器用于周期性执行.
<body>
<input type="text" id="clock">
<input type="button" value="开始执行" onclick="begin_func()">
<input type="button" value="取消执行" onclick="end_func()">
<script type="text/javascript">
function begin(){
var now = new Date();
var stime = now.getTime()
var ret = document.getElementById("clock");
ret.value=stime;
}
var ID; //定义全局变量,后期用于清楚定时器
function begin_func(){
ID =setInterval(begin,1000); //每隔1秒执行一次,设置定时器
}
function end_func(){
clearInterval(ID); //取消一秒内执行,清除定时器
ID = undefined;
}
</script>
</body>
## JavaScript DOM编程
文档对象模型 (Document Object Model,DOM) 是一种W3C标准所有的现代浏览器都支持DOM,DOM用于HTML和XML文档的编程接口,它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式.最为关心的是,DOM把网页和脚本以及其他的编程语言联系了起来,DOM属于浏览器,而不是JavaScript语言规范里的规定的核心内容.Dom+JavaScript就能使网页动起来,一般使用JQuery来做这事,JQuery封装了JavaScript+Dom变得更为简单,这里我们只需要了解一些基本内容.
GetElementById: 根据ID号获取一个标签,这种方式是最常用的.
<body>
<div id="MyDiv"> hello world </div>
<script type="text/javascript">
var temp = document.getElementById("MyDiv");
document.write("获取到的结果: " + temp.innerText);
</script>
</body>
getElementsByName: 根据自定义标签alex=MyDiv
属性获取标签集合.
<body>
<div alex="MyDiv"> <b> hello lyshark </b> </div>
<script type="text/javascript">
var names = document.getElementsByName("alex"); //通过自定义的名称找标签
names.innerText = "www.baidu.com"; //改变元素标签名称
document.write("修改后的内容:" + names.innerText);
</script>
</body>
getElementsByClassName: 根据class类名称属性获取标签集合.
<body>
<div clas="MyClass"> <b> hello lyshark </b> </div>
<script type="text/javascript">
var names = document.getElementsByClassName("MyClass"); //通过类名称找出标签
names.innerText = "www.baidu.com"; //改变元素标签名称
document.write("修改后的内容:" + names.innerText);
</script>
</body>
getElementsByTagName: 根据标签名name="MyDiv"
来获取标签集合.
<body>
<div name="MyDiv"> <b> hello lyshark </b> </div>
<script type="text/javascript">
var names = document.getElementsByName("MyDiv"); //通过标签名称找出标签
names.innerText = "www.baidu.com"; //改变元素标签名称
document.write("修改后的内容:" + names.innerText);
</script>
</body>
innerText: 该方式只能对单纯的标签进行操作,如果标签中嵌入了其他标签,那么该方式会自动过滤掉标签格式.
<body>
<div id="lyshark">hello world</div>
<script type="text/javascript">
var temp = document.getElementById("lyshark"); //通过标签ID获取标签句柄
document.write("原来的内容: " + temp.innerText + "<br>"); //获取标签中原始的内容
temp.innerText = "alex" //修改标签中的内容为alex
document.write("修改后的内容: " + temp.innerText + "<br>"); //获取修改后的标签内容
</script>
</body>
innerHTML: 该方式不但可以修改文本,还可以同时修改HTML的嵌套标签,修改时应加上标签格式.
<body>
<div id="lyshark"> <b> hello lyshark </b> </div>
<script type="text/javascript">
var temp = document.getElementById("lyshark"); //通过标签ID获取标签句柄
document.write("原来的内容: " + temp.innerHTML + "<br>"); //获取标签中原始的内容
temp.innerHTML = '<b> hello alex </b>' //修改标签中的内容为alex
document.write("修改后的内容: " + temp.innerHTML + "<br>"); //获取修改后的标签内容
</script>
</body>
inner 循环修改: 通过使用数组的形式,可以实现循环修改元素,比如以下循环修改name="MyDiv"
的所有标签内容.
<body>
<div name="MyDiv"> <b> hello lyshark </b> </div>
<div name="MyDiv"> <b> hello lyshark </b> </div>
<div name="MyDiv"> <b> hello lyshark </b> </div>
<div name="MyDiv"> <b> hello lyshark </b> </div>
<script type="text/javascript">
var names = document.getElementsByName("MyDiv"); //通过标签名称找出标签
//id.innerText = "www.mkdirs.com"; 不生效:原因是标签名称重复,需要使用数组
names[0].innerText = "www.mkdirs.com"; //改变第1个元素标签名称
names[1].innerText = "www.mkdirs.com"; //改变第2个元素标签名称
//------------------------------------------------
//通过循环修改多个标签
document.write("总共有标签数: " + names.length); //可以统计总共标签数量
for(var item in names){
names[item].innerText = "www.mkdirs.com"; //这里写批量修改的内容
}
</script>
</body>
CreateElement 创建标签: 使用最原始的方式创建标签,实现在父容器div id=tags
中,动态的添加a标签.
< -------------------------[方式1]------------------------- >
<body>
<div id="MyDiv"> </div> <!--指定一个父容器-->
<script type="text/javascript">
var tag = document.createElement("a"); //指定标签格式:这里是a标签
tag.innerText = "点我跳转"; //设置标签名称
tag.href = "http://www.baidu.com"; //设置跳转地址
var id1 = document.getElementById("MyDiv"); //获取标签的对象
id1.appendChild(tag) //放到标签里面
</script>
</body>
< -------------------------[方式2]------------------------- >
<body>
<div id="MyDiv"> </div> <!--指定一个父容器-->
<script type="text/javascript">
var tag = "<a class='c1' href='http://www.baidu.com'>点我啊</a>";
var id1 =document.getElementById("MyDiv"); //加到这个标签的里面
id1.innerHTML = tag; //直接通过inner追加进去
</script>
</body>
修改类属性: 分别新建两个CSS属性,并通过className
方法,实现后期对类属性的修改.
<head>
<style type="text/css">
.show_table{
display: block;
background-color: red;
}
.hide_table{
display: none;
}
</style>
</head>
<body>
<div id="MyDiv" class="show_table"> hello world </div> <!--指定修改的标签-->
<script type="text/javascript">
var ids = document.getElementById("MyDiv"); //通过ID找到标签
ids.className = "hide_table"; //指定使用hid_table的CSS属性
</script>
</body>
修改标签属性: 修改DIV标签id=MyDiv
的标签属性,将name=lyshark
修改为name=hello
.
<body>
<div id="MyDiv" name="lyshark"> hello world </div> <!--准备修改的标签-->
<script type="text/javascript">
var ids = document.getElementById("MyDiv"); //找到DIV标签
document.write("当前 Name= " + ids.getAttribute('name')); //找到div1标签里面的name属性
ids.setAttribute('name','hello'); //将name属性修改为name=hello
document.write("修改后 Name= " + ids.getAttribute('name')); //修改后,再次打印出结果
</script>
</body>
修改标签样式: 修改标签的CSS代码的格式,可以修改多个,但是标签中必须存在该字段,否则无法修改.
<body>
<div id="MyDiv" name="lyshark" style="background-color: red "> hello world </div>
<script type="text/javascript">
var ids = document.getElementById("MyDiv"); //找到DIV标签
ids.style.backgroundColor = "green"; //将背景色改成绿色
</script>
</body>
伪造表单提交: 自己实现一个submit的表单提交功能,自己定义提交按钮的功能.
<body>
<form id="MyForm">
<input type="text">
<input type="submit" value="submit提交">
<a onclick="Submit()">自定义提交</a>
</form>
<script type="text/javascript">
function Submit(){
var form = document.getElementById("MyForm");
form.submit();
}
</script>
</body>
## JavaScript 事件绑定
JavaScript 的事件和事件驱动为网页增添了丰富的交互性,事件是用户在操作浏览器的过程中,由用户触发或由浏览器自身触发的动作,浏览器捕获这些动作,并根据用户编程时设置的对应这些动作的事件处理程序,触发相应的处理过程,从而实现交互过程,浏览器在程序运行的大部分时间都等待交互事件的发生,并在发生时,自动的调用事件处理函数,完成整个处理过程.
keyDown: 当键盘按下某个键时会触发KeyDown事件,用于浏览器窗体,图像,超链接,文本区域.
<body>
<input type="text" name="text" onkeydown="func_keydown()">
<script type="text/javascript">
function func_keydown() {
alert("你按下了一个键..")
}
</script>
</body>
keyUp: 当键盘松开某个键时会触发Keyup事件,用于浏览器窗体,图像,超链接,文本区域.
<body>
<input type="text" name="text" onkeyup="func_keyup()">
<script type="text/javascript">
function func_keyup() {
alert("你按松开了一个键..")
}
</script>
</body>
KeyPress: 当键盘上同时按下一个键并且同时弹出,则执行指定的函数.
<body>
<input type="text" name="text" onkeypress="func_keypress()">
<script type="text/javascript">
function func_keypress() {
alert("同时按下并弹出..")
}
</script>
</body>
Resize: 当浏览器窗口或帧的大小发生变化时触发Resize事件.
<body onresize="mesg()">
<script type="text/javascript">
function mesg() {
document.write("窗口大小已被改变了..." + "<br>")
}
</script>
</body>
keycode: 用户在body区域中按下空格键,触发弹出信息框.
<body onkeypress="keycode()">
<script type="text/javascript">
function keycode() {
if(window.event.keyCode == 32){
alert("您按下了空格...");
}
}
</script>
</body>
Click: 鼠标在一个对象上左键点击触发Click
事件,对象包括button,document,checkbox,link,radio,submit.
<body>
<input type="button" id="button1" value="按钮1" onclick="alert('按钮1被按下了...')">
<input type="button" id="button2" value="按钮2" onclick="alert('按钮2被按下了...')">
<script type="text/javascript">
</script>
</body>
MouseDown&MouseUP: 当我们按下鼠标,系统触发MouseDown
事件,释放鼠标时自动触发MouseUP
事件.
<body>
<input type="button" value="点我" onmousedown="down()">
<input type="button" value="点我" onmouseup="up()">
<script type="text/javascript">
function down() {
document.write("你按下了按键...")
}
function up() {
document.write("你释放了按键...")
}
</script>
</body>
MouseOver&MouseOut: 鼠标指针到达一个对象之上时,触发MouseOver
事件,鼠标离开时触发MouseOut
事件.
<body>
<input type="submit" value="鼠标在按钮上" onmouseover="in_over()"></input>
<input type="submit" value="鼠标离开按钮" onmouseout="out_over()"></input>
<script type="text/javascript">
function in_over() {
alert("鼠标在按钮上...")
}
function out_over(){
alert("鼠标离开按钮...")
}
</script>
</body>
OnClick: 通用事件,可以绑定到任何可以操作的标签中,当事件触发后,执行对应的函数体.
<body>
<input type="button" value="弹窗" onclick="show()">
<script type="text/javascript">
function show(){
alert("触发弹窗一个窗口提示...")
}
</script>
</body>
Focus&Blur: 当屏幕上的光标进入对象区域内时触发focus
事件,反之当光标离开时触发blur
事件.
<body>
<input onfocus="Focus(this);" onblur="Blur(this);"
id="search" value="请输入关键字" style="color: gray;" />
<script type="text/javascript">
function Focus(ths){ //光标来到执行
ths.style.color = "black";
if(ths.value == '请输入关键字' || ths.value.trim() == ""){
ths.value = "";
}
}
function Blur(ths){ //光标离开执行
if(ths.value.trim() == ""){
ths.value = '请输入关键字';
ths.style.color = 'gray';
}else{
ths.style.color = "black";
}
}
</script>
</body>
Submit(1): 通常和form标记配合使用,其作用是用于送出数据,用户在form中输入数据后,点击Sumbit触发自定义函数.
<body>
<form name="forms" method="post" onsubmit="return check()">
<input type="text" name="texts" size="20">
<input type="submit" value="提交">
</form>
<script type="text/javascript">
function check() {
if(document.forms.texts.value == ""){
document.forms.focus()
alert("用户没有输入任何内容...")
return false
}else
{
alert("用户输入了内容...")
return true
}
}
</script>
</body>
Submit(2): 通常和form标记配合使用,其作用是用于送出数据,用户在form中输入数据后,点击Sumbit触发自定义函数.
<body>
<form action="https://www.baidu.com">
<input type="text" id="username">
<input type="submit" value="提交" onclick="return MySub()">
</form>
<script type="text/javascript">
function MySub(){
var user = document.getElementById("username");
if(user.value.length > 0){
alert("编辑框内有数据,允许提交数据..")
return true;
}else
{
alert("用户名输入不能为空...")
return false;
}
}
</script>
</body>
Reset: 通常情况下和form标记配合使用,其起到的作用是,当用户完成信息输入后,按下按钮自动清空已经输入的数据.
<body>
<form name="forms" method="post" >
<input type="text">
<input type="password">
<input type="reset" value="重置" onreset="reset()">
</form>
<!--<script type="text/javascript">-->
<!--function reset(){-->
<!--alert("内容已经清空了...")-->
<!--return 1-->
<!--}-->
<!--</script>-->
</body>
Change: 当文本区域中的鼠标指针移离该对象时,若对象内容与原来内容不同,则就会触发Change事件.
<body>
<textarea name="text" rows="3" cols="30" value=""
onchange="show()"></textarea>
<script type="text/javascript">
function show(){
alert("您在文本框中添加了新的内容...")
}
</script>
</body>
Select: 当一个文本框,文本区域对象中的文本被选中时就会触发Select事件,未被选择则不会出现提示框.
<body>
<input type="text" value="hello lyshark" onselect="show()">
<script type="text/javascript">
function show(){
alert("您选中了文本框中的文本内容...")
}
</script>
</body>
Error: 当网页因为某种原因出现错误时就会触发,在错误处理程序中可以绑定操作,该标签常用与<body>,<img>
配合.
<body>
<img src="temp.jpg" onerror="error_msg()">
<script type="text/javascript">
function error_msg(){
alert("图片加载失败了...")
}
</script>
</body>
jsBase64
//1.加密解密方法使用:
//1.加密
var str = '124中文内容';
var base = new Base64();
var result = base.encode(str);
//document.write(result);
//2.解密
var result2 = base.decode(result);
document.write(result2);
//2.加密、解密算法封装:
function Base64() {
// private property
_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
// public method for encoding
this.encode = function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
}
// public method for decoding
this.decode = function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = _utf8_decode(output);
return output;
}
// private method for UTF-8 encoding
_utf8_encode = function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
// private method for UTF-8 decoding
_utf8_decode = function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}