性别:<label for="man">
<input type="radio" name="sex" id="man">男
label>
<label for="woman">
<input type="radio" name="sex" id="woman">女
label>
<a href="#two">第二集a>
<h3 id="two">第二集内容h3>
<select>
<option select="selected">选项一option>
<option>选项二option>
<option>选项三option>
select>
span {
background-color: yellow;
}
<span>Type selectorsspan>
.highlight {
background-color: yellow;
}
<h1 class="highlight">Class selectorsh1>
h1#heading {
color: rebeccapurple;
}
<h1 id="heading">ID selectorh1>
li[class] {
font-size: 200%;
}
li[class="a"] {
background-color: yellow;
}
li[class~="a"] {
color: red;
}
<h1>Attribute presence and value selectorsh1>
<ul>
<li>Item 1li>
<li class="a">Item 2li>
<li class="a b">Item 3li>
<li class="ab">Item 4li>
ul>
.box::before {
content: "This should show before the other content."
}
<p class="box">Content in the box in my HTML page.p>
.box p {
color: red;
}
<div class="box">
<p>Text in .boxp>
div>
body{
font:font-style font-weight font-size/line-height font-family;
}
<h1 style="color:red;">使用行内样式引入CSSh1>
<style type="text/css">
div{
background: green;
}
style>
<div>我是DIVdiv>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<style type="text/css">
@import url("css/style.css");
style>
.box{
background-image: url(star.png);
background-repeat: no-repeat;
background-position: top 20px right 10px;
background-position: top center;
}
<script>
/*内部js代码*/
alert("HELLO,WORLD!");
</script>
<!--外部js代码-->
<script type="text/javascript" src="js/index.js"></script>
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
left和top分析:
width和height分析
let btn = document.getElementById('btn');
btn.onclick = function(){
console.log('click');
}
const show = function () {
console.log(this.id);
}
var btn = document.querySelector('input');
btn.addEventListener('click', show);
/**
DOM0级事件处理程序:btn.onclick
DOM2级事件处理程序:btn.addEventListener(事件名称,处理函数,true/false)
addEventListener('click',fn,false) 默认为FALSE,可以进行事件冒泡,改为TRUE事件则不会冒泡
DOM2级事件程序,IE8以下不支持,IE8以下使用addEvent方法(此方法中的this指向window,可调用call()方法改变this的指向)
/**
相同点:如果同时出现HTML事件处理程序和 DOM0 级事件处理程序,DOM0级事件会覆盖HTML事件处理
不同点:除IE8以下的浏览器:先执行 DOM0 级事件,再执行 DOM2 级事件
*/
function addEvent(target, eventType, handler) {
if (target.addEventListener) {
target.addEventListener(eventType, handler, false);
} else {
target.attachEvent('on' + eventType, handler);
handler.call(target)
}
}
let timer = null
btn.onclick = function(){
clearInterval(timer)
timer = setInterval(function(){
let left = div.offsetLeft
// 当左边距<600px时,匀速运动
if(left !== '600'){
left += 50
div.style.left = left + 'px'
}else{
clearInterval(timer)
}
},100)
}
function startAnimation(obj,target){
clearInterval(timer)
timer = setInterval(function(){
speed = target > obj.offsetLeft ? Math.ceil((target - box.offsetLeft) / 20 )
: Math.floor((target - box.offsetLeft) / 20)
if(box.offsetLeft === target){
clearInterval(timer)
}
box.style.left = box.offsetLeft + speed + 'px'
},30)
}
startAnimation(box, 'height', 80, function () {
startAnimation(box, 'width', 200, function () {
startAnimation(box, 'opacity', 30)
})
})
function startAnimation(obj,attr,target,fn){
// 针对多值运动,定时器的返回值要绑定当前的对象中
clearInterval(obj.timer)
obj.timer = setInterval(function(){
let cur = 0,speed = 0;
// 透明度变化处理
if(attr === 'opacity'){
cur = Math.round(parseFloat(getStyle(obj,attr)) * 100)
}else{
cur = parseInt(getStyle(obj,attr))
}
// 1.求速度
speed = target > cur ? Math.ceil((target - cur) / 20)
: Math.floor((target - cur) / 20)
// 2.临界处理
if(targer === cur){
clearInterval(obj.timer)
if(fn){
fn()
}
return
}
// 3.运动
if(attr = 'opacity'){
obj.style[attr] = `alpha(opacity : ${cur + speed})`
obj.style[attr] = (speed + cur) / 100
}else{
obj.style[attr] = cur + speed + 'px'
}
},30)
}
function getStyle(obj,attr){
if(obj.currentStyle){
// 兼容IE浏览器
return obj.currentStyle[attr]
}else{
// 兼容主流浏览器
return getComputedStyle(obj,null)[attr]
}
}
function startAnimation(obj, json, fn) {
//针对多值运动,定时器的返回值要绑定当前的对象中
clearInterval(obj.timer)
obj.timer = setInterval(function () {
let flag = true;
let cur = 0, speed = 0;
//透明度变化处理
for (let attr in json) {
switch (attr) {
case 'opacity':
cur = Math.round(parseFloat(getStyle(obj, attr)) * 100)
break;
case 'scrollTop':
cur = obj[attr]
break;
default:
cur = parseInt(getStyle(obj, attr))
break;
}
// console.log(attr, obj[attr])
// console.log(cur,flag)
//1.求速度
speed = json[attr] > cur ? Math.ceil((json[attr] - cur) / 20)
: Math.floor((json[attr] - cur) / 20)
//2.临界处理
if (json[attr] != cur) {
flag = false
}
//3.运动起来
switch (attr) {
case 'opacity':
obj.style[attr] = `alpha(opacity : ${cur + speed})`
obj.style[attr] = (speed + cur) / 100
break;
case 'scrollTop':
obj.scrollTop = cur + speed
break;
default:
obj.style[attr] = cur + speed + 'px'
break;
}
if (flag) {
clearInterval(obj.timer)
if (fn) {
fn()
}
return
}
}
}, 10)
}
function getStyle(obj, attr) {
if (obj.currentStyle) {
//兼容IE浏览器
return obj.currentStyle[attr]
} else {
//兼容主流浏览器
return getComputedStyle(obj, null)[attr]
}
}
let obj = {
a: 100,
fn: function () {
// this表示obj对象
console.log(this) // this指向当前的对象
console.log('fn函数被调用')
},
fn2: function () {
console.log(this)
this.a = 2
}
}
obj.fn() // 打印obj对象
obj.fn2() // 打印obj对象
console.log(obj.a) // a = 2
// 3.间接调用模式:使用 call()、apply() 方法,call方法和apply方法会改变第一个参数的this指向
let arrObj = {
a: 10
}
function sum(a, b) {
console.log(this)
return a + b;
}
console.log("call方法调用的结果:" + sum.call(sum, 1, 3)) // 打印该函数体
console.log("apply方法调用的结果:" + sum.apply(arrObj, [1, 3])) // 打印arrObj对象
// arguments不是真正的数组,他是类数组,且能通过[]访问它的每一个元素
function argueFun() {
console.log("形参个数" + arguments.length)
let sum = 0
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i]
}
console.log(sum)
}
// 引入argument实现函数的重载功能
function doAdd() {
if (arguments.length === 0) {
return 10
} else if (arguments.length === 1) {
return arguments[0] + 10
} else if (arguments.length === 2) {
return arguments[0] + arguments[1] + 10
}
}
console.log("无参doAdd" + doAdd())
console.log("一个参数doAdd" + doAdd(10))
console.log("两个参数doAdd" + doAdd(10, 20))
function setName(obj) {
obj.name = 'sun1566'
}
let Person = {}
setName(Person)
console.log("Person的姓名:" + Person.name)
// 函数的重写
function setName2(obj) {
obj.name = 'sun1566'
console.log("Person2的姓名:" + Person2.name)
obj = {} // obj对象开辟了一个新的内存空间
obj.name = 'sunX' // 将obj对象的name属性赋值’sunX‘,并没有改变Person2地址的内容
console.log("Person2的姓名:" + Person2.name) //打印的结果还是为sun1566
}
let Person2 = {}
setName2(Person2)
// 1.找出数组的最大元素 Math.max,apply(null,[])
console.log(Math.max(1, 2, 3, 4, 5))
let arr = [34, 12, 42, 22]
let max = Math.max.apply(null, arr)
console.log(max)
// 2.将类数组转换为真正的数组
function add() {
console.log(arguments) // 打印实参数组对象(Object)
// 通过slice()方法可以实现浅拷贝(只拷贝内容,且对拷贝的内容进行修改不会改变原内容),slice的返回值为数组
let arr = Array.prototype.slice.apply(arguments)
console.log(arr) // 此时的arr会变成真正的数组
let arr2 = [].slice.call(arguments)
console.log(arr2)
let arr3 = Array.prototype.slice.apply({0: 'hello', 1: 'world', length: 2})
console.log(arr3)
}
add(1, 2, 3, 4, 5)
// 3.数组连接
let arr2 = [5, 5]
let num = Array.prototype.push.apply(arr2, [1, 2, 3, 0]) //push的返回值为数组的长度
console.log("arr2:" + arr2)
console.log("num:" + num)
// 4.利用call和apply做继承
function Animal(name, age) {
this.name = name
this.age = age
this.sayAge = function () {
console.log(this.name + "今年" + this.age + "岁了")
}
}
function Cat(name, age) {
// 继承了animal
// call的变量之间用','隔开
Animal.call(this, name, age) // 把this指向Cat实例对象
}
let c = new Cat('小猫咪', 20)
c.sayAge()
console.log(c)
function Dog() {
// 继承了animal
// apply的第二个参数为数组对象
Animal.apply(this, arguments) // 把this指向Cat实例对象
}
let d = new Dog('小狗狗', 3)
d.sayAge()
console.log(d)
// 柯里化写法
function add(x) {
return function (y) {
return x + y
}
}
console.log(add(4)(5))
function fn() {
// 在严格模式下 'use strict',没有定义变量的关键字会报错
abs = 1; // 没有声明abs的关键字,默认会在window中创建abs变量
}
aaa = 2
var aaa // var会存在变量提升,var声明变量会将变量提升到最上面执行,这个过程叫预解释
console.log(this) // aaa会存入window对象
//声明函数的提升:直接声明函数会提升,但声明函数表达式不会提升(报错)
fun() (√) //存在变量提升
function fun() {
console.log("fun函数被调用")
}
foo() (×)//函数表达式声明,不会提升
let foo = function f() {
console.log("foo函数被调用")
}
var a = 1
var b = 2
function f1(x) {
console.log(a) // var a , 因此打印undefined
var a = 10 // var定义的变量会进行变量提升,提升到函数体的最上方
function bar(x) {
var a = 100
b = x + a
return b
}
bar(20)
// bar(20)的执行环境:x:20 、 a:undefined 、arguments:0 、 this:window
bar(200)
}
console.log("f1:" + f1(0))
// f1(0)的执行环境(存储的变量对象):x:0 、 a:undefined 、 bar:function() 、 arguments:0 、 this:window
let a = 123
function fn1(a){
let b = 234
function fn2(b){
return b
}
return fn2
}
let fn = fn1()
console.log(b) //b为全局作用域中的变量,直接打印fn2中b的值,会报错
console.log(fn())
function count(){
let start = 0;
function add(){
return ++start
}
return add
}
let fn = count()
setInterval(function(){
console.log(fn())
},1000)
fun = null //销毁变量,释放内存
function Person(name) {
// 私有属性
let age
// 私有的方法
function setAge(n) {
age = n
}
function getAge() {
return age
}
return {
name: name,
setAge: setAge,
getAge: getAge
}
}
let p = new Person()
p.setAge(22)
console.log(p.getAge())
function count() {
let start = 0
return function add() {
return ++start
}
// return add
}
// count()()相当于每次都生成一个新的闭包,因此每次都会被初始化
console.log(count()())
console.log(count()())
// 正确调用方式:
let inc = count()
console.log(inc())
console.log(inc())
// 使用完销毁变量
inc = null
// 立即执行函数也叫闭包,可以封装私有的属性,同时可以减少对全局变量的污染
let fun = (function () {
// 私有属性
let count = 0
return function () {
return ++count
}
})();
console.log("第一次执行fun函数" + fun())
console.log("第二次执行fun函数" + fun())
console.log("第三次执行fun函数" + fun())
function f() {
var arr = []
for (var i = 0; i < 10; i++) {
arr[i] = function () { //根据作用域链,当循环体执行完才进行arr[i]函数操作,arr[i]执行的是i++也就是此时的i=10
return i
}
}
return arr
}
var fn1 = f()
console.log("f函数体" + fn1)
console.log(fn1[0]())
console.log(fn1[1]())
// 解决方法一:使用let块级作用域
function foo() {
let arr = []
for (let i = 0; i < 10; i++) {
arr[i] = function () {
return i
}
}
return arr
}
let bar = foo()
console.log(bar[0]())
// 解决方法二:使用闭包
function fn() {
var arr = []
for (var i = 0; i < 10; i++) {
arr[i] = (function (n) {
return function () {
return n
}
})(i);
}
return arr
}
var fn2 = fn()
console.log(fn2[0]())
// 解决方法三:使用立即执行函数
function fun() {
var arr = []
for (var i = 0; i < 10; i++) {
(function (n) {
arr[n] = function () {
return n
}
})(i)
}
return arr
}
console.log("fun函数体" + fun())
var fn3 = fun()
console.log(fn3[0]())
console.log(fn3[1]())
console.log(fn3[2]())
function fn1() {
let i = 1
return function () {
return i
}
}
let fn11 = fn1()
console.log("执行aa函数的结果:" + fn11())
let fn22;
let fn2 = function () {
let name = 'sunX'
let fn = function () {
return name
}
fn22 = fn()
}
fn2()
console.log("执行fn2函数的结果:" + fn22)
function fn33() {
let name = 'sunX'
let a = function () {
return name
}
fn3(a)
}
let fn3 = function (a) {
console.log("执行fn3函数的结果:" + a())
}
fn33()
let fn4 = function (a) {
console.log("执行fn4函数的结果:" + a())
}
!(function () {
let name = 'sunXian'
let a = function () {
return name
}
fn4(a)
})();
let fn = function(){
let arr = []
for(let i = 0 ; i < 10 ; i++){
arr[i] = (function(n){
return function(){
return n
}
})(i)
}
return arr
}
console.log(fn[5]()) // 打印输出5
function setUp(arr) {
let i = 0
return function () {
return arr[i++]
}
}
let next = setUp(['aaa', 'bbb', 'ccc', 'ddd'])
console.log(next()) // 打印输出第一个参数 'aaa'
console.log(next()) // 打印输出第二个参数 'bbb'
function firstLoad(num) {
let arr = []
return function () {
if (arr.indexOf(num) >= 0) {
return false
} else {
arr.push(num)
return true
}
}
}
let flag = firstLoad(10)
console.log(flag())
console.log(flag())
let mult = (function(){
let cache = {}
let calculate = function(){
let sum = 0
for(let i = 0 ; i < arguments.length ; i++){
sum += arguments[i]
}
return sum
}
// 对cache对象进行操作
return function(){
let args = Array.prototype.join.call(arguments,',')
if(args in cache){
return cache[args]
}
cache[args] = calculate.apply(null,arguments)
return cache[args]
}
})()
console.log(multi(1, 2, 3, 4, 11, 8))
console.log(multi(1, 2, 3, 4, 11, 8))
console.log(multi(1, 2, 3, 4, 11, 8, 14))
var a = 0
let bar = function () {
console.log(this.a)
}
let obj = {
a: 1,
foo: bar(),
fo: bar
}
// 把obj.foo赋值给别名bar,造成隐式丢失的情况,因为只是把obj.foo()赋值给了bar变量,而bar与 obj对象毫无关系
obj.foo // 相当于 bar(),因此打印输出的是window下的a
obj.fo()
var b = 0
function fn(){
console.log(this.b)
}
function bar(fun){
fun()
}
let obj = {
b : 0,
fn:fn
}
// 把object的fn当做参数传递到bar函数中,有隐式的函数赋值,fn=obj.fn,只是把fn函数赋值给了 fun,而fun和obj毫无关系
bar(obj.fn)
bar(function(){
console.log(this.b)
})
var c = 100
function f() {
console.log(this.c)
}
let hhh = {
c: 66,
f: f
}
// 隐式绑定:函数当做对象的方法使用,内部的this指向了该对象
hhh.f()
let p = {c: 33}
// 将hhh.f赋值给p.f函数,之后p.f函数再执行,其实是属于p对象的方法的指向,this指向了当前p对象
p.f = hhh.f
p.f() // 打印输出p的属性c
// 立即调用:将f函数对象赋值给p的f函数,然后立即执行,相当于f函数的立即调用,内部的this默认指向 了window
!(p.f = hhh.f)(); // 指向window下的c
var a = 0
let bar = function () {
console.log(this.a)
}
let obj = {
a: 1,
fo: bar
}
!(obj.fo = object.fo)();
!(false || object.fo)();
!(1, object.fo)();
var a = '我是window下的a'
function fn() {
console.log(this.a)
}
let obj = {
a: '我是obj对象下的a'
}
fn()
fn.call(obj)
fn.apply(obj)
let f = fn.bind(obj) // 将fn函数绑定到obj中,并返回函数f
f()
let b = '我是window下的b'
function fun() {
console.log(this.b)
}
let ob = {
b: '我是ob对象下的b'
}
let bar = function () {
fun.call(ob)
}
// 都输出'我是ob对象下的b'
bar()
setTimeout(bar, 1000)
bar.call(window)
var c = 'window下的c'
function foo(el) {
console.log(el, this.c)
}
let o = {
c: 'o对象下的c'
}
let arr = [11, 22, 33]
// 只传递一个参数,因此打印输出'window下的c'
arr.forEach(foo)
// 第二个参数为o对象,打印输出'o对象下的c'
arr.forEach(function (el, index) {
console.log(el, index, this)
}, o)
function f() {
console.log(this)
}
f() // 打印输出window
new f() // 打印输出'f()函数'
function fn() {
console.log(this) // 因为实例化了对象,因此打印输出fn()
return {
name: 'sunX'
}
}
let Fn = new fn()
console.log(Fn) // 打印输出return返回的对象{name:'sunX'}
let Person = {
fav: function () {
return this
}
}
let p = new Person.fav()
console.log(p) // 由于是实例化的对象,因此打印输出fav{}
// 实例化出来的对象内部的属性constructor属性指向了当前的构造函数
console.log(p.constructor === Person.fav)
function f() {
'use strict'
console.log(this)
}
f() // 输出undefined
var color = 'red'
function showColor() {
'use strict'
console.log(this) // this指向undefined
console.log(this.color) // 报错
}
showColor.call(undefined)