<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>first class function</title>
<style>
#thirdexample{
/* background-color: gray; */
width: 400px;
height: 200px;
text-align: center;
}
#thirdexample button{
width: 80px;
height: 30px;
border: none;
border-radius: 5px;
transition: 0.5s;
}
#thirdexample button.active{
background-color: green;
transition: 0.5s;
}
#targetdiv{
display: none;
background-color: rgb(172, 168, 168);
border-radius: 5px;
height: 170px;
line-height: 170px;
}
</style>
</head>
<body>
<h1>first class function</h1>
<p><button>click me plz!</button></p>
<div id="thislist">
<ul>
<li>Clicked <span>0</span> Times</li>
<li>Clicked <span>0</span> Times</li>
<li>Clicked <span>0</span> Times</li>
</ul>
</div>
<div id="thirdexample">
<button id="opendiv">Open Div</button>
<div id="targetdiv">
<div class="content">Will you watch me?</div>
</div>
</div>
<script src="/jQuery/js/jquery-3.5.1.js"></script>
<script>
/******TIP-one
在js中函数也可以是变量————头等函数*/
function add(first,second,callback){
console.log(first+second);
callback();//第三个参数为函数(回调)
}
function logOk(){
console.log('ok')
}
add(1,2,function(){
console.log('ok');
});
add(3,4,logOk);
/*改进使得callback非必须*/
console.log('-----------------')
function addv2(first,second,callback){
console.log(first+second);
if(callback){
callback();
}
}
addv2(1,2);//不会报错
addv2(12,13,logOk);
/******TIP-two——事件驱动环境
js基于事件驱动的环境,代码保存在内存中,
当某事件触发执行相应的代码逻辑(看起来快的原因)
不会重载整个界面*/
var a = 1;
console.log('this would be the only one to be executed');//仅执行一次,点击按钮后只执行与按钮事件有关部分的逻辑代码
//记载这里的的一个小问题,getElementsByTagName返回的是一个数组对象,不能对其使用addEventListener,所以后面需添加[0]
//最好不好通过这种方式访问,使用id或是类名
var mbtn = document.getElementsByTagName('button')[0];
mbtn.addEventListener('click',function(){
alert(a++);
});
/*****TIP-three——闭包
在js中
闭包中的变量,在函数执行后仍保存在内存中(正常来说会被释放)
如:上例中的a,每次点击后函数执行完毕,然而a的值却仍保存在内存中,未被释放
且随着点击的次数增加增加
*/
/******TIP-four——作用域
变量起作用的范围*/
console.log('---------------')
var a = 1;//声名全局变量 a === window.a
function aaa(){
var a = 2;//这里的a仅在aaa()函数范围内生效,与window.a不是同一个a,变量名是存在冲突的,且物理存储位置不同
console.log(a);
}
function bbb(){
a = 3;//在该函数范围内没有对a的声名,会一层一层向外找,直至找到a的声名,若没有将创建全局变量(全局污染)
//可以在脚本起始位置添加"use strict"进入严格模式,可规避此类问题
var b=2;
console.log(a);
}
aaa();//a = 2
bbb();//a = 3
console.log(a);//a = 3
// console.log(b);//报错 b is not defined
/*****TIP-five-context(上下文)
* context === this */
console.log('-----------');
console.log(this);//window
console.log(this===window);//true
function contexttest(){
console.log(this);//window,默认函数运行在window范围
}
contexttest();//===window.contexttest();
//该例中的函数的this不是window而是obj
var obj = {
fuc:function(){
console.log(this);
console.log(this===window);//false
console.log(this===obj);//true
}
}
obj.fuc();
//有三种方式可以改变context:call,apply,bind(知道上下文可以被改变)
obj.fuc.call(window);//上下文变成window,如果存在参数一并写在call中call(window,1,2,3)
obj.fuc.apply(window);//与call类型,区别是,参数使用数组统一存储apply(window,[1,2,3]
var myboundfnc = obj.fuc.bind(window);//返回一个函数
myboundfnc();
//this的实际应用
$('body').on('click',obj.fuc);//这里的this指向body
var $list = $('#thislist');
$list.find('li').on('click',function(){
console.log(this);
//不使用this的情况下,单独使得点击元素的数字增加时困难且复杂的
// var currentTimes = parseInt($('li span').html() );
// $('li span').html(currentTimes+1);//所有的span都增加了,不符合预期
//使用this,来获取每次点击的目标(即对应的context),有助于针对性的完善代码逻辑
//根据上下文这里的this是所点击的li
var currentTimes = parseInt($(this).find('span').html());
$(this).find('span').html(currentTimes+1);
});
//example3 使用this过程中需要注意的问题
$('#opendiv').on('click',function () {
var self = this;
// //逻辑:点击opendiv同时显示content
// $(this).toggleClass('active');
// $('#targetdiv').slideToggle(500);
//现要求在显示content后button样式才生效
$('#targetdiv').slideToggle(500,function(){
// $(this).toggleClass('active');//但是此处的this,根据context已经变成了targetdiv
//有以下方法,利用全局变量self,保存上一个this
// $(self).toggleClass('active');
//使用bind(this),绑定slideToggle的this
$(this).toggleClass('active');
}.bind(this));//绑定slideToggle的this后,里层的this默认指向外层的opendiv
});
</script>
</body>
</html>