一、一些弹框
1.输入框
var myname = prompt('请输入你的姓名');
2.警示框,展示给用户
alert(myname);
3.控制台输出
console.log('控制台输出,展示给程序员')
二、实践应用
1.倒计时程序
function countDown(time) {
var nowTime = +new Date(); // 返回的是当前时间总毫秒数
var inputTime = +new Date(time); // 输入时间总毫秒数
var times = (inputTime - nowTime) / 1000; // 转换成秒
var d = parseInt(times / 60 / 60 / 24); // 天
d = d < 10 ? '0' + d : d;//都转换成2位数
var h = parseInt(times / 60 / 60 % 24); // 时
h = h < 10 ? '0' + h : h;
var m = parseInt(times / 60 % 60); // 分
m = m < 10 ? '0' + m : m;
var s = parseInt(times % 60); // 秒
s = s < 10 ? '0' + s : s;
return d + '天' + h + '时' + m + '分' + s + '秒';
}
2.冒泡排序(记住)
sort本来就是冒泡排序,但是单独使用有bug,要配合function来写
var arr1 = [13, 4, 77, 1, 7];
arr1.sort(function(a, b) {
return a - b; // 升序
// return b - a; 降序
});
//ES6
arr1.sort((a,b)=>a-b)
3.去重函数
indexOf(从头开始搜索,lastindexOf从尾开始)从字符串中搜索传入的字符串,返回符合条件的第一个index,找不到返回-1
function unique(arr) {
var newArry = [];
for (i = 0; i < arr.length; i++) {//遍历要操作的数组
if (newArry.indexOf(arr[i]) === -1) {//如果newArry里没有相同的
newArry.push(arr[i]);//添加这个元素
}
}
return newArry;
}
var demo = [1, 2, 3, 3, 4, 4, 5, 'a', 'a', 'b']
console.log(unique(demo));
4.打印字符串中重复的'o'的索引号
var str = 'oabdcdjfiaejofqaiqooeo';
var index = str.indexOf('o');//只能取第一个o的索引号
//indexof找不到返回-1,while先执行里面的
while (index !== -1)
{
index = str.indexOf('o', index + 1);//第二个参数是起始索引号
console.log(index);
}
5.统计str中字母的次数和出现最多的字符数
charAt()方法返回给定索引位置的字符;
charCodeAt()返回字符编码
//定义一个对象
var o = {};
for (i = 0; i < str.length; i++) {
var chars = str.charAt(i); // chars是不断更新的字符串的每一个字符 charAt=str[index]
if (o[chars]) //对象['属性名']:判断该对象有无该属性
{o[chars]++;} else {
o[chars] = 1;}
}
var max = 0
var ch = ''
for (var k in o) {
//k是属性名 o[k]是属性值
if (o[k] > max) {
max = o[k];
ch = k;
}
}
console.log(ch + '最多,有' + max + '次');
6.多次点击在两个照片和文本之间切换
var flag = 0;
eye.onclick = function() {
if (flag == 0) {
pwd.type = 'text';
eye.src = 'image1';
flag = 1;
} else {
pwd.type = 'password';
eye.src = 'image2';
flag = 0;}
}
}
三、排他思想
1. 定位元素
- 父元素.document.getElementByTagName('子元素'),返回的是指定标签名的元素对象的集合,以伪数组的形式储存。父元素默认是window,可以不写。实际不区分大小写,在XHTM中区分。
- document.getElementById(''),没找到返回null,敏感大小写。返回在文档中出现的第一个元素。
- document.getElementByName(''),常用于单选按钮
- document.querySelector('') .class/#id,返回指定选择器中的第一个元素对象
- document.querySelectorAll('')返回指定选择器中的元素对象的集合,以伪数组的形式储存。
- document.body获取body
var btns = document.getElementsByTagName('button');
//for循环绑定点击事件
for (var i = 0;i<btns.length;i++){
btns[i].onclick = function(){
//先把所有按钮的背景颜色都去掉
for (var i = 0;i<btns.length;i++){
btns[i].style.backgroundColor = '';
}
this.style.backgroundColor = 'pink';
}
}
2.鼠标事件
鼠标经过事件onmouseover
鼠标离开事件onmouseout
习惯在css中写样式,所以JS经常搭配this.className使用
- 全选框案例
var j_cbAll = document.getElementById('j_cbAll'); //全选按钮
var j_tbs = document.getElementById('j_tb').getElementsByTagName('input'); //j_tb里全部input(复选框)
j_cbAll.onclick = function() {
for (var i = 0; i < j_tbs.length; i++) {
j_tbs[i].onclick = this.checked; //复选框的checked是全选框的checked,只有ture和false两个选项
}
}
for (var i = 0; i < j_tbs.length; i++) {
j_tbs[i].checked = function() {
//flag控制全选按钮是否选中
var flag = ture;
//每次点下面的复选框都要检查是否全部选中,来决定全选按钮的值
for (var i = 0; i < j_jbs.length; i++) {
if (!j_jbs.checked) {//没选中才执行
flag = false;
break //提高效率
}
}
j_cbAll = flag;
}
}
3.获取元素的属性值
1)element.属性 系统自带
2)element.getAttribute('属性') 主要自定义属性 H5规定自定义属性以date-开头
4.修改属性值
1)element.属性 ='值'
2)element.setAttribute('属性','值')
3)移除属性removeAttribute(属性)
5.案例:点击列表就会显示对应内容
for (var i = 0; i < lis.length; i++) { //lis是列表
//给五个小li设置索引号
lis[i].setAttribute('index', i)
lis[i].onclick = function() {
for (i = 0; i < lis.length; i++) {
lis[i].className = ''; //排他
}
this.className = 'current';
//显示对应的内容模块
var index = this.getAttribute('index');
for (i = 0; i < item.length; i++) {
item[i].style.display = 'none';//排他
}
item[index].style.display = 'block';//显示对应内容模块
}
}
四、节点
nodeType:元素节点--1;属性节点--2;文本节点--3
一般的,节点至少拥有nodeType节点类型、nodeName节点名称和nodeValue节点值三属性
1.分类
1)父级节点
.parentNode,没有则返回null
2)子节点
.childNodes所有的子节点,包含元素节点 文本节点等 不常用
.children获取所有子元素节点,常用
firstChild lastChild第一个子节点
firstElementChild lastElementChild ie9以上 第一个子元素节点
.children[0];ol.children[ol.children.length - 1];开发中常用
3)兄弟节点(不常用)
next/previousSibling下一个节点
next/previousElementSibling下一个元素节点 ie9
2.操作
1)创建元素节点
元素加单引号
document.creatElement('元素');
2)添加节点
父级.appendChild(子级);//在这个子级后追加元素,类似于数组的push,不加单引号
父级.insertBefore(创建的节点名称,父级.children[x]);//在指定的位置添加元素
li.innerHTML = text.value;//把text的value值赋值给li
3)删除节点
父节点.removeChild(要删除的子节点)
4)克隆节点
node.cloneNode();//括号为空/false,浅复制,只复制标签不复制里面内容
node.cloneNode(true);//深复制,都复制
5)动态表格的制作
var datas = [{name: '1',subject: '语文',score: 100}, {name: '2',subject: '语文',score: 99}, {name: '3',subject: '语文',score: 98}]
var tbody = document.querySelector('tbody');
//创建人头数个行
for (i = 0; i < datas.length; i++) {
var tr = document.createElement('tr');
tbody.appendChild(tr);
//按属性个数创建单元格 for遍历对象 datas[i]
for (var k in datas[i]) {
var td = document.createElement('td');
tr.appendChild(td);
//把属性值给td
td.innerHTML = datas[i][k];
tr.appendChild(td);
}
//创建有删除的单元格
var td = document.createElement('td');
td.innerHTML = '<a href="javascript:;">删除</a>';//javascript:;可以不跳转页面
tr.appendChild(td);
}
- innerHTML比createElement()创建元素效率高(innerHTML不要拼接字符串,而是采取数组形式拼接,结构稍微复杂
- 修改元素属性:src,href,title等;
- 修改普通元素内容:innerHTML、innerText
- 修改表单元素:value、type、disabled等
- 修改元素样式:style、className
五、注册事件:
1)传统方式:一个元素一个事件只能设置一个处理函数。(btn.onclick=function(){})
2)方式监听:addEventListener() ie9之前不支持,用attachEvent()代替;一个元素一个事件可以注册多个监听器(事件处理程序),按注册顺序依次执行
目标对象.addEventListener('事件类型字符串,如click',function{},useCapture)//第三个参数为false或者省略则处于冒泡阶段,ture为捕获阶段
onblur失去焦点/onfocus获得焦点/onmouseenter/onmouseleave没有冒泡
1. 删除(解绑)事件
传统:目标元素.onlick = null;
方式监听:
divs[0].addEventListener('click',fn)//fn不要加小括号
function fn(){
alert(11);
divs[0].removeEventListener('click',fn);//解绑}
2. 绑定事件函数的形参
function fn(事件对象){}中的形参一般命名为event/evt/e;是我们事件的一系列相关数据的集合,跟事件相关的。
3. this返回绑定元素
4. 事件委托
事件监听器放到父节点上,利用冒泡法影响每个子节点。
例子:禁止右键菜单和禁止选中
重点记住page 如果要使用注意加单位 比如:var x = e.pageX;
pic.style.left = x + 'px';
只要鼠标移动1px,就触发该事件
document.addEventListener('mousemove',function(e){})
五、键盘事件
- onkeyup:某个键松开触发;onkeydown:某个键按下触发;onkeypress:按下触发,不识别功能键
- 在使用addEventLisener时不加on,顺序:keypress-keydown-keyup;press区分大小写,down和up不区分
- 注意:keydown和keypress在文本框中的特点:两个事件触发时,文字还没落入文本框中
- 键盘事件对象e.key返回按下的键。区分大小写
六、BOM
如果想把JS写在HTML的上端
window.onload = function{JS}//只能写一次,有多个则只对最后一个有效
或者
window,addEventListener('load',function(){JS})//等页面内容全部加载完毕,包括dom元素 图片 flash css等
//DOMContentLoaded是DOM加载完毕,速度快,用于图片多的网页加载重要的内容
1.窗口高度和宽度
获取当前屏幕宽度 window.innerWidth;获取当前屏幕高度 window.innerHight
window.addEventListener('resize',function(){});//调整窗口大小加载的事件
2.计时器 指向window
setTimeout(function() {
console.log('时间到了');
}, 2000); //window在调用时可省略,延时单位是毫秒,可省略,默认是0
function callback() {
console.log('爆炸了');
}
var time1 = setTimeout(callback, 3000);//为了区别定时器,起不同的标识符(名字),callback是回调函数,只调用一次
var time2 = setInterval(回调函数,间隔毫秒数);//每个这个延迟时间,都会调用这个函数
3.停止计时器
写计时器有关的函数时,第一句话加上clearInterval(obj.timer)可以避免计时器重复叠加。 使用给形参加参数的方式定义计时器,提高效率,如 obj.timer = setInterval(function{})
clearTimeout(time1)//time1计时器的标识符
clearInterval(time1)
4.页面倒计时案例落地
var inputTime = +new Date('2022-10-13 18:00:00'); // 输入时间总毫秒数
countDown(); //先调用一次这个函数;防止第一次刷新页面有空白
//开启定时器
setInterval(countDown, 1000);
function countDown(time) {
var nowTime = +new Date(); // 返回的是当前时间总毫秒数
var times = (inputTime - nowTime) / 1000; // 转换成秒
var d = parseInt(times / 60 / 60 / 24); // 天
d = d < 10 ? '0' + d : d;
day.innerHTML = d; //把天数给天数的小盒子
var h = parseInt(times / 60 / 60 % 24); // 时
h = h < 10 ? '0' + h : h;
h.innerHTML = h; //把小时给小时的小盒子
var m = parseInt(times / 60 % 60); // 分
m = m < 10 ? '0' + m : m;
m.innerHTML = m; //把分钟给分钟的小盒子
var s = parseInt(times % 60); // 秒
s = s < 10 ? '0' + s : s;
s.innerHTML = s; //把秒给秒的小盒子
}
- 如果两个函数都要使用一个变量,可以在函数外定义一个全局变量var time1=null;
- button里面的值是通过innerHTML修改的
七、同步任务与异步任务
同步任务在执行栈中执行,先执行同步任务,异步任务(回调函数)放进任务队列中。执行完同步任务,再依次读取任务队列中的异步任务,放入执行栈中,开始执行。
1.异步任务类型
- 普通事件,click、resize等
- 资源加载,load、error等
- 定时器,setInterval、setTimeout等
2.location
没有历史记录形式
location对象属性
例子:
console.log(location.search);//?uname=andy
//先去掉?:substr('起始位置',截取几个字符);
var params = location.search.substr(1);//省略第二个参数直接截取到最后
var arr = params.split('=');//将字符串分割成数组
location对象方法
3.history
八、offset
1.offset与style
例子
//鼠标按下获得鼠标相对于.box的坐标
var box = document.querySelector('.box');
var movebox = document.querySelector('.movebox')
movebox.addEventListener('mousedown', function(e) {
//e.page和offset返回的都不带单位
var x = e.pageX - box.offsetLeft;
var y = e.pageY - box.offsetTop;
this.innerHTML = 'x坐标是' + x + 'y坐标是' + y;
//鼠标在document里面走,盒子跟着他走
document.addEventListener('mousemove', move)
function move(e) {
box.style.left = e.pageX - x + 'px';
box.style.top = e.pageY - y + 'px';
}
//鼠标弹起,就让移动事件移除
document.addEventListener('mouseup', function() {
document.removeEventListener('mousemove', move)
})
})
九、client
十、立即执行函数
独立创建了作用域
- 1)(function(形参){})(实参);
- 2)(function(形参){}(实参))
十一、scroll
1.对比
2.应用
滚动窗口至文档中的特定位置
window.scroll(x,y);//注意,x和y不跟单位,直接写数字
滚动动画
function animate(obj, target, callback) {
//先清除以前的定时器,避免定时器叠加
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
//停止动画
clearInterval(obj.timer);
callback && callback()
}
})
}
十二、mouseenter mouseover
缓动动画
var step = {target - obj.pffsetLeft} / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);//前进向上取整,后退向下取整
十三、回调函数
当这个函数执行完执行的函数。当作形参写在定时器结束的函数里。
1.无缝滚动
原理:复制第一张到最后一张后面,然后跳转到第一张
2.回调函数与节流阀
3.回调函数的短路运算
callback&&callback();
轮播图
window.addEventListener('load', function() {
//获取元素
var arrow_1 = document.querySelector('.arrow-1');
var arrow_2 = document.querySelector('.arrow-2');
var focus = document.querySelector('.guanggao');
var focusWidth = focus.offsetWidth;
var ul = focus.querySelector('ul');
var ol = focus.querySelector('ol');
//鼠标经过显示按钮
focus.addEventListener('mouseenter', function() {
arrow_1.style.display = 'block';
arrow_2.style.display = 'block';
//暂停自动播放按钮
clearInterval(timer);
timer = null;
})
//鼠标离开隐藏按钮
focus.addEventListener('mouseleave', function() {
arrow_1.style.display = 'none';
arrow_2.style.display = 'none';
//手动调用点击事件
timer = setInterval(function() {
arrow_2.click();
}, 2000);
})
//动态生成小圆圈,几张图几个圆圈
for (var i = 0; i < ul.children.length; i++) {
var li = document.createElement('li');
li.setAttribute('index', i);
ol.appendChild(li);
//在里面写哦 小圆圈的排他思想
li.addEventListener('click', function() {
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
var index = this.getAttribute('index');
num = index;
circle = index;
//别忘了加单位!!
ul.style.left = -index * focusWidth + 'px';
}
this.className = 'current';
})
}
//ol中的第一个li设置为current
ol.children[0].className = 'current';
//克隆第一张图片(li)放到ul最后面,因为在生成小圆圈后克隆的,所以不增加小圆圈数量
var first = ul.children[0].cloneNode(true);
ul.appendChild(first);
var num = 0;
var circle = 0;
arrow_2.addEventListener('click', function() {
// 如果走到了最后,从最后一张(和第一张图片一样)到第一张
if (num == ul.children.length - 1) {
ul.style.left = 0;
num = 0;
}
num++;
ul.style.left = -num * focusWidth + 'px';
circle++;
//到达我们创造的伪图像时,小圆圈变成第一个
if (circle == ol.children.length) {
circle = 0;
}
circleMove()
})
arrow_1.addEventListener('click', function() {
// 如果走到了最后,从最后一张(和第一张图片一样)到第一张;这里的负号代表位置为负
if (num == 0) {
num = ul.children.length - 1;
ul.style.left = -num * focusWidth + 'px';
}
num--;
ul.style.left = -num * focusWidth + 'px';
circle--;
if (circle < 0) {
circle = ol.children.length - 1;
}
circleMove()
})
function circleMove() {
//排他思想
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
ol.children[circle].className = 'current';
}
//自动播放轮播图
var timer = setInterval(function() {
arrow_2.click();
}, 2000);
})
十四、存储
1.本地存储
- 数据存储在用户浏览器中
- 设置、读取方便、甚至刷新页面也不丢失数据
- 容量较大,sessionStorage约5M,localStorage约20M
- 只能存储字符串,可以将对象JSON。stringify()编码后存储
2.sessionStorage
sessionStorage的增查删
3.local
十五、原型对象
公共属性定义到构造函数里,公共方法放到原型对象身上。每个函数都有个prototype对象,可以利用它来节省内存。
1.构造函数原型protptype
举例
注意:不能直接对_proto_进行赋值等操作
2.constructor
对象原型_proto_和构造函数原型对象prototype里都有个constructor属性,称为构造函数,因为它指回构造函数本身
例子
prototype被下面两个对象覆盖掉了
3.指向与关系
原型链
- 查找规则:按原型链的顺序查找,直到找到位置。
- 原型对象和构造函数中的this都指向调用他的实例对象
扩展实例对象
4.修改this指向--call()
子构造函数继承父构造函数的一些属性
利用原型对象实现继承
5.es6中的类就是构造函数的语法糖
十六、数组遍历
1.主要用于遍历
2.主要用于筛选,返回新数组
3.主要用于查找,返回布尔值
在forEach里面return true不会终止迭代,some会。
十七、字符串的方法
1.trim的使用
2.新增、修改属性
使用defineProperty定义的属性是默认false,使用逗号连接,最后一个不用写
十八、对象的方法
十九、函数
1.函数的创建
2.函数的原型链
3.函数调用
4.this指向
改变this指向
- 1)call
- 2)apply
例子:输入是数组,但是输出是字符串或者数字。
- 3)bind 返回的是新函数且不会调用函数
应用
二十、严格模式
if for里不允许声明函数
1.高阶函数
2.闭包
有权访问另一个函数作用域中的变量的函数。延伸了变量的作用范围
3.递归
4.浅拷贝
只拷贝一层,更深层次对象级别的只拷贝引用(指向同一地址,一改都改)
es6
Object.assign(目标,被拷贝的)
二十一、正则表达式
正则表达中不需要加引号,不管是什么类型。test中字符串型需要加引号。
var rg = /abc/; //只要包含abc就可以
var rg1 = /^[a-z]$/; //a-z中的字母任选一个。字符类[]表示任选一个
字符组合,直接连在一起
量词符 在要限制的符号后写
左边那个模式重复6-16次,{}里不要有空格
预定义类
替换可以用正则表达式的形式
text.value.replace(/被和谐/g,'替换的内容');