学习新技术的时候可以做夜歌todomvc项目
Stack Overflow
msdn.itellyou.cn
================================Html+css========================================
1.HTML:是一门标记语言,是展示数据的;
CSS:美化页面的;
Js:控制网页内容,给页面增加效果;
2.由于浏览器中有JavaScript引擎所有可以运行JavaScript代码;
3.JavaScript中有错误代码后面的JavaScript就不执行,但是不同的的script标签中互不影响;
<!DOCTYPE html>是H5的标准,所以Script标签中可以不写type/JavaScript(language=“en”)
4.script的标签一般是放在body标签中最后面;因为如果放在最前面会阻塞渲染(遇到script会停止当前页面树的渲染,解析JS完成后从暂停的地方继续开始渲染)
5.变量的声明(有var 没值)var name;
变量的初始化(有var 有值) var name=“小黑”
/*字符串类型的值都用双引号和单引号*/
- “=”的意义是赋值 “==”的意义是比较;
- 名字的声明尽量用英语,可以上网翻译,记得使用驼峰命名法;
- //单行注释一般是在一行代码上面;
/**/多行注释:一般是用在函数或者一段代码
- tyoeof 变量名 可以获得除null外原始类型变量名的类型和function这个对象类型,其他对象类型会显示成object ,instanceof 可以获得对象类型的类型,但是不能获得原始类型的类型;
- Console 中字符串是黑色的,数字是蓝色的;
- 不要拿小数验证小数,精度会出现问题
Var num1=0.1;
Var num2=0.2;
Num1+num2==0.3 ------> false;
- 如果一个是字符串,一个是数字两个相减的时候,会转换成数字;“10”-5=5;
- 类型的转换: 1. 数字的转换parseInt.parseInt.Float
- 字符串的转换 num.toString()有意义的才转换 即有值;
14.prompt是输入的弹框 输入的是字符串,如果要用于计算要用parseInt(prompt(“ ”));
15.创建变量的三种方式:①使用系统的构造函数创建对象;var obj=new object;
②自定义构造函数创建对象:
function Person ( ) { 自定义构造函数}
var obj =new Person();自定义构造对象
在自定义构造函数和创造对象的时候做的四件事:
- 在内存中创建一个内存空间,存储对象
- 设置this 为当前的对象;
- 设置对象属性和方法的值;
- 返回this;
③字面量的创建:var obj={}等同创建对象类似自定义变量
Var obj={name:“”,sex:“”,age:“”}
16 值类型的值在栈中储存,引用类型的对象在堆中存放(内存),地址在栈中存放;
- 遍历数组用for(key in arrays)和forEach(value,key,arr)遍历对象用for of
- 内置对象:①Math②String③Arrays④Date
- Arguments可以获取方法括号内的值;(var max=arguments[0];)
- 标签自定义属性用getAttribute()来获取;标签自带的属性可以用element.Attribute获取;
- NodeType 是节点的类型如果是1--标签 2--属性 3--文本;
nodeName 是节点的名字 大写---标签 小写---属性名 #text 文本
- *获取节点和元素的代码,谷歌火狐都支持 ,但是获取节点在IE8中获取的是元素,而获取元素的在IE8中没定义,不兼容;
23.如果是用循环添加事件就用命名事件,因为节省内存空间;如果不是就用匿名事件;
24.*为同一个元素添加多个事件可以使用addEventListener(“事件类型”,事件处理函数,false);谷歌和火狐支持;但是IE8只支持attentEvent(“有on的事件类型”,事件处理函数);
25.方法和函数的区别:方法是需要用对象调用的,而函数直接调用;
Eg: 方法: 对象.sayHi(); 函数: sayHi();
26.判断有没有这个方法的时候直接写方法名,不要加();
Eg;if(sayHi){ console.log(“有sayHi方法”)}else{“没有sayHi方法” }
- 绑定事件和解绑事件:
* 注意:用什么方式绑定事件,就应该用对应的方式解绑事件
* 1.解绑事件
* 对象.on事件名字=事件处理函数--->绑定事件
* 对象.on事件名字=null;
* 2.解绑事件
* 对象.addEventListener("没有on的事件类型",命名函数,false);---绑定事件
* 对象.removeEventListener("没有on的事件类型",函数名字,false);
* 3.解绑事件
* 对象.attachEvent("on事件类型",命名函数);---绑定事件
* 对象.detachEvent("on事件类型",函数名字);
- 事件冒泡:当元素嵌套,有层次,内层元素和外层元素注册了相同事件时,运行内层事件,外层事件也会运行,
- 阻止事件冒泡:必须在需要阻止的那一层函数加入
①Window.event.cancelBubble=true;*IE 8和谷歌支持 但是火狐不支持;
②而function(e){e.shopPropagation()} ; *谷歌火狐支持 IE8 不支持;
*e在谷歌和火狐中是对象,window.event在IE8 和谷歌中是对象
- 事件:①事件的捕获阶段; true 从外到里;
②事件的目标阶段; 点击或事件的目标;
③事件的冒泡阶段; false 从里到外;
通过e.event.Phase(*function(e){ e.event.Phase)可以获取数字1.2.3即为事件阶段 ;
- 为同一个元素绑定多个不同的事件使用同一个处理函数用switch-case的方式解决;
- 数组必记方法:1.push 追加(); 2. pop();删除最后一个元素 3.shift();删除第一个元素返回删除的元素 4.unshift();在数组的第一个位置添加元素;(轮播图)
【.every(function(ele,index)) 检测元素是否符合函数
.filter(function(ele))返回符合条件的元素;
Ele.from复制数组;
arr1.concat(arr2,arr3)】添加元素
- 三种弹窗:prompt.Confirm.alert;
- <Form action =”地址” method=”get/post”>表单input 表单元素如果要提交必须要有name
- 设置css模块隐藏的时候使用display:none 要使他显示的时候必须在style中的class具体到哪个父类子类、例如
要显示的span元素在class为‘dv’的div内,只要有.showit就显示
设置 .dv display:none 设置.dv .showit {display: block;}
- 子元素的margin-top/left/.. 设置(n%)百分比的时候,实际上的margin/padding就是父元素的宽度* n%;记得都是父元素的宽度,没有高度
- 块级元素的padding和margin取百分比值的时候,都是相对于父元素的宽度来计算的。
BOM--------------------------------------------------------------------------------------------------------------------
1.location几个需要记的属性及方法:
①主机名和端口:号window.location.host ⑧*跳转地址:location.href=”www.4399.com”
②主机名:window.location.hostname (可以返回)=location.assign(“www.43...”)
③#后面的内容:window.location.hash (不能返回)=location.replace(“www.43..”)
④端口window.location.port
⑤协议 :window.location.protocol
⑥相对路径:window.location.pathname
⑦附带参数:window.location.search
2.判断平台的系统:使用window.navigation.platform (移动端pc端;)
3.看自己的系统和浏 览器:window.Navigation.userAgent;
4.BOM中的俩种定时器:①定时器:var timeId=window.setInterval(function(),time) 清除定时器:clearInterval(timeId)
②一次性定时器: var timeId=window.setTimeout(function(),time)
清除定时器:clearTimeout(timeId)
5.透明度:element.style.opacity=(0-1);
6.如果样式的代码是在style中设置的那么外部是无法获取的;如果是在style属性中设置的就可以获取;如果想获取 style中的left可以使用element.offsetLeft(以此类推!)得到的是数字类型;
7.element.children 可以获得子元素节点; element.childNodes获得子元素;
8获得对象属性的三种方法:
①offsetLeft 可以获得style中的Left 但是当没有脱离文档流时不能获取left值
②window.getComputeStyle(element).left 谷歌火狐支持IE8不支持;
③element.currentStyle.left IE8支持,火狐谷歌不支持;
9 . ① function (e)e.clientX 与 function (e)e.pageX的区别在与一个是可视化距离一个是距离界面边框的大小,图片跟着鼠标飞时是用pageX;
② function (e)e.clientX 火狐谷歌支持,
而在IE8中应该使用function ()window.event.clientX
兼容代码 e=window.event||e
③pageX和pageY在IE8中不兼容
Window.eventcancelBubble()
10原型可以解决遍历时调用导致重复开辟多个内存空间的问题,(构造函数名字.prototype.构造方法名字)原型的作用:共享数据,节省内存空;
11单的原型写法:缺陷:-->原型直接指向{ },没有构造器,要自己加 constructor=对象名
eg:简单的写法:Student.prototype ={
constructor:Student,
height: "188",
weight: "55kg",
}
一般的写法:
Student.prototype.height="188";
Student.prototype.weight="55kg";
12.自调用函数(一次性函数)(function(形参){ })(实参) 可以用来把局部变量替换成全局变量; function(win){ Win.number=10;})(window)
Console.log(number) ====> 10
13.面向对象的编程思想:根据需求,抽象出相关的对象,总结出对象的特征和行为,把特征变成属性,行为变成方法,然后定义构造函数,实例化对象,通过对象调用属性和方法,完成相应的需求;
- Bind可以改变函数里this的值;function(){}.bind(that) this==that;
- new 构造函数 == 实例对象,构造函数的prototype就是原型对象。原型对象的构造器就是构造函数。实例对象的__proto__(原型)就是原型对象,实例对象可以使用原型对象的方法。原型链就是一种实例对象和原型对象的联系,关系是通过原型(__proto__)联系。per实例对象的__proto__------->Person.prototype的__proto__---->Object.prototype的__proto__是null
- 原型的指向可以改变,函数2的原型对象等于函数1的实例化对象。因为 Func.prototype ={}对象。f1的实例对象也是对象。所以当f2.prototype = new f1()的时候f2继承f1的属性和函数.还存在一个问题是,如果一开始f1设置了原型对象,一旦改变了指向后,前面设置的原型对象内容都不存在,存在的只有新的原型对象(f2的实例对象)!
Function f1(){}
Function f2(){}
f2.prototype = new f1()的时候f2继承f1的属性和函数
- 原型指向改变后再添加方法就可以使用,实例对象访问这个属性,应该先从实例对象中找,找到了就直接用,找不到就去指向的原型对象中找,找到了就使用。
- Js中的继承是通过原型来实现的;(改变原型的指向相同的行为就用原型的方法写,)
Dog(子对象).prototype=new Animal(name,color)(实例化父对象)
- 原型继承会导致所有父级的值相同。即:stu1 小明 男 120分 stu2 小明 男 130分
这也就是继承的缺陷。
19.要解决继承的缺陷就需要借用父级的构造函数;(在子集构造函数中加入 父级构造函数名字.call(this,属性,属性,属性,属性));但是缺陷在于父级的方法无法继承day3中的11
- 组合继承:就是原型继承+借用构造函数 在原型继承中不用输入属性值
20.①普通拷贝 var obj1={} var obj2=obj1;只拷贝了地址,而内存却只有一盒
②拷贝继承var obj={}
for(key in Person.prototype){obj2[key]=Person.prototype[key]}
- 函数声明if-else在IE8中会出现问题
- *函数中的this
①普通函数中的this------>window(直接调用)
Function f1(){ }
F1();
②定时器里的this------>window
③对象.方法中的this------>当前的实例对象;
Function Person(){ this.play=function(e){ };}
Var pre=new Person(); pre.play(e);
④原型对象方法中的this------>实例对象;(对象点)
⑤构造函数中的this------>实例对象 (函数用new的方法调用)
Funtion F1(){ this.name} var f=new F1(构造函数首字母大写,普通小写);
- 对象中有__proto__原型是对象 函数中有一定有prototype 和__proto__ 是对象;
- 方法.call 和方法.apply 的区别在与参数call是一个个传,apply是传一个数组,相同点在于可以改变this的指向,如果第一个对象参数是null那么this指向window,如果是一个对象那么就指向这个对象;
- Bind的函数用法和call类似 但是call和apply是调用函数,而bind是复制一份函数
- addEventListener(“click”,function(){},false)事件监听对象;
- 把js中的var 换成const 就可以定义为常量,不可以被修改;
27.css中的text-indent是首行缩进!
===================================正则表达式==================================
元字符:
1 . 表示的是:除了/n以外的所有字符
2 []
①范围:[1-7][a-z][A-Z][0-9a-zA-Z]分别表示 1-7数字 a-z的小写字母,a-z的大写字母,所有数字字母。(不存在[100-200]只能一个一个数字来)
②把正则表达式中元字符的意义去掉 [.]就是一个.没有意义了
3 | 或者 [1-2]|[3-4] 1-2或者3-4;
4 () 分组和提升优先级 分组都是从最左边来算((())()) 第一个左括号就是第一
元字符下的限定符:
1 * 表示的是:前面表达式出现了0次到多次,例如“dd232132135”和[a-z][0-9]*匹配,(多个数字)
2 + 表示的是:前面表达式出现了1次到多次
3 ? 表示的是: 前面的表达式出现0-1次
4 {}:可以更加明确的表示前面的表达式出现的次数{5,10} 最少5次最多10次
{0,}=== * {1,}=== + {0,1}=== ? {4} 4次
5 ^表示的是:以什么开始或者取非
^(a-z):在括号外面所以是以字母开头
(^a-z):在里面说明是取非 ,除了字母;
6 $表示的是以什么结束 [a-z][0-9]$ 以数字结束
如果正则表达式以^开头$结尾说明是严格模式,字符串必须以这样的形式出现,如果没有,那么只需要在字符串中出现就可以了
7 \d 数字中的任意一个
\D 非数字的任意一个
8 \s 空白符
\S 非空白符
9 \w 非特殊符号
\W特殊符号
10 \在非特殊符号前加一个\ 说明下一个字符是特殊的。 s是字母\s是空白符
创建正则表达式
Var reg = /\d{1,5}/
Reg.test(“我的幸运数字是:6”)
============================jQuery============================================
- js和jq对象的区别在于他们都是由各自的方法获得的,js对象无法使用js函数;jq对象无法使用js函数,除非他们互相转换
- JS---->JQ :var name=.... $(name);
- JQ---->JS :$(name) $(name)[0];
- 操作JQ不会覆盖,JS会覆盖;Js对象是一个一个对象(需要遍历),Jq对象是一组对象;
- $有3中用法 :
1>第一种是入口函数
2>第二种是JS转换成Jq
3>第三种是获取对象:$(“div”) $(“#div”) $(“.className”)
- 过滤选择器:前面都有冒号,:even 下标为偶数 :odd 下标为奇数 :eq(index)下标等于index :gt(index)下标大于index :lt(index) 下标小于index ;
- Jq中是链式编程,因为使用方法后都会返回jq对象;
- Jq中的调错错误只可能出现在对象上直接看对象
- -css操作 (改变样式 样式是在style中的)
1>设置样式:①css(“name”,“value”);②css({“name”:“value”,“name”:“value”;})
2>获取样式:①css(“name”) name是想要获取的样式(但是获取jq对象的时候只能得到一个元素的属性值)
8. -attr操作(改变属性 属性是在script中的)使用的方法和-css操作一样!
*自定义属性可以直接在attr操作中设置例如 attr(aa:bb)
*当用attr 设置 checked select disable 时会出现bug 这时需要使用.prop()来改变;
9. -class操作
1>添加一个类:addClass(“classname”)
2>移除一个类:removeClass(“classname”);
3>判断类是否存在: hasClass(“classname”) 返回 boolean。
4>切换类:toggleClass
10.jq动画的三种基本函数
1>显示 show(time,function) hide(time,function);
2>淡入 fadeIn(time,function) fadeOut(time,function)
3>滑入 slideUp(time,function) slideDown(time,function)
11.动画操作 .animate({attr:num},speed,swing(秋千) or linear(匀速),function);
.stop()可以停止当前正在进行的动画 用 .stop().animate()解决动画队列的问题
- 音频操作 用 audio(src=“” controls(播放器) autoplay(自动播放))
视频操作 用video(src=“” controls(播放器) autoplay(自动播放))
注意在音频前添加一个.load 再添加一个.play去掉一点要把音乐放完的bug
- 元素节点操作: var $li=$(“<a>123</a>”)
1>把元素添加到父元素最后面 : .append($li);
2>把元素添加到父元素最前面 : .prepend($li);
3>把子元素添加到父元素后面 : .appendTo();
4>把子元素添加到父元素前面 : .prependTo();
14.清空节点用 .empty();可以把元素节点和对应的事件清除;
15.删除节点:.remove()
15.深度复制 .clone(boolean) 为true的时候会复制事件为false不会复制事件;
16.操作value 值可以 .val(“ ”)来改变;
17.聚焦事件
1>聚焦用 .focus(function(){ })
2>离开焦点用 .blur(function({ }))
18. .html和.text的区别在于
1>.html更类似于innerHTML会打印标签
2> .text类似于innerText
19. 1>获取宽度高度: .width .height 不能获取padding附加的区域
2>可以获取padding 的区域: .innerWidth .innerHeight
3>可以获得border 的区域: .outerWidth .outerHeight
4>获取滚动出去的宽度高度:
$(window).scroll(function (){ $(window).scrollLeft})
5>获取窗口可视化区域的大小
$(window).resize(function(){$(window).width}))
- offset是获得相对于页面的位置
- 相对于有定位的父元素位置
- 委托事件:.delegate(select,type,function)给父元素注册然后给子元素执行;
优点:
- 动态创建出来的元素也有事件,在点击时元素没有事件由于冒泡会触发被委托事件从而为创建出的元素注册事件;
- 当多个子元素要注册相同事件的时候,用委托事件让父元素只为被点击对象进行操作,从而节省空间;
- 注册事件有2种方式 .on(type ,select,function)
1>注册简单事件 .on(“click”,function)
2>注册委托事件 .on(“click”,“p”,function)
先执行自己的委托事件然后再执行自己的简单事件;
22.移除事件 .off(“type”)输入事件就移除这个事件,不输入就全部移除
23.事件的触发 .trigger(“type”)== .type可写click等();
24.阻止浏览器默认跳转
1> e.preventDefault();
2>阻止事件冒泡:e.stopPropagation();
3> return false; 阻止跳转和阻止冒泡;
25.避免多次触发使得出现bug用节流阀的思路,设置一个开关 在函数中判断开关然后关闭开关 再在另一个函数打开开关;
26. .delay(time) 延迟的时间 可以用在2个动画之间
27.五角星评分案例:
1>前面所有兄弟prevAll();
2>后面所有兄弟.nextAll();
28.遍历的两种方法:
1>for
2>.each(function(index,element){
$(element).css( , )});
- $.noConflict 当使用多个库定义符号冲突时释放$的控制权 需要的时候再上网查
- 插件: 颜色渐变插件 懒加载
- 获得现有的年份
- var d=new Date;
- d.getYear()获得现在距离1900年的年数;
- d.setYear(需要设置的年数,不是距离1900的年数)
- d.toGMTstring()可以获得当前设置的时间;
- day2城市选择案例中的selected;
- day2 $(btn).click(function(){
*Var tex=$().val(获取$()中的值)
$(“<li></li>”(直接创建li对象)).text(tex)(设置文本内容)})
- day3 飞到顶部的小火箭:
由于只有Body 和html有scrollTop属性window没有所以
$(“body,html”).aninmate({scrollTop:0});
==============================PHP=====================================
- 查询端口占用 #
- 每次改变Apache后用http-t 来测试是否OK
- 更改网页根目录是 找到httpd.conf 修改Document Root (记得复制过去后要改斜杆 )
- 添加虚拟机出现forbidden 时找到文件vhost中的 DocumentRoot,在下面添加
<Directory "${SRVROOT}/cgi-bin">
AllowOverride None
Options None
Require all granted
</Directory> 即可
2>添加虚拟机也要注意修改虚拟机Document Root
- 默认文档是:当客户端访问一个文件时默认返回的文档 可以在配置文件中修改 directoryindex来修改
- 阻止别人访问本机的其他文件目录可以把配置文件中的Options Indexes FollowSymLinks 中的Indexes 去掉;
- 虚拟主机,就是把一个网站分成多个网站
先在配置文件中解除主文件里的注释505行 Include conf/extra/httpd-dav.conf conf\extra\v中修改,每个虚拟主机必须配置ServerName 就是修改DocumentRoot“默认文件”;ServerName必须是自己购买的域名
- 宽字符集就是普通的文字 ,他有一套专门的api 都是mb_xxxx;需要载入模块后才能使用
- # php -a 进入console
- Php.ini 中的display_errors在开发阶段设置为On 在生产阶段设置为Off;(警告)
- 用if(isset($arr[$foo]))可以判断是否有$foo这个键;用if($arr[$foo]) 也可以但是会警告不推荐
- Empty() 和isset()的区别在于Empty()=!isset()|| arr=false;用empty()来识别别人提交的数据是否可以获取,或者有没有数据; *(‘0’==false ‘’==false)
- In_array()和IndexOf的区别在于In_array()只是判断是否存在,不返回下标;
13.require()和include()都是载入文件的函数但是require一旦没有文件那么就不会执行,而include()和报警告并继续执行;(include一般用于载入部分html,require用于载入必要的代码文件)
- 用from action 提交给另一个PHP后用:
- var_dump($_GET):用于接收URL地址中的数据(一般是GET发出的)
- var_dump($_POST):用于接收请求体中的数据(一般是POST发出的 )
- var_dump($_REQUEST):$_GET+$_POST;
- GET和POST的使用在于到底是拿东西还是送东西(账号密码是送,筛选等的是拿)
15.在from的客户端中:(必须查询$_SERVER使用方法)
- 使用if[$_SERVER(‘REQUEST_METHOD’)===‘post/get’]可以判断是什么类型;
- 对action=“”使用<?Php echo $_SERVER[‘PHP_SELF’];?>”得到当前php的名字
- 将数据保存到文本中 file_put_contents (, ,FILE_APPEND)
- 表单处理的三个步骤:
- 接收并校验;
- 持久化(将数据保存到文件磁盘)
- 响应(服务端后台响应)
- 直接在地址栏输入地址以及用a标签的形式进入的是用GET的方式请求的,但是一旦点击注册就是用POST方式请求的 (见day'3 case1 :第一行PHP判断是否是POST 请求,如果是才执行接下来的PHP代码,为了让一开始的错误信息就直接显示出来;)
- 如果表单中有文件上传必须把method设置为“post”,把enctype设置为multipart/form-data,接收文件要使用全局变量$_FILES;
- 上传文件大小限制可以找php.ini 查找upload_max;修请求提交总文件的大小查找post_max_size;
- 字面量是代码中用来表述数据的一种手段,Json是一种基于字面量的语法;
- Json 中属性必须用双引号包裹;
- Json 中字符串必须用双引号包裹;
- Json 中不允许使用注释;
- Json 的解析用Json_decode($contain,//假如加入true 那么才是关联数组)
Eg: [
{ id:xxx ,name:xxx,email:xxx },
{ id:xxx ,name:xxx,email:xxx },
{ id:xxx ,name:xxx,email:xxx },
{ id:xxx ,name:xxx,email:xxx },
{ id:xxx ,name:xxx,email:xxx },
{ id:xxx ,name:xxx,email:xxx },
{ id:xxx ,name:xxx,email:xxx }
]
- 注册列表的步骤;(传到文件夹中)
- 清单;
1.1获取 json文件 file_get_contents();
1.2解析 json文件 $arr= json_decode();
1.3显示 json文件 foreach($arr as item){ $item[‘name’]}
- 服务端;
2.1表单的校验:
1.判断是不是post请求 $_SERVER[‘REQUEST_METHOD’]==='POST'调用函数;
2.使用函数让文件格式清楚使用if (empty($_POST[‘name’])){return;}来解决
2-1文件域是否存在if (empty($_POST[‘source])){return;}
2-2是否上传文件成功$source[‘error’]!==UPLOAD_ERR_OK;
2-3限制文件大小$source[‘size’]
2-4限制文件种类$source[‘type’]
$allowed_types = array('audio/mp3', 'audio/wma');
if (!in_array($source['type'], $allowed_types))
<input accept=“可以是MIMEtype 还可以 是 .txt ,.url等 格式”>可以限制文件种类
<input multiple>可以选择多个文件
一个文本域上传多个文件的时候必须把name变成一个数组;
2-3更改上传目录 move_uploaded_file(临时路径($source['tmp_name']),$target)
- 注册表单:(传到数据库中)
1>复制注册表单静态页面必须注意form:
①form action="<?php echo $_SERVER['PHP_SELF']; ?>"method="post" enctype="multipart/form-data" autocomplete=“off”>
②有id的input要加name
③点击保存后查看network是否正常运行;
保存数据的路径一定用绝对路径
相对路径中的./代表当前目录 ../代表上级目录 传路径时要用substr()剪切
路径要用 . 拼接;
2>“”可以解析$id但是‘’不可以
写mysqli_query 的时候;$qurey = mysqli_query($coun,"insert into users values (null,'$avatars','$name',$gender,'$birthday');");
3>在选择性别的时候是select标签包含option标签,若要默认选择那么必须使用selected属性 为了判断是否和原来编辑前的值一样,必须用三目运算符。例如
<select>
<option value = -1 <?Php echo $users[‘gender’]==1? ‘ selected’:’’?> 男 </option>
</select> 注意的是selected 前面的空格必须存在才符合规则;
要删除或者是编辑指定的表单要在action后面加? 和判断的数值;
24.编辑表单:
时候需要更新原来是数据库,语句是update users set sex ='为' where id=3,要注意到id到底取什么值,这时就要在edit.php中的href中传Id值(在校验的过程中出错的时候会返回原来的页面,如果没有传id值那么前面那些需要get中id值的地方全部都会报错,所以必须传入id值)由于有id值所以前面那些需要id值的函数可以执行而不报错,进行校验。
25.数据库的整体思路:
1>连接数据库 mysqli_connect("localhost","root","123","demo");
判断:if ($coun) {echo("连接成功");}else{exit("连接失败");}
字符:mysqli_set_charset($coun,'utf8');
2>查询数据库 mysqli_query($coun,"select * from users;");
判断:if (!$qurey) {exit("查询失败");}
- 遍历数据库 while ($row = mysqli_fetch_assoc($qurey)){var_dump($row);}
单条:$row = mysqli_fetch_assoc($qurey)
4>查询的话要释放结果集 mysqli_result($qurey);
5>炸桥 mysql_close($qurey);
25.表单案例中的思路!很重要!
总思路 :连接并检验,持久化(保存数据),响应(返回);
清单页面:index.php
1>连接数据库
2>查询数据库
3>遍历数据库(在html中遍历混合编码)
注册页面:
- 接收并校验文件
- 连接数据库
- 查询数据库
- 持久化(保存到数据库)
- 响应(跳转)
删除页面:
- 获取get后的id值
- 连接数据库
查询数据库(删除指定行)mysqli_query($con,delete from users where id=1;
- 响应 header(Location:XXX.php)
编辑页面:
1>获取get后的id值
2>连接数据库
3>获取数据库的值放在一个变量中;
4>修改html文件中的初始化value值;
5>在点击保存的时候在?后面加id值(因为要删除指定行,如果不传那么就无法在$_SERVER[‘REQUEST_METHOD’]===’POST’)中获得当前的id值;)
25.pathinfo($_FILES[‘avatar’][‘name’],PATHINFO_EXTENSION);可以获得文件格式;
- 进行文件移动操作的时候(move_upload_file()),若想接收中文文件名字必须用iconv来转换中文编码为GBK编码 (iconv(‘utf-8’,’GBK’,$XXXX[‘name’]));
- 忽略报错:在PHP头error_reporting(E_ALL&~E_NOTICE)
- 解决无状态的方法就是使用cookie
①在php中使用setcookie来修改cookie
1.使用的方法(‘键’,’值’,’过期时间’,’path’,‘domian’);
2.使用$_COOKIE这个全局变量来获取cookie
3.单单只有一个键的时候是用来删除这个cookie的;
4.使用想同的键的时候会被覆盖;
5.同时由于cookie是在报文中被保存的所以可以修改heard里的Set-Cookie从而修改 或添加cookie;
②同时在js中也可以修改和获取cookie
1.获取:COOKIE.cookie(‘key’);
2.修改:COOKIE.cookie=‘key=value’
③如果有人伪造cookie来获取数据
1.加密(比较高级)
2.记总账:
2.1在使用之前必须要用session_start();
2.2使用$_SESSION[‘key’]='value';改变的是在session中的数据,用cookie可 以访问到但是由于这个cookie是一个随机编码,所以不能轻易获得相应session的 cookie编码;
2.3使用$_SESSION来获取session里的数值;
==============================AJAX=====================================
Ajax就是浏览器给我们提供的api,作用是操作网络,可以操作响应请求,对网络进行网络编程
- AJAX 核心的 三个步骤
①安装浏览器 :var htr = new XMLHttpRequest;
②打开浏览器并输入地址 htr.open(‘GET’,‘http://study08.io/time.php’);
③敲回车访问: htr.sent();
- 涉及到AJAX的操作页面不能使用文件协议访问(file://XXXXX)
- 同一个网站下面就可以写相对或者绝对路径;
- 常用api:
- 获取当前的状态 xhr.readyState
- 获取状态的改变 xhr.onreadystatechange = function (){}
- 使用switch(xhr.readyState){case 2:;...} 来获取这些状态下应该做什么;
- 获取响应体 xhr.response 获取的结果会随着responseType变化而变化
- 获取响应体 xhr.responseText 获取字符串文本
- 获取全部的响应头 xhr.getAllResponseHeaders();
- 获取指定的响应头 xhr.getResponseHeader(‘date’);
- 获取响应的状态 xhr.status (200)
- 获取状态内容 xhr.statusText(OK)
- 不同状态代表的意义:
// 0.新建请求代理
// 1.open了一个对象
// 2.加载了响应头和响应行建立了连接
// 3.加载了响应体但是没有完全下载完毕
// 4.完全下载完毕
- xhr.onload = function(){} 可以直接获取状态4时的情况(有兼容性问题)
- 设置open对象的响应头使用xhr.setRequestHeader
- xhr.setRequestHeader(‘Foo’,‘bar’);
- xhr.setRequestHeader(‘Content-Type’,‘application/x-www-form-urlencoded(根据不同的情况而改变)’)
- AJAX的基本操作
var xhr = new XMLHttpRequest();
xhr.open("POST","ajax.php");
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send('valq=1&ss=2');
//同时还可以使用xhr.send(`valq=${ }&ss=${ }`);
//设置请求头
xhr.addEventListener('readystatechange',function(){
if(xhr.readyState!==4)return;
1console.log(xhr.readyState);
console.log(xhr.response);
console.log(xhr.responseText);
//responseText获取字符串文本
console.log(xhr.status);
console.log(xhr.statusText);
console.log(xhr.getResponseHeader('Content-type'));
console.log(xhr.getAllResponseHeaders());}
- AJAX函数的封装需要封装成回调函数:ajax(method,url,params,done)
Done为函数
- 回调函数,当函数里面嵌套着函数,外面函数是无法获取里面函数的返回值的所以需要使用回调函数来解决;
function getTime(done){
(function getThis(){
done(Date.now());
})();
}
getTime(function(time){
console.log(time)
})
其中里面的函数需要执行才可以,在这里我们使用自调用。同时done=function(time);
time的值为date.now()
- AJAX解决跨域的问题可以使用JSONP,它是一种借助于动态创建script标签进行跨域请求的技巧
JSONP就是当script里的src属性引入的文件为PHP文件,但是返回的结果是JS;
从而将服务器想要给客户端发过去的数据发给客户端
==============================Vue======================================
- v-for : v-for="item in list" 是循环list里的内容然后放入item中。
- v-bind特性被称为指令。指令带有前缀v-,以表示它们是 Vue 提供的特殊特性
- input : 里的v-model="inputValue"的时候就是双向绑定了。
①this.inputValue :可以获得input中的值
- v-on:click :事件使用v-on:click = 'func';func是要写在methods里的
- MVC、MVP模式、MVVM设计模式的区别
①MVC:前端常用的设计模式
Model: 模型(用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法)
View: 视图(渲染页面)
Controller: 控制器(M和V之间的连接器,用于控制应用程序的流程,及页面的业务逻辑)
MVC流程:M-->V-->C--M...成一个循环的状态,MV可以直接联系,同时导致视图与控制器间过于紧密连接。
②MVP模式:MVC的改良模式将 Controller 改名为 Presenter,同时改变了通信方向。
此时M数据层和V视图层不能直接联系都得通过P来进行联通,修改视图可以不影响模型,主要的程序逻辑都在P层,缺点在于视图层和模型层的交互太过频繁。
③MVVM模式:在vue中M层是模型层,V层是视图层,而Vue就是VM层,我们主要修改的方面在于V层和M层!MVVM模式和MVC模式类似,主要目的是分离视图(View)和模型(Model)
- 前端的组件化:组件是页面的一个区域,组件也是一个实例,一个项目是由很多个组件组成的,也可以说是由很多个实例组成的
- 实例对象后面以$开头的是实例属性或实例方法例如 app.$el,app.$data
- Vue的生命周期钩子:
大体分为四个部分分别为:
- 创建实例
beforeCreate:function(){}
Created:function(){}
- 渲染页面
beforeMount:function(){}
Mounted:function(){}
- 销毁实例
beforeDestroy:function(){}
Destroyed:function(){}
- 更新数据
beforeUpdate:function(){}
Updated:function:function(){}
- Vue的基础模板语法
以下三种都需要获取实例中data的数据,而且都可以使用js的语法书写内容。
- 插值表达式:在标签中{{ }}以这样的形式传入内容。
- 标签中的 v-text 属性 类似与js中的innerText 方法
- 标签中的v-html 属性 类似于js中的innerHTML方法
9.重要 绑定样式的两种方式class和style。都有俩种写法,数组和对象!
(1):class="{样式名:决定是否出现样式名 }"
(2).:class="['样式名','样式名']"!通过methods中的函数调整。
(3):style="样式名"需要在data中用样式名输入Css
(4):style="[样式名,{fontSize:'20px'}],前面和第一种一样,后面对象可以直接输入CSS样式注意单引号
10.使用v-if,v-elseif ,v-else 条件渲染必须让他们连续出现,中间不可以存在其他DOM节点
else后面不存在变量直接书写!
使用v-if时由于vue会尽量不更换DOM节点,如果有相同的大部分不会替换!如果需要在替换的时候清空那么需要在input后面添加key值,key值是任意的!
11.v-if和v-show的区别在于,当v-if为false的时候就会被销毁,为true重新创建,但是v-show就会保留,只是标签属性的display变成none从而隐藏
12.在列表渲染时:
(1)为了提升性能需要给循环的每一项提供:key值
(2)当:key值都是不相同时性能最优,而不是使用index作为key
(3)修改数据和同时改变渲染的方法:
①通过数组的几个变异方法来改变数据渲染:pop,push,shift,unshift,sort,resver,
②改变引用地址,即改变data中list的数据!(输入全部数据)
③使用vue.set(vm.list,"key","value")来改变list中那个key 的 value!
注意:当我们修改数据的时候不能通过下标的形式修改数据的渲染,但是可以修改数据 (arr[4]="5");
13当存在多级的时候,例如table>tbody>child 组件child最后会与table同级。
解决的方法:table>tbody> <tr is=”child”>。
<template>模板占位符!可以让内容需要整体循环的外文本包括消失。如果使用<div>那么外围div也会循环
- 当需要子组件中数据为独立的可以通过组件中的data返回一个对象来解决,如果使用template那么就会使用同一个数据
- 用ref引用修改DOM节点或者组件
- 如果使用 DOM节点的话修改的就是 DOM节点,获取的方式需要用this.$refs.ref(注:这里的ref就是body标签中ref=“”的值)获取。
- 如果是组件的话就是获取组件!
- 父组件通过属性(:count="0")的方式向子组件传值
- 可以通过接收父组件属性的方式接收数据,但是如果没有:count没有 ':'传递过来的值是字符串
- 因为Vue中存在单项数据流的概念,所以直接改变的话会报错,父组件可以随机改变子组件值,但是子组件无法修改父组件的值,只能使用。
- 解决的方法是:在子组件中定义一个函数=父组件需要传输的值,此时点击修改的是子组件的值(例如:return{number:this.count})
- 子组件通过事件触发的方式向父组件传值!@click=“handleClick”
- 非父子组件之间的传值:
1 首先先设置一个全局组件
2 其次令Vue.prototype.bus = new Vue();
3 创建实例对象
4 在全局组件中设置模板template 同时设置时间click,由于是在全局组件中使用的方法所以methods写在全局组件中
5 然后该方法使用this.bus.$emit(),由于最后还是全局组件监听所以在这可以使用生命周期钩子 mounted,自动监听
6 监听时注意作用域!
19.Vue的插槽就是在组件中插入标签,然后在template中用slot进行引用,如果要指定标签在模板中的位置,那么就需要使用具名插槽。就是给slot加name值(在body标签中是<div solt=”one”> ,在模板的template中是使用 ` <solt name=”one”>Default Value</solt>`)
20.Vue当中的作用域插槽:
(1).创建全局组件及其模板template
(2)当需要用到循环或者是需要用到各种的模板,则需要用到Vue中的作用域插槽
(3).在body中写出组件,同时其第一子元素必须是<template> 同时必带属性slot-scope="属性(props)"即<template slot-scope="props)">
(4).在template中输入值,<li>属性.值</li>,在使用的时侯必须保证组件中template模板存在:item=item属性,此时获取的item值将传输到props.item中
21.实像toggle装换;
第一种:
1.先写2个组件,再设置一个按钮,点击时切换type值
2.当v-if值为type时候就显示!
第二种:使用动态组件。
1.先写2个组件,再设置一个按钮,点击时切换type值
2.设置component标签 此时需要一个:is属性,:is的值是什么就返回什么组件!
================================Vue的环境==================================
1.路由器(router):根据网址的不同返回不同的内容给用户
2.main.js是主页面,里面可以展示路由,组件,等等可以按照名字在src中寻找到,在此同时在使用前要用import引入。
3.引入fastclick依赖的 原因:
1、手动点击与真正触发click事件会存在300ms的延迟(ios上面最明显)
2、点击穿透问题(点击行为会穿透元素触发非父子关系元素的事件)
在cmd中的traval 书写命令:npm install fastclick --save来安装然后使用import FastClick from 'fastclick' FastClick.attach(document.body)
4.在引入其他css文件的时候可以把它集中放在文件及中,然后使用main.js中的import来引用css
5.项目的开始引入的依赖
1.npm install stylus --save
2.npm install stylus-loader --save
6.使用npm audit fix修复漏洞之后,再运行npm run dev 就报错:
解决:最后找出是版本更新原因。删除node_modules后,在npm install之后,运行 npm i -D webpack-dev-server@2.9.7更新版本
- 每个公司的reset.css是不同的,需要适当进行修改才能达到目的
- 使用图片的时候可以去iconfont查找
- 组件的优化:
- 在style设置varibles.styl全局css使用时需要引入,需要改变主题色可以直接在文件里改
- @符号代表src目录这样可以优化代码,减少长度。在css中要引入其他css要使用~@
- 如果需要多次使用同一个路径可以把其代换成一个符号就是@代表src一样:
方法:点开build中的webpack.base.conf.js找到resolve下的alias来改
- git的指令。
- 最基础的 文件上传
①git init //在当前项目目录中生成本地git管理,并建立一个隐藏.git目录
②git add . //添加当前目录中的所有文件到索引
③git commit -m "first commit" //提交到本地源码库,并附加提交注释
④git push
-
- 如果创建了分支使用
- git pull 把线上的分支下载到本地
- git checkout index(分支) //切换到该分支
- git status //查看在那个分支
- 编码!
- git add . => git commit -m “index” =>git push
- git checkout master //切换的主分支
- git merge (分支)origin/index-swiper //合并到master注:先要处于master
- 如果创建了分支使用
- 使用轮播图的时候可以下载插件 使用命令 npm-awesome-swiper@2.6.7 --save
官网https://github.com/surmon-china/vue-awesome-swiper
- 一般设置大小都先在reset.css中设置body大小接下来都使用rem
- 如果要让多的文字显示 ... 那么需要封装一个函数 mixins.styl到styles中,当发现没有用的时候就在父元素中flex:1 下面加一个min-width:0
内容是:
ellipsis()
overflow:hidden
white-space:now-rap
text-overflow:ellipsis
- 注意flex布局!很重要
-
- 在父元素写display:flex说明子元素开始弹性布局
- flex-direction:column :主轴的方向横row纵column,向主轴方向收缩
- justify-content:center: 主轴对齐方式,center居中,space-between两边
- align-items:center :交叉轴对齐,盒子下边界对齐用flex-end向交叉轴反向收缩
- flex-warp:warp(换行)/nowrap(默认)/warp-reserve :的时候就可以自动换行,同时由于有边框所有需要使用box-sizing:border-box,
- 加载图片的时候注意在外面包裹一层占位的div
- Height:0 padding-bottom: 22%
- 进行数据交互的时候可以使用axios它功能完善十分强大
- 安装的时候输入命令npm install axios --save
18.进行ajax请求的时候尽量不要一个一个组件请求可以在总界面进行请求!这样性能得以优化
19只有把一些静态的页面放在static页面中才可以在外部访问到
20.如果不想某些文件提交到线上就需要打开gitignore 把需要屏蔽的路径放上去
21.vue中存在一个转发的机制可以把对api下面的所有请求,转发到本地static中mock(自己建立的)文件下,即:点开config文件夹里的index.js文件,找到proxyTable更改成
proxyTable:{
'/api': {
target: 'http://localhost:8080',
pathRewrite: {
'^/api': '/static/mock'}
}}
- 首次进行ajax请求的过程
- 安装axios npm install axios --save
- 在主页Home引入axios import axios form ‘axios’
- 在static下创建文件,因为外部只能访问到这个文件
- 屏蔽上传到码云,找到gitignore 输入路径就可以
- 在Home中进行ajax请求:
- 生命周期函数mounted : function() { this.getHomeInfo()}
- 在methods中添加函数getHomeInfo(){
axios.get(‘路径eg:/static/mock/index.json/’)//请求数据
.then(this.getHomeInfoSucc())//获取数据成功
}
-
-
- 在methods中添加方法 this.getHomeInfoSucc(res){ console.log(res)}
- 在(5)②中的路径一般需要更改,换成/api/index.json此时需要使用vue中的一个转发的机制更改 config文件夹里的index.js文件,找到proxyTable更改。
-
- 首次进行ajax交互:
- 父组件设立要传输的data值为空
- 在组件标签属性设置值
- 在子组件用props接收记住 Key:String/Array...,不用放在data中,然后用this.值放置在组件上
- (5)③中可以获得数据,由于之前设值为空,所以在这里先判断
if (res.ret && res.data) {
const data = res.data
this.city = data.city
.....
}
24.页面使用组件的时候自己的template中不要加其他标签,加组件标签就好
25.当存在float浮动的时候会场上BFC区域,需要在父元素使用overflow=hidden 解决
26.在准备访问class下 的class的时候,需要在写出2给class,一个作为父class,内容就是子class
27.当页面list没有设置display:hidden 的时候,多出来的部分会撑出去。设置了之后页面不能移动,此时需要引入better-scroll
28.使用router-link标签的to属性可以跳转页面
29.在需要网络的一些图片的时候需要使用iconfont组件
30.如果要使用ajax必须使用网络环境,要么搭建本地服务器 要么就用subineServer插件,点击工具-subineServer-serverstart之后,点击文件右键viewinserver打开就可以了、
基本项目中使用的插件
1.懒加载
npm install --save lozad
var lozad = require('lozad')
标签中:<img class="lozad" data-src="image.png" />
Js中:const observer = lozad(); // lazy loads elements with default selector as '.lozad'observer.observe();
2.vuex
npm install vuex --save
由于大型项目需要传输很多值,所以需要在src中添加文件store文件同时添加index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new vuex.Store({
state: {//state存放全局公用数据
city: '北京' } })
Main.js中引入import store from './store'在new Vue 中传入store
==============================移动端================================
meta name="viewport" content="width=device-width,initial-scale=1.0" 解释
- Viewport概念
通俗来讲就是移动设备上显示网页的那一个部分,一般来说移动端的浏览器会设定自己的viewport一般是980px或1024px,实际的网站可能会比这个大,就会在显示出滚动条
2.css中的1px和移动设备中1px的区别
在PC端中css的1px往往是为实际的物理像素1px。但是在移动端中的设备五花八门,例如早先的ipone3分辨率为320*480,后来新出的ipone屏幕升级为640*960但是尺寸没有发生改变。这时css中的1px就不为1个物理像素了。我们可以通过window.devicePixelRatio来获取css中1px和实际像素的比例,像刚刚ipone3 1px为一个物理像素,更新后为1px等于2给像素。(window.devicePixelRatio = 2)
可以这么理解,由于你设备分辨率增大了,但屏幕尺寸并没有变大多少,必须让css中的1px代表更多的物理像素,才能让1px的东西在屏幕上的大小与那些低分辨率的设备差不多,不然就会因为太小而看不清。
3. ppk大神关于viewPort理论中的三种表现方式
layout viewport : 浏览器默认的viewport,会出现滚动条
visual viewport:浏览器可视化区域的大小(通过window.innerWidth获取)
ideal viewport:不同设备由不用的ideal viewport
例如ipone的viewport值为320,意思是css中的320px就是苹果宽度的100%,不管是什么尺寸的苹果手机ideal viewport 都是相同的!安卓设备就比较五花八门了320 360 384等等。(http://viewportsizes.com可查询)
添加<meta name="viewport" content="width=device-width, initial-scale=1">就可以把viewport设置为
4.在iphone和ipad上,无论你给viewport设的宽的是多少,如果没有指定默认的缩放值,则iphone和ipad会自动计算这个缩放值,以达到当前页面不会出现横向滚动条(或者说viewport的宽度就是屏幕的宽度)的目的
5.媒体查询常见尺寸
@media screen and (min-width:1200px){ ... }/* 大型设备(大台式电脑,1200px 起) */
@media screen and (min-width:992px){ ... }/* 中型设备(台式电脑,992px 起) */
@media screen and (min-width:768px) { ... } /* 小型设备(平板电脑,768px 起) */
@media screen and (min-width:480px){ ... }/* 超小设备(手机,小于 768px) */
==============================mysql====================================
1.利用mysql_connect(‘127.0.0.1’,’root’,’password’,’demo’);
2.navicat中的增删改查
-- 查询
-- select id,age,sex from users
-- 如果产生通配符就会产生全表扫描
-- select * from users
-- 语句可以选择一个列或者一个具体的值
-- select 1 from users
-- 增加
-- insert into users values(null,'小红',18,'女')
-- insert into users(name,age,sex) values('小白',18,'男')
-- 删除
-- delete from users where id<=2
-- delete from users where id<=2 and sex='女'
-- delete from users where id<=2,sex='女'
-- delete from users where id in(1,2,3,4,)
-- 修改
-- update users set sex ='为' where id=3
-- update users set sex=‘1’,age=‘2’ where id in(1,2,3,4);
bootstrap中 :
- col-md-5 mb-3 代表 form的长 宽
- Container表示居中
- mx-5 my-5 代表margin right和margin top;
- px-5 py-5 代表padding right和 padding top;
Form
1.form-control 代表from的标准格式;
2.form-row 代表from和label同一行 form-ground 代表换行;
Btn
- btn btn-danger 红色;
Btn btn-success 绿色