浏览器窗口,屏幕大小
网页可见区域宽:document.body.clientWidth
网页可见区域高:document.body.clientHeight
网页可见区域宽:document.body.offsetWidth (包括边线的宽)
网页可见区域高:document.body.offsetHeight (包括边线的宽)
网页正文全文宽:document.body.scrollWidth
网页正文全文高:document.body.scrollHeight
网页被卷去的高:document.body.scrollTop
网页被卷去的左:document.body.scrollLeft
网页正文部分上:window.screenTop
网页正文部分左:window.screenLeft
屏幕分辨率的高:window.screen.height
屏幕分辨率的宽:window.screen.width
屏幕可用工作区高度:window.screen.availHeight
屏幕可用工作区宽度:window.screen.availWidth
this指向
this最终指向调用他的对象
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j();
虽然是o.b.fn但是没有执行,最后执行的是j();是window调用
3 new 改变this指向
function Fn(){
this.user = "追梦子";
}
var a = new Fn(); //把fn的代码复制一份给a;此时this指向a
console.log(a.user); //追梦子
4
4 如果返回值是一个对象,this指向返回的对象,如果返回值不是对象this指向函数的实例
返回值为对象
// 虽然null也是对象,但是在这里this还是指向那个函数的实例,
function fn()
{
this.user = '追梦子';
return function(){};
}
var a = new fn;
console.log(a.user); //undefined
返回值不是对象
补充
1 在严格模式先 默认this不是window,而是undefined
2 在函数定义中this确定不了,只有执行的时候才知道this指向谁
深度克隆
1 基础数据类型
number null string Booleacn Undefned
又叫原始数据类型,这些值有固定的值,保存在栈内存中,由系统自动分配存储空间。
2 引用类型
Object Array function Data 这些数据存储在堆内存中,不能直接操作堆内存中的位置,只能操作对象栈内存中的引用地址。
1 潜克隆 (克隆栈内存中的数据)
基本数据类型用潜克隆就够了,引用数据类型克隆的是栈内存中的引用
2 深度克隆 (克隆堆内存中的位置)
拷贝的对象是对立内存修改不影响其他对象的值
1 简单的深度克隆方法
const newObj = JSON.parse(JSON.stringify(oldobj));
缺陷 1 无法实现对函数,RegExp等特殊对象的克隆
2 会抛弃独享的constructor,所有的构造函数都会指向Object
3 对象有循环引用,会报错
判断数据类型的经典方法
var type = Object.prototype.toString.call(obj);
判断数据的类型
function isClass(o){
if (o ===null) return 'null';
if(o === undefined) return 'Undefined';
return Obect.prototype.toString.call(o).slice(8,-1);
}
深度克隆
function deepClone(obj){
var result,oClass = isClass(obj);
//确定result的类型
if(oClass==='Object'){
result = {};
}else if(oClass==='Array'){
result [];
}else{
return obj;
}
for(key in obj){
var copy = obj[key];
if(isClass(copy)=="Object"){
result[key]=arguments.callee(copy);//递归调用知道返回的为基本类型
}else if(isClass(copy) =="Array"){
result[key] =arguments.callee(copy);
}else{
result[key]=obj[key];
}
}
return result;
}
递归函数
在函数中调用自己
function f(num){
if(num<1){
return 1;
}else{
return arguments.callee(num-1)*num;
}
}
Fibonacci数列第N项 从第三项开始每一项都等于前面的和
var fib = function (n){
if(n<=2){
return 1;
}
return fib(n-1)+fib(n+2);
}
console.log(fib(5));
js命名规则
1 不允许 数字开头,不允许中间有空格其他字符,不允许关键字
2 以 字母 _ $开头中间也是这些组合
循环遍历
switch
var day = new Date.getDay();
switch(day){
case 1:console.log('周一');break;
case 2:console.log('周二');break;
case 3: console.log('周三');break;
case 4 : console.log('周四');break;
case 5 : console.log('周五');break;
case 6 : console.log('周六');break;
case 7 : console.log('周日');break;
}
forEach() 用来遍历数组 没有返回值
arr[].forEach(function(value,index,arr){
})
value 数组的当前项
index 当前项的索引
arr 原始数组
var arr = [11,22,33,44,55,66];
var res = arr.forEach(function(value,index,arr){
arr[index] = value * 10;
})
console.log(res); undefined;没有返回值
console.log(arr); 通过索引改变原数组
map 与forEach一样都是遍历数组,但是有返回值,不改变元素组,也不检测孔数组;
var res = arr.map(function(value,index,arr){
return value * 10;
})
console.log(res); //[110, 220, 330, 440, 550, 660]
console.log(arr); //[11, 22, 33, 44, 55, 66]
$.each(arr,function(index,value){
})没有返回值,可以遍历数组,也可以遍历对象;遍历对象时为key,value
$.each(function(index,value){
console.log()
})
$.map(arr,function(value,index){})
有返回值,即可遍历对象也可遍历数组
for...of最简单直接的遍历数组的方法
避开了for in循环的所有缺陷
与forEach不同的是,他可以正确响应break,continue和return语句
for (var value of myArray) {
console.log(value);
}
for in主要获取对象的属性名
for (var i in colors) {
typeof i; // string
}
try catch fanily
try{
//代码区
}
catch(err){
console.log(err)
}
finally{}
如果代码区有错误catch中的err会保存起来 在catch中抛出错误,如果try catch程序中出现错误,程序会崩溃,加上try catch 程序不会崩溃还会把错误输出出来
最后finally 无论try catch执行结果如何都会执行
三级选择框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div class="jilian">
<h3>三级联动</h3>
<div class="content">
<!-- 选择的容器 -->
<select name="" id="sel_p"></select>
<select name="" id="sel_c"></select>
<select name="" id="sel_a"></select>
</div>
</div>
<script src="zepto/zepto.min.js"></script>
<script>
// 一级选项
var arr_p =[
{'id':0,'text':'请选择省'},
{'id':1,'text':'广东'},
{'id':2,'text':'湖南'},
{'id':3,'text':'河北'}
];
// 二级选项
var arr_c = [
{'id':'0','p_id':0,'text':'选择省份'},
{'id':'1','p_id':1,'text':'广州'},
{'id':'2','p_id':1,'text':'佛山'},
{'id':'3','p_id':1,'text':'深圳'},
{'id':'4','p_id':2,'text':'长沙'},
{'id':'5','p_id':2,'text':'永州'},
{'id':'6','p_id':3,'text':'石家庄'},
{'id':'7','p_id':3,'text':'沧州'}
];
// 三级选项
var arr_a = [
{'id':0,'c_id':0,'text':'选择市区'},
{'id':1,'c_id':1,'text':'广州1'},
{'id':2,'c_id':1,'text':'选择市区1'},
{'id':3,'c_id':1,'text':'选择市区2'},
{'id':4,'c_id':1,'text':'选择市区3'},
{'id':5,'c_id':2,'text':'选择市区4'},
{'id':6,'c_id':2,'text':'选择市区5'},
{'id':7,'c_id':2,'text':'选择市区6'},
{'id':8,'c_id':2,'text':'选择市区7'},
{'id':10,'c_id':3,'text':'选择市区8'},
{'id':11,'c_id':3,'text':'选择市区9'},
{'id':12,'c_id':4,'text':'选择市区10'},
{'id':13,'c_id':4,'text':'选择市区11'},
{'id':14,'c_id':5,'text':'选择市区12'},
{'id':15,'c_id':5,'text':'选择市区13'}
]
</script>
<script>
// 一级列表
function general_select_p(){
var select = $('#sel_p');
var len = arr_p.length;
for(var i=0;i<len;i++){
var option = '<option value ="' + arr_p[i]['id'] + '">' + arr_p[i]['text'] + '</option>';
select.append(option);
}
}
// 二级列表
function general_select_c(p_id){
var select = $('#sel_c');
select.empty();
var len = arr_c.length;
for(var i=0;i<len;i++){
if(arr_c[i]['p_id']==p_id){
var option = '<option value="' + arr_c[i]['id'] +'">'+arr_c[i]['text'] +'</option>';
select.append(option);
}
}
}
// 三级列表
function general_select_a(c_id){
var select = $("#sel_a");
select.empty();
var len = arr_a.length;
for(var i=0;i<len;i++){
if(arr_a[i]['c_id']==c_id){
var option = '<option value="' + arr_a[i]['id'] + '">' + arr_a[i]['text'] + '</option>';
select.append(option);
}
}
}
</script>
<script>
$(document).ready(function(){
general_select_p();
general_select_c(0);
general_select_a(0);
$("#sel_p").change(function(){
var p_id = $(this).val();
general_select_c(p_id);
var c_id = $("#sel_c").val();
general_select_a(c_id);
});
$("#sel_c").change(function(){
var c_id = $(this).val();
general_select_a(c_id);
})
});
</script>
</body>
</html>
节流函数
函数在一段时间内只执行一次
function throttle(fn,wait = 1000){
let lastTime = 0;
return function(){
let startTime = Date.now();
if(startTime - lastTime >= waitTime){
fn();
lastTime = startTime;
}
}
}
防抖函数
连续触发的事件,只有空闲一定时间后才会执行,不停的触发时间,就不会执行函数
function scrollFn(){
console.log('节流函数')
}
function throttle(methd,context){
clearTImeout(method.tId);
method.tId = setTimeout(function(){
method.call(context);
},300)
}
window.onscroll = function(){
throttle(scrollFn);
}
登录模块
<title>登录模块</title>
<style>
.ok {
color:green;
border: 1px solid green;
}
.error {
color: red;
border: 1px solid red;
}
</style>
<form action="http://www.tmooc.cn">
<p>
账号:
<input type="text" id="code" onblur="check_code()">
<span id="code_msg">亲输入6-10为字母,数字,下划线</span>
</p>
<p>
密码:
<input type="text" id="pwd" onblur="check_pwd()">
<span id="pwd_msg">8-20为字母数字下划线</span>
</p>
<p>
登录:
<input type="submit" value="登录">
</p>
</form>
<script>
//检验账号格式
function check_code(){
console.log(1);
//获取账号
var code = document.getElementById('code').value;
var span = document.getElementById('code_msg');
var ref = /^\w{6,10}$/;
if(ref.test(code)){
span.className = 'ok';
}else{
span.className = 'error';
}
}
function check_pwd(){
console.log(2);
var code2 = document.getElementById('pwd').value;
var span2 = document.getElementById('pwd_msg');
var reg2 = /^\w{6,10}$/;
if(reg2.test(code2)){
span2.className = 'ok';
}else{
span2.className = 'error';
}
}
</script>
闭包
第一 函数作为返回值
function fn(){
var max = 10;
if(x > max) {
console.log(x);
}
}
var f1 = fn();
f1(15);
第二 函数作为参数传递
var max = 10;
fn = function(x){
if(x > max ){
console.log(x);
}
}
(function(f){
var max = 100;
f
})(fn);
fn函数作为一个参数被传递进另一函数,复制给f参数,执行(15)时,max变量的取值是10,而不是100;
对象转换基本类型
- 对象转基本类型时,若果侧重于string(alert(obj))类型就调用toString方法,如果侧重于Number(alert(1 + obj))类型就调用valueOf方法
var obj = {
toString(){
console.log('toString')
reutrn 'string'
}
valueOf(){
console.log('valueOf')
return 'value'
}
}
alert(obj) //string
console.log(1 + obj) //1value
如果重写了toString方法,而没有重写valueOf方法,则会调用toString方法
var obj = {
toString () {
return 'string'
}
}
console.log(1 + obj) // 1string
调用上述两个方法时,需要return原始类型的值(primitive value)
调用 valueOf的时候,返回的不是原始类型的值,就会去调用toString,如果还不是原始的值,就会去报错
var obj = {
toString () {
console.log('toString')
return 'string'
},
valueOf () {
console.log('valueOf')
return {}
}
}
console.log(1 + obj)
// 依次打印出
valueOf
toString
1string
连加函数
var add = function (x){
var temp = function(y){
return add(m+n);
}
temp.toString = function(){
return m;
}
return temp;
}
add(3)(4)(5); //12
add(3)(6)(9)(25) //43
过程解释
1 先执行add(3),此时m=3,并且放回temp函数;
2 执行temp(4),这个函数执行add(m+n);m为上次的3,n 为这次的4 所有add(m+n) =add(3+4)=add(7),此时m=7,并且返回temp函数
3 执行temp(5),这个函数内执行add(m+n),n是此次传进来的数值5,m值还是上一步中的7,所以add(m+n)=add(7+5)=add(12),此时m=12,并且返回temp函数
5 最后如果没有参数传入,返回的temp函数不被执行,调用toString函数转为基本类型,而toStrng函数reutrn m值,而m最后一步为12
点击显示对象的索引
<ul id="ul1">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
方法一
var list = document.getElementsByTagName('li');
for(var i=0;i<list.length;i++){
list[i].index = i;
list[i].onclick = function(){
console.log(this.index)
}
}
方法二 利用闭包
var list = document.getElementsByTagName('li');
for(var i=0;i<list.length;i++){
list[i].onclick = function(n){
return function()
console.log(n);
}(i)
}
history
history 存储历史对象
history.back() 返回上次网页
history.forward();向前一个网页
history.go() 去某个网页
location对象
location既是window对象的属性,也是document对象的属性换句话说window.location和document.location引用的是同一个对象不只表现在他保存着当前文档的信息。还表现在它将URL解析为独立的片段,
http://www.baidu.com:80/news/index.aspx?id=1&name=location#top
location.hash 返回URL中hash #top
location.href / location.toString() 返货当前加载页面的完整URL
location.protocol 返回当前页面的协议 "http:"
location.hostname 返回服务器名称 "www.baidu.com"
location.host 返回服务器名称和端口号 "www.baidu.com:80
location.search 返回URL的查询字符串 以问号开头 "? id=1&name=location"
js的书写位置
1 行内
<input type="button" value="按钮" onclick="alert('Hello World')" />
2 写在script标签中
<script>
alert('Hello World!');
</script>
3 外部js文件中,在页面引入
<script src="main.js"></script>
- 引用外部js文件的script标签中不可以写JavaScript代码否则会覆盖掉
变量
变量 计算机内存储数据的标识符,根据变量名可以获取内存中的数据
声明变量 var age;
赋值 age=10;
声明赋值 var age=10;
命名规则
1 不能以数字开头 由字母数字下划线$组成
2 驼峰命名法 userName
数据类型
基本类型
number null string bool undefined 存在栈内
undefined 声明了变量却没有赋值
null 对象的值未设置,变量未指定任何对象
获取变量类型
typeof
typeof 2 number
typeof '222' string
typeof true boolean
typeof null object
typeof {} object
typeof [] object
typeof(function(){}) function
typeof(undefined) undefined
获取变量类型
Object.prototype.toString.call(obj).slice(8,-1);
显示转换(隐式转换)
数字转换
parseInt( ) 从第一数字开始到第一个非数字结束
parseInt("123") 123
parseInt("+123") 123
parseInt("123-") 123
parseInt("123.3") 123
parseInt("abc") NaN
parseInt([1,2,3,4]) 1
parseInt(" ") NaN
Number() 可把任意值转为数值,如果转换的字符春又一个不是数字,返回Null
parseFloat() 从第一个数字开始到第一个非数字结束(. 也看成数字)
parseFloat(123.3元) 123.3
Boolean () 存在内容为true 不存在为false
boolean([]) true
boolean(null) false
toString 变量有意义用
string() 变量无意义用
隐式转换
不同类型的变量进行比较都会先转换为
1 字符串与数字比较都会先转换为数字
2 字符串和布尔值比较 转换为数字
3 布尔值和数字比较 先转换为数字
undefined==null
三元运算
表达式1 ? 表达式2 : 表达式3
1 为true 执行 2 为false时执行3
switch
var day = new Date().getDay();
switch(day){
case 6:'周六';break;
case 7:'周日';break;
default:"Look foreard to the Weekend";
}
数组
求一数组中和的平均值
var arr=[1,2,3,4,5,6,7,8,9];
var sum= 0;
var m=0;
for(var i=0;i<arr.length;i++){
sum+=arr[i];
m = sum/arr.length;
}
求一组数组的对最大值最小值
var arr=[1,2,3,4,5,6,7,8,9];
var max = arr[0];
for(var i=0;i<arr.length;i++){
if(max<arr[i]){
max=arr[i];
}
}
去掉数组中的0项
var var arr = [10, 0, 20, 0, 30, 0, 50];
var newArr=[];
for(var i=0;i<arr.length;i++){
if(arr[i]!=0){
newArr[newArr.length]=arr[i];
}
}
冒泡排序
for(int i=0;i<arr.length;i++){
for(int x=0;x<arr.length-1-i;x++){
if(arr[x]>arr[x+1]){
var a = arr[x];
arr[x]=arr[x+1];
arr[x+1]=a;
}
}
}
请求头 请求体
在XM中get post不区分大小写 在http中GET和POST区分大小写
HTTP协议是以ASCII码传输,建立在TCP/IP协议智商的应用层规范的,把HTTP请求分为三个部分:状态航请求行 请求头,请求体
<method><request-URL></method>
<headers></headers>
<entity-body>
服务端根据请求头(headers)中的Content-Type字段获取请求体的编码方式,在对主体进行解析。所以说POST提交数据方式,包含了Content-Type和消息主体两部分
1 application/x-www-form-urlencoded常见的POST提交数据的方式
Content-Type被指定为application/x-www-form-urlencoded;其次提交的数据按照照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。例如PHP中$post['title']可以获取到title的值
2 multipart/form-data 表单上传文件时,必须让 form 的 enctyped 等于这个值
但是仔细看,会发现,尾部的分隔符要比头部的分隔符后面多“--”,用来表示表单的结束。因此,这里会引出一个非常重要的一个HTTP协议的规范:HTTP multipart/form-data请求时结束分割符比开始分隔符尾部多两位“--”,每个字段或者文件之间用“--分隔符”进行分割,最后一个分割符“--分隔符--”用来表示结束
如果我们通过HTTP提交multipart/form-data请求时,必须要做的两件事情:
第一,必须设定Content-Type属性值为multipart/form-data,否则它会以默认的application/x-www-form-urlencoded格式提交请求,会报错。
第二,必须指定boundary,也就是分隔符,并且要保证结束分隔符比开始分割符后面多两个“--”
3 application/json 用来告诉服务端消息主体是序列化后的 JSON 字符串,现在各大浏览器都原生支持 JSON.stringify
4 text/xml