当前位置: 代码迷 >> 综合 >> javaScripts(二)
  详细解决方案

javaScripts(二)

热度:71   发布时间:2023-11-17 11:30:44.0

一、面向对象

// 原型对象:
var Student = {name: 'Robot',height: 1.2,run: function () {console.log(this.name + ' is running...');}
};function createStudent(name) {// 基于Student原型创建一个新对象:var s = Object.create(Student);// 初始化新对象:s.name = name;return s;
}var xiaoming = createStudent('小明');
xiaoming.run(); // 小明 is running...
xiaoming.__proto__ === Student; // true1、创建对象

二、浏览器

1、window
window对象有innerWidth和innerHeight属性,可以获取浏览器窗口的内部宽度和高度。
内部宽高是指除去菜单栏、工具栏、边框等占位元素后,用于显示网页的净宽高
outerWidth整个宽度            outerHeight整个高度表
打印:
// 可以调整浏览器窗口大小试试:
console.log('window inner size: ' + window.innerWidth + ' x ' + window.innerHeight);2、navigator 浏览器信息对象
输出浏览器的信息:
navigator对象表示浏览器的信息,最常用的属性包括:navigator.appName:浏览器名称;
navigator.appVersion:浏览器版本;
navigator.language:浏览器设置的语言;
navigator.platform:操作系统类型;
navigator.userAgent:浏览器设定的User-Agent字符串。console.log('appName = ' + navigator.appName);
console.log('appVersion = ' + navigator.appVersion);
console.log('language = ' + navigator.language);
console.log('platform = ' + navigator.platform);
console.log('userAgent = ' + navigator.userAgent);3、screen屏幕信息
screen.width:屏幕宽度,以像素为单位;
screen.height:屏幕高度,以像素为单位;
screen.colorDepth:返回颜色位数,如8、16、24。console.log('Screen size = ' + screen.width + ' x ' + screen.height+ ',颜色:'+screen.colorDepth);4、location表示当前页面完整url信息location.protocol; // 'http'location.host; // 'www.example.com'location.port; // '8080'location.pathname; // '/path/index.html'location.search; // '?a=1&b=2'location.hash; // 'TOP'要加载一个新页面,可以调用location.assign()。
如果要重新加载当前页面,调用location.reload()方法if (confirm('重新加载当前页' + location.href + '?')) {location.reload();//重新加载当前页面
} else {location.assign('http://www.baidu.com'); // 设置一个新的URL地址  点击取消加载这个新的页面
}5、document 对象表示当前页面修改当前页面的titledocument.title = '努力学习JavaScript!';可以通过document.属性来获取当前页面的信息查找ID和Tag Name,准备的HTML数据如下<dl id="drink-menu" style="border:solid 1px #ccc;padding:6px;"><dt>摩卡</dt><dd>热摩卡咖啡</dd><dt>酸奶</dt><dd>北京老酸奶</dd><dt>果汁</dt><dd>鲜榨苹果汁</dd></dl>var menu = document.getElementById('drink-menu');
var drinks = document.getElementsByTagName('dt');
var  s;s = '提供的饮料有:';
for (i=0; i<drinks.length; i++) {s = s + drinks[i].innerHTML + ',';
}
console.log(s);

三、操作DOM

更新:更新该DOM节点的内容,相当于更新了该DOM节点表示的HTML的内容;
遍历:遍历该DOM节点下的子节点,以便进行进一步操作;
添加:在该DOM节点下新增一个子节点,相当于动态增加了一个HTML节点;
删除:将该节点从HTML中删除,相当于删掉了该DOM节点的内容以及它包含的所有子节点。案例:
// 返回ID为'test'的节点:
var test = document.getElementById('test');// 先定位ID为'test-table'的节点,再返回其内部所有tr节点:
var trs = document.getElementById('test-table').getElementsByTagName('tr');// 先定位ID为'test-div'的节点,再返回其内部所有class包含red的节点:
var reds = document.getElementById('test-div').getElementsByClassName('red');// 获取节点test下的所有直属子节点:
var cs = test.children;// 获取节点test下第一个、最后一个子节点:
var first = test.firstElementChild;
var last = test.lastElementChild;2、selector        querySelector()、querySelectorAll()
// 通过querySelector获取ID为q1的节点:
var q1 = document.querySelector('#q1');// 通过querySelectorAll获取q1节点内的符合条件的所有节点:
var ps = q1.querySelectorAll('div.highlighted > p');严格地讲,我们这里的DOM节点是指Element,但是DOM节点实际上是Node,在HTML中,Node包括Element、Comment、CDATA_SECTION等很多种,以及根节点Document类型,但是,绝大多数时候我们只关心Element,也就是实际控制页面结构的Node,其他类型的Node忽略即可。根节点Document已经自动绑定为全局变量document。二、更新DOM
1、修改innerHTML属性// 获取<p id="p-id">...</p>var p = document.getElementById('p-id');// 设置文本为abc:p.innerHTML = 'ABC'; // <p id="p-id">ABC</p>// 设置HTML:p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';// <p>...</p>的内部结构已修改2、修改innerText或textContent属
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置文本:
p.innerText = '<script>alert("Hi")</script>';
// HTML被自动编码,无法设置一个<script>节点:
// <p id="p-id">&lt;script&gt;alert("Hi")&lt;/script&gt;</p>3、修改css// 获取<p id="p-id">...</p>var p = document.getElementById('p-id');// 设置CSS:p.style.color = '#ff0000';p.style.fontSize = '20px';p.style.paddingTop = '2em'三、插入DOM <!-- HTML结构 -->
<p id="js">JavaScript</p>
<div id="list"><p id="java">Java</p><p id="python">Python</p><p id="scheme">Scheme</p>
</div>例如:需要实现把<p id="js">JavaScript</p>添加到<div id="list">的最后一项:
代码如下:
var js=document.getElementById('js');
var ls=document.getElementsById('list');
ls.appendChild(js);得到新的结构:<!-- HTML结构 --><div id="list"><p id="java">Java</p><p id="python">Python</p><p id="scheme">Scheme</p><p id="js">JavaScript</p></div>从零创建一个节点:
var list=document.getElementById('list');
var hall=document.createElement('p')
hall.id='hall'
hall.innerText='hall'
list.appendChild(hall)新的文件结构:
<!-- HTML结构 -->
<div id="list"><p id="java">Java</p><p id="python">Python</p><p id="scheme">Scheme</p><p id="hall">hall</p>
</div>添加CSS节点
var d = document.createElement('style');
d.setAttribute('type', 'text/css');
d.innerHTML = 'p { color: red }';
document.getElementsByTagName('head')[0].appendChild(d);2、insertBefore插入指定元素之前
parentElement.insertBefore(newElement, referenceElement)var list =document.getElementById('list');
var ref=document.getElementById('python');
var hall=documnet.createElement('p')
hall.id='hall'
hall.innerHTML='hall'
list.insertBefore(hall,ref)新的结构:
<!-- -HTML结构 --->
<div id="list"><p id="java">Java</p><p id="hall">hall</p><p id="python">Python</p><p id="scheme">Scheme</p>
</div>四、删除DOM// 拿到待删除节点:
var self = document.getElementById('to-be-removed');
// 拿到父节点:
var parent = self.parentElement;
// 删除:
var removed = parent.removeChild(self);
removed === self; // true如下结构:
<div id="parent"><p>First</p><p>Second</p>
</div>删除节点:
var parent = document.getElementById('parent');
parent.removeChild(parent.children[0]);
parent.removeChild(parent.children[1]); // <-- 浏览器报错,因为索引1已经不存在了

四、操作表单

文本框,对应的<input type="text">,用于输入文本;
口令框,对应的<input type="password">,用于输入口令;
单选框,对应的<input type="radio">,用于选择一项;
复选框,对应的<input type="checkbox">,用于选择多项;
下拉框,对应的<select>,用于选择一项;
隐藏文本,对应的<input type="hidden">,用户不可见,但表单提交时会把隐藏文本发送到服务器。1、获取值:这种方式应用于text、password、hidden以及select
// <input type="text" id="email">
var input = document.getElementById('email');
input.value; // '用户输入的值'针对单选框和复选框,需要判断checked,true选中,false没选// <label><input type="radio" name="weekday" id="monday" value="1"> Monday</label>
// <label><input type="radio" name="weekday" id="tuesday" value="2"> Tuesday</label>
var mon = document.getElementById('monday');
var tue = document.getElementById('tuesday');
mon.value; // '1'
tue.value; // '2'
mon.checked; // true或者false
tue.checked; // true或者false2、设置值
// <input type="text" id="email">
var input = document.getElementById('email');
input.value = 'test@example.com'; // 文本框的内容已更新
备注:对于单选框和复选框,设置checked为true或false即可。3、HTML5控件
<input type="date" value="2015-07-01"> //页面显示时间控件
2019/07/04<input type="datetime-local" value="2015-07-01T02:03:04">//页面显示时间控件
2015/07/01 02:03:04<input type="color" value="#ff0000">//页面显示颜色控件4、提交表单方式一是通过<form>元素的submit()方法提交一个表单:
<!-- HTML -->
<form id="test-form"><input type="text" name="test"><button type="button" onclick="doSubmitForm()">Submit</button>
</form><script>
function doSubmitForm() {var form = document.getElementById('test-form');// 可以在此修改form的input...// 提交form:form.submit();
}
</script>第二种方式是响应<form>本身的onsubmit事件,在提交form时作修改:<!-- HTML -->
<form id="test-form" onsubmit="return checkForm()"><input type="text" name="test"><button type="submit">Submit</button>
</form><script>
function checkForm() {var form = document.getElementById('test-form');// 可以在此修改form的input...// 继续下一步:return true;
}
</script>加密口令改变用户的输入:
<!-- HTML -->
<form id="login-form" method="post" onsubmit="return checkForm()"><input type="text" id="username" name="username"><input type="password" id="password" name="password"><button type="submit">Submit</button>
</form><script>
function checkForm() {var pwd = document.getElementById('password');// 把用户输入的明文变为MD5:pwd.value = toMD5(pwd.value);// 继续下一步:return true;
}
</script>加密口令不改变用户的输入
<!-- HTML -->
<form id="login-form" method="post" onsubmit="return checkForm()"><input type="text" id="username" name="username"><input type="password" id="input-password"><input type="hidden" id="md5-password" name="password"><button type="submit">Submit</button>
</form><script>
function checkForm() {var input_pwd = document.getElementById('input-password');var md5_pwd = document.getElementById('md5-password');// 把用户输入的明文变为MD5:md5_pwd.value = toMD5(input_pwd.value);// 继续下一步:return true;
}
</script>校验登陆密码用户名:var checkRegisterForm = function () {  var uname = document.getElementById('username');var uname_re = /^\w{3,10}$/;var pwd = document.getElementById('password');var pwd2 = document.getElementById('password-2');if(uname_re.test(uname.value)){ alert('用户名输入合法'); return false;if(pwd.value.length<6 || pwd.value.length>20) {alert('口令必须是6-20位');return false;}else {alert('口令合法')return false;if(pwd.value!==pwd2.value){alert('两次输入口令不一致');return false;}else {alert('两次输入口令一致');return true;}    }}else{alert('用户名输入不合法');return false;}

五、操作文件

在HTML表单中,可以上传文件的唯一控件就是<input type="file">。
注意:当一个表单包含<input type="file">时,表单的enctype必须指定为multipart/form-data,method必须指定为post,浏览器才能正确编码并以multipart/form-data格式发送表单的数据。var f = document.getElementById('test-file-upload');
var filename = f.value; // 'C:\fakepath\test.png'
if (!filename || !(filename.endsWith('.jpg') || filename.endsWith('.png') || filename.endsWith('.gif'))) {alert('Can only upload image file.');return false;
}

六、AJAX

七、promise

八、Canvas
九、jQuery

十、错误处理

1、基础var s = null;
var len = s.length; // TypeError:null变量没有length属性try ... catch ... finallyvar r1, r2, s = null;
try {r1 = s.length; // 此处应产生错误r2 = 100; // 该语句不会执行
} catch (e) {console.log('出错了:' + e);
} finally {console.log('finally');
}
console.log('r1 = ' + r1); // r1应为undefined
console.log('r2 = ' + r2); // r2应为undefined当代码块被try { ... }包裹的时候,就表示这部分代码执行过程中可能会发生错误,一旦发生错误,就不再继续执行后续代码,转而跳到catch块。catch (e) { ... }包裹的代码就是错误处理代码,变量e表示捕获到的错误。最后,无论有没有错误,finally一定会被执行。2、错误类型
avaScript有一个标准的Error对象表示错误,还有从Error派生的TypeError、ReferenceError等错误对象。我们在处理错误时,可以通过catch(e)捕获的变量e访问错误对象:try {try {...
} catch (e) {if (e instanceof TypeError) {alert('Type error!');} else if (e instanceof Error) {alert(e.message);} else {alert('Error: ' + e);}
}3、抛出错误输入字符串  主动抛出异常实例:
var r, n, s;
try {s = prompt('请输入一个数字');n = parseInt(s);if (isNaN(n)) {throw new Error('输入错误');}// 计算平方:r = n * n;console.log(n + ' * ' + n + ' = ' + r);
} catch (e) {console.log('出错了:' + e);
}最后,当我们用catch捕获错误时,一定要编写错误处理语句:var n = 0, s;
try {n = s.length;
} catch (e) {console.log(e);
}
console.log(n);二、错误传播设置合理地捕获位置function main(s) {console.log('BEGIN main()');try {foo(s);} catch (e) {console.log('出错了:' + e);}console.log('END main()');
}function foo(s) {console.log('BEGIN foo()');bar(s);console.log('END foo()');
}function bar(s) {console.log('BEGIN bar()');console.log('length = ' + s.length);console.log('END bar()');
}main(null);三、异步错误处理function printTime() {console.log('It is time!');
}setTimeout(printTime, 1000);等待1s执行printTime函数
console.log('done');

十一、underscore 第三方库

解析:underscore,会把自身绑定到唯一的全局变量 _ 上用underscore实现map()操作如
'use strict';
_.map([1, 2, 3], (x) => x * x); // [1, 4, 9]'use strict';
_.map({ a: 1, b: 2, c: 3 }, (v, k) => k + '=' + v); // ['a=1', 'b=2', 'c=3']一、Collections1、map/filter作用于Object时,传入的函数为function (value, key),第一个参数接收value,第二个参数接收key:
'use strict';
var obj = {name: 'bob',school: 'No.1 middle school',address: 'xueyuan road'
};
var upper = _.map(obj, function (value, key) {return key+ '=' + value;
});2、every/some
当集合的所有元素都满足条件时,_.every()函数返回true,当集合的至少一个元素满足条件时,_.some()函数返回true:'use strict';
// 所有元素都大于0?
_.every([1, 4, 7, -3, -9], (x) => x > 0); // false
// 至少一个元素大于0?
_.some([1, 4, 7, -3, -9], (x) => x > 0); // true判断是否全部小写:
'use strict';
var obj = {name: 'bob',school: 'No.1 middle school',address: 'xueyuan road'
};var r1 = _.every(obj, function (value, key) {return isLowerCase(key) && isLowerCase(value);
});
var r2 = _.some(obj, function (value, key) {return isLowerCase(key) && isLowerCase(value);});function isLowerCase(str) {return str === str.toLowerCase();
}3、max/min  返回集合中最大或者最小的值
'use strict';
var arr = [3, 5, 7, 9];
_.max(arr); // 9
_.min(arr); // 3// 空集合会返回-Infinity和Infinity,所以要先判断集合不为空:
_.max([])
-Infinity
_.min([])
Infinity注意,如果集合是Object,max()和min()只作用于value,忽略掉key:
'use strict';
_.max({ a: 1, b: 2, c: 3 }); // 34、groupBy'use strict';var scores = [20, 81, 75, 40, 91, 59, 77, 66, 72, 88, 99];
var groups = _.groupBy(scores, function (x) {if (x < 60) {return 'C';//返回C分类} else if (x < 80) {return 'B';//返回B分类} else {return 'A';//返回A分类}
});
// 结果:
// {
//   A: [81, 91, 88, 99],
//   B: [75, 77, 66, 72],
//   C: [20, 40, 59]
// }5、shuffle sampleshuffle()用洗牌算法随机打乱一个集合
'use strict';
// 注意每次结果都不一样:
_.shuffle([1, 2, 3, 4, 5, 6]); // [3, 5, 4, 6, 2, 1]sample()则是随机选择一个或多个元素:
'use strict';
// 注意每次结果都不一样:
// 随机选1个:
_.sample([1, 2, 3, 4, 5, 6]); // 2
// 随机选3个:
_.sample([1, 2, 3, 4, 5, 6], 3); // [6, 1, 4]二、Arrays1、first / last顾名思义,这两个函数分别取第一个和最后一个元素:'use strict';
var arr = [2, 4, 6, 8];
_.first(arr); // 2
_.last(arr); // 82、flatten
flatten()接收一个Array,无论这个Array里面嵌套了多少个Array,flatten()最后都把它们变成一个一维数组:'use strict';_.flatten([1, [2], [3, [[4], [5]]]]); // [1, 2, 3, 4, 5]3、zip / unzipzip:'use strict';var names = ['Adam', 'Lisa', 'Bart'];
var scores = [85, 92, 59];
_.zip(names, scores);
// [['Adam', 85], ['Lisa', 92], ['Bart', 59]]unzip:'use strict';
var namesAndScores = [['Adam', 85], ['Lisa', 92], ['Bart', 59]];
_.unzip(namesAndScores);
// [['Adam', 'Lisa', 'Bart'], [85, 92, 59]]4、object
'use strict';var names = ['Adam', 'Lisa', 'Bart'];
var scores = [85, 92, 59];
_.object(names, scores);
// {Adam: 85, Lisa: 92, Bart: 59}注意_.object()是一个函数,不是JavaScript的Object对象。5、range'use strict';// 从0开始小于10:
_.range(10); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]// 从1开始小于11:
_.range(1, 11); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]// 从0开始小于30,步长5:
_.range(0, 30, 5); // [0, 5, 10, 15, 20, 25]// 从0开始大于-10,步长-1:
_.range(0, -10, -1); // [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]uniq:'use strict';
var arr = ['Apple', 'orange', 'banana', 'ORANGE', 'apple', 'PEAR'];
var result = _.uniq(arr,s=>s.toUpperCase());//不区分大小写进行排序三、Functions1、bind'use strict';var s = ' Hello  ';
var fn = s.trim;
// 调用call并传入s对象作为this:
fn.call(s)
// 输出Hello'use strict';var s = ' Hello  ';
var fn = _.bind(s.trim, s);把s对象直接绑定在fn()的this指针上
fn();
// 输出Hello2、partial
根据Math.pow(x, y)创建新函数pow2N(y),它固定住了原函数的第一个参数(始终为2):'use strict';var pow2N = _.partial(Math.pow, 2);
pow2N(3); // 8
pow2N(5); // 32
pow2N(10); // 1024如果我们不想固定第一个参数,想固定第二个参数怎么办?比如,希望创建一个偏函数cube(x),计算x3,可以用_作占位符,固定住第二个参数:
'use strict';var cube = _.partial(Math.pow, _, 3);
cube(3); // 27
cube(5); // 125
cube(10); // 10003、memoize   自动缓存结果//只会缓存factorial(10)var factorial = _.memoize(function(n) {console.log('start calculate ' + n + '!...');var s = 1, i = n;while (i > 1) {s = s * i;i --;}console.log(n + '! = ' + s);return s;
});// 第一次调用:
factorial(10); // 3628800
// 注意控制台输出:
// start calculate 10!...
// 10! = 3628800// 第二次调用:
factorial(10); // 3628800
// 控制台没有输出//优化调用调用fdctorial(10)   缓存actorial(1)~factorial(10)'use strict';var factorial = _.memoize(function(n) {console.log('start calculate ' + n + '!...');if (n < 2) {return 1;}return n * factorial(n - 1);
});factorial(10); // 3628800
// 输出结果说明factorial(1)~factorial(10)都已经缓存了:
// start calculate 10!...
// start calculate 9!...
// start calculate 8!...
// start calculate 7!...
// start calculate 6!...
// start calculate 5!...
// start calculate 4!...
// start calculate 3!...
// start calculate 2!...
// start calculate 1!...factorial(9); // 362880
// console无输出4、once 调用只执行一次
'use strict';var register = _.once(function () {alert('Register ok!');
});// 测试效果:
register();
register();
register();5、delay
delay()可以让一个函数延迟执行,效果和setTimeout()是一样的,'use strict';
// 2秒后调用alert():
_.delay(alert, 2000)如果要延迟调用的函数有参数,把参数也传进去:'use strict';
var log = _.bind(console.log, console);
_.delay(log, 2000, 'Hello,', 'world!');
// 2秒后打印'Hello, world!':四、Objects1、keys / allKeys
keys()返回一个object自身所有的key,不包含从原型链继承下来的:
'use strict';
function Student(name, age) {this.name = name;this.age = age;
}
var xiaoming = new Student('小明', 20);
_.keys(xiaoming); // ['name', 'age']allKeys()除了object自身的key,还包含从原型链继承下来的:function Student(name, age) {this.name = name;this.age = age;
}
Student.prototype.school = 'No.1 Middle School';
var xiaoming = new Student('小明', 20);
_.allKeys(xiaoming); // ['name', 'age', 'school']2、values和keys()类似,values()返回object自身但不包含原型链继承的所有值:'use strict';
var obj = {name: '小明',age: 20
};
_.values(obj); // ['小明', 20]3、mapObject针对object的map版本
'use strict';var obj = { a: 1, b: 2, c: 3 };
// 注意传入的函数签名,value在前,key在后:
_.mapObject(obj, (v, k) => 100 + v); // { a: 101, b: 102, c: 103 }4、invert
invert()把object的每个key-value来个交换,key变成value,value变成key:var obj = {Adam: 90,Lisa: 85,Bart: 59
};
_.invert(obj); // { '59': 'Bart', '85': 'Lisa', '90': 'Adam' }5、extend / extendOwn
extend()把多个object的key-value合并到第一个object并返回
'use strict';var a = {name: 'Bob', age: 20};
_.extend(a, {age: 15}, {age: 88, city: 'Beijing'}); // {name: 'Bob', age: 88, city: 'Beijing'}
// 变量a的内容也改变了:
a; // {name: 'Bob', age: 88, city: 'Beijing'}注意:如果有相同的key,后面的object的value将覆盖前面的object的value。
extendOwn()和extend()类似,但获取属性时忽略从原型链继承下来的属性。6、clone复制原有的所有属性'use strict';
var source = {name: '小明',age: 20,skills: ['JavaScript', 'CSS', 'HTML']
};var copied = _.clone(source);
console.log(JSON.stringify(copied, null, '  '));注意,clone()是“浅复制”。所谓“浅复制”就是说,两个对象相同的key所引用的value其实是同一对象:7、isEqualisEqual()对两个object进行深度比较,如果内容完全相同,则返回true:
var o1 = { name: 'Bob', skills: { Java: 90, JavaScript: 99 }};
var o2 = { name: 'Bob', skills: { JavaScript: 99, Java: 90 }};
o1 === o2; // false
_.isEqual(o1, o2); // true五、Chainingvar r = _.chain([1, 4, 9, 16, 25]).map(Math.sqrt)//求平方根得到12345.filter(x => x % 2 === 1)135.value();
console.log(r); // [1, 3, 5]