面向对象相关联导图 |
1json
json数据渲染-字符串拼接变量法
var a=" ";
for(var i=0;i<arr.length;i++){
a += "<dl><dt>"+arr[i].name+"</dt>";
for(var j=0;j<arr[i].content.length;j++){
a += "<dd class="+arr[i].content[j].hot+">"+arr[i].content[j].name+"</dd>";
}
a += "</dl>"
box.innerHTML = a; //别忘记获取对象追加页面
}
//渲染数据时字符串拼接比较麻烦-"字符串"+变量
//es6[现在es5语法]字符串拼接: `` 反引号代替'' , ${变量}代替原来变量写法
三.json数据渲染-dom法
1.找最外层dom对象: oUl
2.遍历数据
3.创建内层元素 var oLi=obj.createElement('li')
4.追加到父元素里 oUl.appendChild(oLi);
5.拼接字符串 oLi.innerHTML='
四.json数据大部分是后台给你的,后台给你数据都是'{}',原本要用的对象{},把它转成原本格式用到的方法:eval("("+原本对象+")");
五.拼音简写-数据在处理
六.下拉列表
0.找元素对象
1.改变事件 onchage()
2.处理事件里逻辑
处理逻辑
obj.onchage=function(){
//改变时拿到当前索引内的值select对象属性: options ,selectedIndex
oinpt.value = osel.options[this.selectedIndex].innerHTML;
}
七.二级联动
1.渲染省数据: option动态追加:
options.innerHTML = "请选择"; 增加一个索引
创建元素,追加元素
2.省改变,市数据渲染
取省索引-注意要把省索引与市索引一一对应上
//取二维数组里的值
options.innerHTML = data[province.selectedIndex][i].name;
八.三级联动
数据 var address=[{}, {},{}] ;
1.渲染省 address[i].name
for(var i in address){
address[i].name
}
2.省改变渲染市 address[i].children
//定义全局变量 index ,后面的市改变会依赖前面的省的索引
index=this.selectedIndex-1
for(var j in address[i].children.length){
address[i].children[index].name
}
3.市改变渲染县
九.购物车
1.渲染数据
var add=`<li style="width: 178px">${json.shangpin}</li>
<li style="width: 100px">${json.jiaqian}</li>
<li style="width: 225px">${json.pingjia}</li>
<li style="width: 65px">${json.kucun}</li>
<li style="width: 84px">${json.haoping}</li>
<li style="width: 98px"><input type="text" value="加入购物车"></li>`
oUl.apendChild(add)
2.点击加入购物车事件:
拼接新的字符串
var str=`<li style="width: 228px">获取当前点击的商品内容 innerHTML</li>
<li style="width: 150px">获取点击单价 innerHTML</li>
<li style="width: 125px">数量 3个Input</li>
<li style="width: 149px">
获取金额innerHTML-封装公用金额变化方法aaa()
</li>
<li style="width: 98px"><input type="text">
删除按钮
</li>`
for(){
oinpt.onclick=function(){
//追加
ocart.apendChild(str)
//总价
sum()
}
}
3.计算总计方法 sum(){
for(){
//获取所有金额累加 +=
}
}
4.加+事件 plus(){
数量改变:数量++ -可封装公用金额变化方法aaa(数量*单价)
sum()
}
5.减-事件 jian(){
数量改变:数量--
sum()
}
6.点击删除事件
delete(){
删除当前祖辈元素
同时总价变化 sum()
}
2鼠标滚轮
dom0级事件绑定方法: obj.事件=function(){}
DOMMouseScroll -ff火狐 dom二级事件:需要通过事件绑定方式执行
obj.addEventListener('不带on事件',函数,false)
obj.addEventListener('DOMMouseScroll',函数,false)
全屏滚动-渲染不同图片数据
给当前这一屏追加内容
当前这一屏怎么获取?可以追加一个class 进行标识,我现在在第几个
pages[n].className = "page page"+i+'active' //输出成整体了
page page4active
编写工具方法 addClass(obj,追加的类)-实现标识page page4 active
建议日常积累的常用代码块放入自己的库里: public_pc.js
渲染:随机出现
//JSON.parse 跟eval功能一样,少用eval, 把字符串对象转换成真正的json对象
------------------------------
9.全屏问答游戏
1.产生随机数后不能重复渲染数据:
//通过splice()方法 将下标为随机数的对象从数组中切出来
arr.splice(randomNum,1) //得到切出来的对象,原数组就不会存在那个值
对切出来的对象进行读取-切出来一个渲染一个
2.可对每个答案点击事件进行事件代理(事件委托)方法操作
事件委托:把子级的元素事件统一委托给父级执行
优点:可提高性能,也可给未来元素追加事件
实现:
父元素.onmouseover = function(ev){
var ev = ev || window.event;
//目标源:来源于哪个元素
var target = ev.target || ev.srcElement;
//console.log(target.innerHTML);
//通过判断具体是划上的哪个儿子标签 ev.target.nodeName 默认输出是大写,通过 toLowerCase()转成小写
if(target.nodeName.toLowerCase() == "li"){
target.style.background = "red";
}
}
3.用户点击时计算分数同时自动跳到下一页
定义全局变量分数 score,同时num++,执行切换方法,
无缝滚轮
通过继承实现淡入淡出
5-1同步异步,自执行函数
自执行函数
特点:
1.省个函数名
2.里面的变量也是局部变量
3.形成了封闭的空间,主要是用于隔离作用域。除了局部作用域避免污染,广告,第三方统计需求这种,也是需要自执行的
用法:
1.自执行函数 (函数)()
(function (){
alert('a');
})();
2.第二种写法(function(){}()) -推荐用这种
(function(){
alert('b');
}());
3. 函数有名字也可以:
(function show(){
alert('c');
}());
或者
(function show(){
alert('c');
})();
//作用:主要用于隔离作用域,形成封闭空间,互不影响,避免函数重名造成的问题
(function show(){
alert('c');
}());
function show(){
alert('c');
}
show();
数组filer
筛选数据内容思路:
一.根据事件进行筛选
1.获取焦点事件
opt.oninput=function(){
//根据获取内容对比遍历所有数据里名字name,符合的显示-字符串indexOf方法
if(personArr[i].name.indexOf(txt)!=-1)
}
2.点击all事件
$$('span')[2].onclick=function(){
//两种情况:1.输入文本为空时 2.不为空
for(){
//为空时,全部数据渲染
$$('ul li')[i].style.display='block'
//不为空:获取内容对比遍历所有数据里name
}
}
3.点击男,女事件单独写-因为要遍历性别
obj.onclick=function(){
for(){
//为空时
if(txt==undefined){
//筛选性别出来
if(personArr[i].sex.indexOf(sexM)==-1){ }
}
}
//不为空
else{
//名字与性别同时满足才显示
if(personArr[i].name.indexOf(txt)!=-1&&personArr[i].sex.indexOf(sexM)!=-1)
{
$$('ul li')[i].style.display='block'
}
}
链式运动
链式运动:一个物体运动完,下一个运动开始
思考问题:
1.一个运动里怎么让一个物体同时加多个属性-可传入对象json={width: 400, height: 400}
for(var attr in json) //循环执行json里的值
{
}
2.怎么判断是否有没走完的{}目标值-可加开关进行判断
cur=parseInt(getStyle(obj, attr)) //获取非行间样式
if(cur!=json[attr]) //判断是否有没执行完的目标值-cur是获取对象里的值跟页面上的对象对比
bStop=false;
2.1匀速速度设置:
匀速速度=(对象里的值-当前走了多少的值)/6
var speed=(json[attr]-cur)/6;
最后赋值对象上:
obj.style[attr]=cur+speed+'px';
3.如何设置回调函数-一个对象走完后,接着另一个对象
if(bStop) // 如果目标值全部都执行完了,执行这一步,清除定时器,
{
clearInterval(obj.timer);
if(fnEnd)fnEnd(); //如果还有传入的目标值继续执行
}
4.多个物体运动时-清除定时器,要清除自己对象的,否则定时器会累加
obj.timer=setInterval(function(){},30)
clearInterval(obj.timer);
原型继承
// var arr=[1,2];
// console.log(arr) //可以查看原型链关系
function Person(){ //构造函数父类
this.name='小米';
this.color='黄色';
this.eat=function(){
console.log('吃东西')
}
}
//通过原型扩展父类方法
Person.prototype.aa=function(){
console.log('哈哈'+this.name)
}
function Son(){ //构造函数子类
this.gender='男';
this.hobby='玩';
this.say=function(){
console.log('说话')
}
}
//1.通过原型实现继承方法:
//构造函数名.prototype=new 构造函数名();
Son.prototype=new Person(); //原型继承:建立继承关系
var son1=new Son(); //实例化子类
son1.say();//调用自己方法
son1.eat();//调用父类方法
console.log(son1.name) //小米
son1.aa() //哈哈小米...00
面向对象概念
面向对象的一些属性和方法
hasOwnProperty() : 看是不是对象自身下面的属性
constructor : 查看对象的构造函数
每个原型都会自动添加constructor属性
For in 的时候有些属性是找不到的
避免修改construtor属性
instanceof : 运算符
对象与构造函数在原型链上是否有关系
toString() : object上的方法
面向对象编程基础
面向对象编程(OOP)的特点:
抽象:抓住核心问题
封装:只能通过对象来访问方法
继承:从已有的对象下继承出新的对象
多态:多对象的不同形态,目的是灵活的复用
JS不支持面向对象(半面向对象)
最终目的:方便扩展,灵活复用
.建立面向对象3步:
1.创建构造函数或类(公有属性):
function Person(name1,gender1){ //声明一个构造函数
this.name=name1; // 把变量变成对象的属性用this
this.gender=gender1;
}
2.通过原型扩展构造函数功能:把函数变成对象的方法(用prototype)
Person.prototype.eat=function(){
console.log('姓名:'+this.name+'性 别:'+this.gender)
}
3.创建实例化对象,通过new
var man=new Person('奎哥','男');
调用方法:
man.eat();
man.say();
继承组件封装
原型链:new出的对象的属性(__proto__)与构造函数原型(prototype)之间的关系
// 原型链关系:原型链的形成是真正是靠__proto__
// 构造函数有属性:prototype ,对象有隐式属性:__proto__ ,js中一切又都是对象
console.log(Person.prototype==man.__proto__) //true
console.log(Person.prototype.__proto__==Object.prototype) //true
console.log(Object.prototype.__proto__==null) //true
二.
1.通过原型实现继承方法:
//构造函数名.prototype=new 构造函数名();
Son.prototype=new Person(); //建立继承关系
var son1=new Son(); //实例化子类
2.通过call或aplly改变this指向实现继承-常用
function Son(){
this.gender='男';
this.hobby='玩';
this.say=function(){
console.log('说话')
}
Person.call(this); //在子类里通过call方法改变父类指向,让它指向子类
}
三.思考:将方法写在原型里与将方法写在构造函数里有什么不同
1.把方法写在原型中比写在构造函数中消耗的内存更小,因为在内存中一个类的原型只有一个,而写在类中的方法,实例化的时候会在每个实例中再复制一份,所以消耗的内存更高
所以没有特殊原因,我们一般把属性写到类中,而方法写到原型中
2、构造函数中定义的属性和方法要比原型中定义的属性和方法的优先级高,如果都定义了同名称的属性和方法,构造函数中的将会覆盖原型中的
本地储存localStorage
---------------------------------
--------------------------
一.本地数据库 webStorage:包含两个 localStorage ,sessionStorage 可把数据存储到本地(浏览器上)
查看: F12-application-找到,localStorage常用些
应用场景:搜索记录,浏览记录,购物车,角标等
注意!!!存储要的是字符串类型
localStorage,sessionStorage,cookie 区别
cookie localStorage sessionStorage
容量 4K 5M
过期 有 没有 浏览器关闭过期
网络 走 不走
兼容 兼容 不兼容 (IE6,7,8)
-------------------------------
1.如何存:
localStorage.a=12;
取:
localStorage.a
删除:
delete localStorage.a
-------------------------------
2.第二种用法:
存:
localStorage.setItem('a',12);
用:
localStorage.getItem('a')
删除:
localStorage.removeItem('a');
-------------------------------
localStorage.clear(); 清空所有
-------------------------------
----------------------------------
sessionStorage-浏览器关闭后就失效 -用法同上
----------------------------------
------------------------------------------------------------------------------------------
二.cookie介绍:
Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。
例如购物网站存储用户曾经浏览过的产品列表,或者门户网站记住用户喜欢选择浏览哪类新闻。 在用户允许的情况下,还可以存储用户的登录信息,使得用户在访问网站时不必每次都键入这些信息?
cookie用法:
其它浏览器打开,文件要放在服务器,火狐中可直接打开
cookie(可在火狐中打开,也能直接读取cookie):
离不开wamp:
必须要有域名,才能用cookie
域名:一个域名值能有一个cookie
cookie不能"跨域"
"跨域"==两个域名的cookie不能共享
做什么?
保存信息
用在哪?
自动登录,记住用户信息(用户名,密码,地址)
大小: 4k左右 4*1024英文 2*1024中文
为什么小?
出现的早
cookie在哪?
浏览器的缓存文件,在用户的电脑上
安全:别存隐私
cookie里面可以有很多条字符:
expires 过期(3天后过期,1小时后,几年)
session 会话结束(浏览器关闭cookie消失)
------------------------------------------------------------------------------------------设置cookie document.cookie=值 值:'属性=值'
读取cookie document.cookie
多个cookie的读取: alex=123; blue=123; jianjian=123; xuxu=123
;空格
cookie如果没有 返回'';
属性名相同会相互覆盖
轮播组件
弹窗案例:
初始化:
var d1 = new Dialog();
d1.init({ //配置参数,有配置走配置,没配置走默认
w : 100,
h : 400,
dir : 'right',
title : '公告'
});
----------------------------------------------------
一.思考:如何配置参数和默认参数-对外暴露哪些属性:
1.1居中弹窗:
{ //配置参数
w : 300,
h : 300,
dir : 'center',//方向
title : '登录'
}
1.2靠右弹窗:
{ //配置参数
w : 100,
h : 400,
dir : 'right',
title : '公告'
}
提练公有属性:默认参数配置:
function Dialog(){
this.oLogin = null;
this.settings = { //默认参数
w : 300,
h : 300,
dir : 'center',
title : ''
};
}
----------------------------------------------------
二.参数如何合并?
Dialog.prototype.init = function( opt ){
//1.把new传入的对象合并到默认参数,如果有冲突就合并,没有就继承默认参数
extend( this.settings , opt );
this.create();
this.fnClose();
};
function extend(obj1,obj2){
for(var attr in obj2){
obj1[attr] = obj2[attr];
}
}
----------------------------------------------------
三.弹窗动态创建共用方法create(如何找相同方法):
Dialog.prototype.create = function(){
this.oLogin = document.createElement('div');
this.oLogin.className = 'login';
this.oLogin.innerHTML = '<div class="title"><span>'+ this.settings.title +'</span><span class="close">X</span></div><div class="content"></div>';
document.body.appendChild( this.oLogin );
this.setData();//不同方向方法
};
----------------------------------------------------
四.如何设置不同位置方法setData(单独找不同方法)
this.oLogin.style.width = this.settings.w + 'px'; //获取自己宽高
this.oLogin.style.height = this.settings.h + 'px';
if( this.settings.dir == 'center' ){
//居中
}
else if( this.settings.dir == 'right' ){
//居右
}
----------------------------------------------------
----------------------------------------------------
第二个:多次事件点击会重复创建元素产生覆盖问题:通过判断是否是当前对象{}点击后加入开关解决
1.可给每个初始化方法索引,iNow :0,1,2...,
var d1 = new Dialog();
d1.init({ //配置参数
iNow : 0,
title : '登录'
});
2.初始化init()方法时通过判断是否是当前对象{}点击后加入开关——实现同一个对象点击多次只能执行一次
if(this.json[opt.iNow]){
this.create();
this.fnClose();
if(this.settings.mark){
this.createMark();
}
this.json[opt.iNow] = false;
}
3.关闭事件时fnClose(),给当前对象打开
This.json[This.settings.iNow] = true;