这是一个很常见的布局,当然也可以实现右侧自适应,左侧自适应。比如常见的网页中,左侧导航栏是固定的,右侧的内容区要自适应浏览器的大小。
现在我们来看下HTML布局:
<div id="outer">
<div id="sidebar" style="height:240px;">固定宽度区div>
<div id="content" style="height:340px;">自适应区div>
div>
<div id="footer">后面的一个DIV,以确保前面的定位不会导致后面的变形div>
下面讲一下常见的方法:
1、将左侧div浮动,右侧div设置margin-left。
.sidebar{
width: 300px;
height: 300px;
background-color: pink;
float:left;
}
.content{
margin-left: 300px;
height: 100px;
background-color: blue;
}
.footer{
background-color: red;
}
.outer:after{
display: block;
content:'';
clear: both;
visibility: hidden;
}
.outer{
zoom:1;
}
效果图如下:
大家要注意html中必须使用div标签,不要妄图使用什么p标签来达到目的。因为div有个默认属性,即如果不设置宽度,那他会自动填满他的父标签的宽度。这里的content就是例子。
当然我们不能让他填满了,填满了他就不能和sidebar保持同一行了。我们给他设置一个margin。由于sidebar在左边,所以我们设置content的margin-left值,值比sidebar的宽度大一点点——以便区分他们的范围。例子中是300.
假设content的默认宽度是100%,那么他设置了margin后,他的宽度就变成了100%-300,此时content发现自己的宽度可以与sidebar挤在同一行了,于是他就上来了。
而宽度100%是相对于他的父标签来的,如果我们改变了他父标签的宽度,那content的宽度也就会变——比如我们把浏览器窗口缩小,那wrap的宽度就会变小,而content的宽度也就变小——但,他的实际宽度100%-300始终是不会变的。
这个方法看起来很完美,只要我们记得清除浮动(这里我用了最简单的方法),那footer也不会错位。而且无论content和sidebar谁更长,都不会对布局造成影响.
但实际上这个方法有个限制——html中sidebar必须在content之前!
如果siderbar当到了content后面,就会出现如下的效果:
但我需要sidebar在content之后!因为我的content里面才是网页的主要内容,我不想主要内容反而排在次要内容后面。
但如果sidebar在content之后,那上面的一切都会化为泡影。
可能有的人不理解,说你干嘛非要sidebar在后面呢?这个问题说来话长,反正问题就是——content必须在sidebar之前,但content宽度要自适应,怎么办?接着往下看。
2、固定区采用绝对定位,自适应区仍然设置margin。
CSS代码如下:
.sidebar{
width: 300px;
height: 300px;
background-color: pink;
position: absolute;
top:0;
left: 0;
}
.content{
height: 100px;
background-color: blue;
}
.footer{
background-color: red;
}
.outer{
position: relative;
}
效果图:
可以发现,此时下面的红色div受影响了。其实这与footer无关,而是因为outer对sidebar的无视造成的。看来这种定位方式只能满足sidebar自己,但对他的兄弟们却毫无益处。
3、标准浏览器的方法
当然,以不折腾人为标准的w3c标准早就为我们提供了制作这种自适应宽度的标准方法。那就简单了:把outer设为display:table并指定宽度100%,然后把content+sidebar设为display:table-cell;然后只给sidebar指定一个宽度,那么content的宽度就变成自适应了。
对应的CSS代码
.sidebar{
width: 300px;
height: 300px;
background-color: pink;
display:table-cell;
}
.content{
height: 100px;
background-color: blue;
display:table-cell;
}
.footer{
background-color: red;
}
.outer{
display: table;
width:100%;
}
不过这种做法,如果sidebar写在content前面,sidebar会固定在左侧,否则固定在右侧。
HTML:
<div class="outer">
<div class="sidebar">
sidebar固定区域
div>
<div class="content">
content自适应区域
div>
div>
<div class="footer">
后面的一个DIV,以确保前面的定位不会导致后面的变形
div>
代码很少,而且不会有额外标签。不过这是IE7都无效的方法。
———————再说一点————————
如果不考虑ie7及以下版本,则使用标准方法;如果不在意sidebar与content的顺序,则用第一种方法;如果不考虑对其他兄弟元素的影响,用第3种方法。
以上代码都没在IE6测试,有问题不负责解释。让IE6寿终正寝的办法就是——从此不再理他。
实际的页面开发中经常会遇到左边定宽,右边自适应的需求,特别是一些管理系统,比如左边显示信息或操作列表,右边显示详情,如下所示:、
针对这种布局,首先抽象出页面结构如下:
1
2
3
4
5 Document
6
7 * {
8 padding: 0;
9 margin: 0;
10 color: #fff;
11 font-size: 30px;
12 font-weight: bold;
13 text-align: center;
14 box-sizing: border-box;
15 }
16 aside {
17 width: 200px;
18 height: 200px;
19 padding-top: 75px;
20 background: #5A6A94;
21 }
22 section {
23 height: 200px;
24 padding-top: 75px;
25 background: #BE4F4F;
26 }
27
28
29
30
31
32
33 Right
34
35
浏览器中效果:
需要实现的效果如下:
那么针对这种常见的布局,方式是非常多的,下面给出几种比较简单和常见的方法。
方法一:左边设置左浮动,右边宽度设置100%
【分析】这样的方式简单得让我怀疑,但是效果上确实是实现了。
方法二: 父容器设置 display:flex;Right部分设置 flex:1
【分析】display:flex; 设置为弹性盒子,其子元素可以通过设置 flex 的数值来控制所占空间的比例。
方法三:设置浮动 + 在 css 中使用 calc() 函数
【分析】
1. 浮动。(注意:为了不影响其他元素,别忘了在父级上清除浮动)
2. calc() = calc(四则运算) 用于在 css 中动态计算长度值,需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px)
;
3. vw: viewport width。1vw = viewport 宽度的 1%, 100vw = viewport width,
同样的还有 vh: viewport height。1vw = viewport 高度的 1%, 100vh = viewport height。
浏览器支持情况: 主流浏览器、IE10+
vw 和 vh 会随着viewport 的变化而变化,因此十分适合于自适应场景来使用。
方法四:使用负margin
首先修改页面结构,为自适应部分添加容器 .container, 同时改变左右部分的位置,如下:
设置样式:
【分析】
1. 首先设置左边部分和右边部分左浮动,并为自适应部分(Right)设置宽度100%。此时的效果是这样的:
2. 设置左边部分左外边距为负100%,此时效果如下:
但是右边部分的宽度仍然为100%,部分内容被 Left 所覆盖。
3. 为 Right 部分添加左边距(即 Left 部分的宽度)
此时可以看到,Right 部分的内容居中显示了。
在各种浏览器中显示效果也有可能不相同,这样让清除浮动更难了,下面总结8种清除浮动的方法,测试已通过 ie chrome firefox opera,需要的朋友可以参考下
清除浮动是每一个 web前台设计师必须掌握的机能。css清除浮动大全,共8种方法。
浮动会使当前标签产生向上浮的效果,同时会影响到前后标签、父级标签的位置及 width height 属性。而且同样的代码,在各种浏览器中显示效果也有可能不相同,这样让清除浮动更难了。解决浮动引起的问题有多种方法,但有些方法在浏览器兼容性方面还有问题。
下面总结8种清除浮动的方法(测试已通过 ie chrome firefox opera,后面三种方法只做了解就可以了):
1,父级div定义 height
复制代码
代码如下:
div2
原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。
优点:简单、代码少、容易掌握
缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题
建议:不推荐使用,只建议高度固定的布局时使用
2,结尾处加空div标签 clear:both
复制代码
代码如下:
div2
原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度
优点:简单、代码少、浏览器支持好、不容易出现怪问题
缺点:不少初学者不理解原理;如果页面浮动布局多,就要增加很多空div,让人感觉很不好
建议:不推荐使用,但此方法是以前主要使用的一种清除浮动方法
3,父级div定义 伪类:after 和 zoom
复制代码
代码如下:
div2
原理:IE8以上和非IE浏览器才支持:after,原理和方法2有点类似,zoom(IE转有属性)可解决ie6,ie7浮动问题
优点:浏览器支持好、不容易出现怪问题(目前:大型网站都有使用,如:腾迅,网易,新浪等等)
缺点:代码多、不少初学者不理解原理,要两句代码结合使用才能让主流浏览器都支持。
建议:推荐使用,建议定义公共类,以减少CSS代码。
4,父级div定义 overflow:hidden
复制代码
代码如下:
div2
原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度
优点:简单、代码少、浏览器支持好
缺点:不能和position配合使用,因为超出的尺寸的会被隐藏。
建议:只推荐没有使用position或对overflow:hidden理解比较深的朋友使用。
5,父级div定义 overflow:auto
复制代码
代码如下:
div2
原理:必须定义width或zoom:1,同时不能定义height,使用overflow:auto时,浏览器会自动检查浮动区域的高度
优点:简单、代码少、浏览器支持好
缺点:内部宽高超过父级div时,会出现滚动条。
建议:不推荐使用,如果你需要出现滚动条或者确保你的代码不会出现滚动条就使用吧。
6,父级div 也一起浮动
复制代码
代码如下:
div2
原理:所有代码一起浮动,就变成了一个整体
优点:没有优点
缺点:会产生新的浮动问题。
建议:不推荐使用,只作了解。
7,父级div定义 display:table
复制代码
代码如下:
div2
原理:将div属性变成表格
优点:没有优点
缺点:会产生新的未知问题。
建议:不推荐使用,只作了解。
8,结尾处加 br标签 clear:both
复制代码
代码如下:
div2
原理:父级div定义zoom:1来解决IE浮动问题,结尾处加 br标签 clear:both
建议:不推荐使用,只作了解。
大多OO语言都支持两种继承方式: 接口继承和实现继承 ,而ECMAScript中无法实现接口继承,ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现,下文给大家技术js实现继承的六种方式,需要的朋友参考下
前言:大多OO语言都支持两种继承方式: 接口继承和实现继承 ,而ECMAScript中无法实现接口继承,ECMAScript只支持实现继承,而且其实现继承主要是依靠 原型链 来实现。
1.原型链
基本思想:利用原型让一个引用类型继承另外一个引用类型的属性和方法。
构造函数,原型,实例之间的关系:每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。
原型链实现继承例子:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = function() { return this.property; } function subType() { this.property = false; } //继承了SuperType SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function (){ return this.property; } var instance = new SubType(); console.log(instance.getSuperValue());//true |
2.借用构造函数
基本思想:在子类型构造函数的内部调用超类构造函数,通过使用call()和apply()方法可以在新创建的对象上执行构造函数。
例子:
?
1 2 3 4 5 6 7 8 9 10 11 |
function SuperType() { this.colors = ["red","blue","green"]; } function SubType() { SuperType.call(this);//继承了SuperType } var instance1 = new SubType(); instance1.colors.push("black"); console.log(instance1.colors);//"red","blue","green","black" var instance2 = new SubType(); console.log(instance2.colors);//"red","blue","green" |
3.组合继承
基本思想:将原型链和借用构造函数的技术组合在一块,从而发挥两者之长的一种继承模式。
例子:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
function SuperType(name) { this.name = name; this.colors = ["red","blue","green"]; } SuperType.prototype.sayName = function() { console.log(this.name); } function SubType(name, age) { SuperType.call(this,name);//继承属性 this.age = age; } //继承方法 SubType.prototype = new SuperType(); Subtype.prototype.constructor = Subtype; Subtype.prototype.sayAge = function() { console.log(this.age); } var instance1 = new SubType("EvanChen",18); instance1.colors.push("black"); consol.log(instance1.colors);//"red","blue","green","black" instance1.sayName();//"EvanChen" instance1.sayAge();//18 var instance2 = new SubType("EvanChen666",20); console.log(instance2.colors);//"red","blue","green" instance2.sayName();//"EvanChen666" instance2.sayAge();//20 |
4.原型式继承
基本想法:借助原型可以基于已有的对象创建新对象,同时还不必须因此创建自定义的类型。
原型式继承的思想可用以下函数来说明:
?
1 2 3 4 5 |
function object(o) { function F(){} F.prototype = o; return new F(); } |
例子:
?
1 2 3 4 5 6 7 8 9 10 11 |
var person = { name:"EvanChen", friends:["Shelby","Court","Van"]; }; var anotherPerson = object(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = object(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie" |
ECMAScript5通过新增Object.create()方法规范化了原型式继承,这个方法接收两个参数:一个用作新对象原型的对象和一个作为新对象定义额外属性的对象。
?
1 2 3 4 5 6 7 8 9 10 11 |
var person = { name:"EvanChen", friends:["Shelby","Court","Van"]; }; var anotherPerson = Object.create(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = Object.create(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie" |
5.寄生式继承
基本思想:创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真正是它做了所有工作一样返回对象。
例子:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function createAnother(original) { var clone = object(original); clone.sayHi = function () { alert("hi"); }; return clone; } var person = { name:"EvanChen", friends:["Shelby","Court","Van"]; }; var anotherPerson = createAnother(person); anotherPerson.sayHi();///"hi" |
6.寄生组合式继承
基本思想:通过借用函数来继承属性,通过原型链的混成形式来继承方法
其基本模型如下所示:
?
1 2 3 4 5 |
function inheritProperty(subType, superType) { var prototype = object(superType.prototype);//创建对象 prototype.constructor = subType;//增强对象 subType.prototype = prototype;//指定对象 } |
例子:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function SuperType(name){ this.name = name; this.colors = ["red","blue","green"]; } SuperType.prototype.sayName = function (){ alert(this.name); }; function SubType(name,age){ SuperType.call(this,name); this.age = age; } inheritProperty(SubType,SuperType); SubType.prototype.sayAge = function() { alert(this.age); } |
以上内容给大家介绍了javascript实现继承的六种方式,希望对大家有所帮助!
1.js原型(prototype)实现继承
代码如下
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
function Parent(name,age){ this.name=name; this.age=age; this.sayHi=function(){ alert("Hi, my name is "+this.name+", my age is "+this.age); } } //Child继承Parent function Child(grade){ this.grade=grade; this.sayGrade=function(){ alert("My grade is "+this.grade); } } Child.prototype=new Parent("小明","10");/////////// var chi=new Child("5"); chi.sayHi(); chi.sayGrade(); |
2.构造函数实现继承
代码如下:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
function Parent(name,age){ this.name=name; this.age=age; this.sayHi=function(){ alert("Hi, my name is "+this.name+", my age is "+this.age); } } //Child继承Parent function Child(name,age,grade){ this.grade=grade; this.sayHi=Parent;/////////// this.sayHi(name,age); this.sayGrade=function(){ alert("My grade is "+this.grade); } } var chi=new Child("小明","10","5"); chi.sayHi(); chi.sayGrade(); |
3.call , apply实现继承 -----很方便!
代码如下:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
function Parent(name,age){ this.name=name; this.age=age; this.sayHi=function(){ alert("Hi, my name is "+this.name+", my age is "+this.age); } } function Child(name,age,grade){ this.grade=grade; // Parent.call(this,name,age);/////////// // Parent.apply(this,[name,age]);/////////// 都可 Parent.apply(this,arguments);/////////// this.sayGrade=function(){ alert("My grade is "+this.grade); } // this.sayHi=function(){ // alert("Hi, my name is "+this.name+", my age is "+this.age+",My grade is "+this.grade); // } } var chi=new Child("小明","10","5"); chi.sayHi(); chi.sayGrade(); |
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持脚本之家!
在之前写了一篇博文《javascript
操作 url
中 search
部分方法函数》.在这篇博文里面,我们通过写好的函数可以对url
中的各种参数进行查询,设置.唯独,忘记了删除.
而今天就是遇到要删除某个参数的问题.郁闷,于是,写了这个函数.
// 删除url中某个参数,并跳转
function funcUrlDel(name){
var
loca = window.location;
var
baseUrl = loca.origin + loca.pathname +
"?";
var
query = loca.search.substr(
1);
if
(query.indexOf(name)>-
1) {
var
obj = {}
var
arr = query.split(
"&");
for
(
vari =
0; i < arr.length; i++) {
arr[i] = arr[i].split(
"=");
obj[arr[i][
0]] = arr[i][
1];
};
delete
obj[name];
var
url = baseUrl +
JSON.stringify(obj).replace(
/[\"\{\}]/g,
"").replace(
/\:/g,
"=").replace(
/\,/g,
"&");
return
url
};
}
功能:删除url
中指定的参数,并返回删除参数后的完整url
使用方法
示例
url:
http//xx.com/list?page=1&a=5
执行代码
funcUrlDel(
"page")
返回
http//xx.com/list?a=
5
其他说明
会忽略 hash
值,如果需要,自行加上即可.
使用jquery获取url以及使用jquery获取url参数是我们经常要用到的操作,下面通过文字说明加代码分析的形式给大家解析,具体详情请看下文。
1、jquery获取url很简单,代码如下:
复制代码代码如下:
window.location.href;
其实只是用到了javascript的基础的window对象,并没有用jquery的知识。
2、jquery获取url参数比较复杂,要用到正则表达式,所以学好javascript正则式多么重要的事情
首先看看单纯的通过javascript是如何来获取url中的某个参数:
?
1 2 3 4 5 6 |
//获取url中的参数 function getUrlParam(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象 var r = window.location.search.substr(1).match(reg); //匹配目标参数 if (r != null) return unescape(r[2]); return null; //返回参数值 } |
通过这个函数传递url中的参数名就可以获取到参数的值,比如url为
http://localhost:33064/WebForm2.aspx?reurl=WebForm1.aspx
我们要获取reurl的值,可以这样写:
复制代码代码如下:
var xx = getUrlParam('reurl');
明白了javascript获取url参数的方法,我们可以通过这个方法为jquery扩展一个方法来通过jquery获取url参数,下面的代码为jquery扩展了一个getUrlParam()方法
?
1 2 3 4 5 6 7 |
(function ($) { $.getUrlParam = function (name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return null; } })(jQuery); |
为jquery扩展了这个方法了之后我们就可以通过如下方法来获取某个参数的值了:
复制代码代码如下:
var xx = $.getUrlParam('reurl');
完整代码:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
$(function () { //方法二: (function ($) { $.getUrlParam = function (name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return null; } })(jQuery); //方法二: var xx = $.getUrlParam('reurl'); //方法一: // var xx = getUrlParam('reurl');
alert(xx); }); //方法一: //获取url中的参数 function getUrlParam(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象 var r = window.location.search.substr(1).match(reg); //匹配目标参数 if (r != null) return unescape(r[2]); return null; //返回参数值 } |
2014-4-23 修改
今天在用上面的方法获取url中的参数时,url中传递的中文参数在解析的时候无论怎么测试,获取的都是乱码。经过一番调试后发现,我再传递参数时,对汉字编码使用的是 encodeURI ,而上面的方法在解析参数编码时使用的是unescape ,修改为 decodeURI 就可以了。
附: W3School中的介绍:
JavaScript unescape() 函数
unescape() 函数可对通过 escape() 编码的字符串进行解码。
参数 |
描述 |
string |
必需。要解码或反转义的字符串。 |
说明
该函数的工作原理是这样的:通过找到形式为 %xx 和 %uxxxx 的字符序列(x 表示十六进制的数字),用 Unicode 字符 \u00xx 和 \uxxxx 替换这样的字符序列进行解码。
提示和注释
注释:ECMAScript v3 已从标准中删除了 unescape() 函数,并反对使用它,因此应该用 decodeURI() 和 decodeURIComponent() 取而代之。
综上: javascript对参数编码解码方法要一致:
escape() unescape()
encodeURI() decodeURI()
encodeURIComponent() decodeURIComponent()
网上找的另一种javascript获取url中参数的方法:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
function GetUrlParms() { var args=new Object(); var query=location.search.substring(1);//获取查询串 var pairs=query.split("&");//在逗号处断开 for(var i=0;i { var pos=pairs[i].indexOf('=');//查找name=value if(pos==-1) continue;//如果没有找到就跳过 var argname=pairs[i].substring(0,pos);//提取name var value=pairs[i].substring(pos+1);//提取value args[argname]=unescape(value);//存为属性 } return args; } var args = new Object(); args = GetUrlParms(); //如果要查找参数key: if(args["id"]!=undefined) { //如果要查找参数key: var value1 = args["id"] ; alert(value1); } |
jquery 取url参数和在url加参数
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
(function ($) { $.extend({ Request: function (m) { var sValue = location.search.match(new RegExp("[\?\&]" + m + "=([^\&]*)(\&?)", "i")); return sValue ? sValue[1] : sValue; }, UrlUpdateParams: function (url, name, value) { var r = url; if (r != null && r != 'undefined' && r != "") { value = encodeURIComponent(value); var reg = new RegExp("(^|)" + name + "=([^&]*)(|$)"); var tmp = name + "=" + value; if (url.match(reg) != null) { r = url.replace(eval(reg), tmp); } else { if (url.match("[\?]")) { r = url + "&" + tmp; } else { r = url + "?" + tmp; } } } return r; }
}); })(jQuery); |
使用方法
dev.zhang.com/IOF.Signup/index_uscn_chs.html?act=1
1、取值使用
$.Request("act") = 1
2、url加参数
$.UrlUpdateParams(window.location.href, "mid", 11111),
结果window.location.href?mid=11111
布局中经常会遇到让一个盒子水平且垂直居中的情况,以下总结了几种居中方法:
不兼容IE低版本的可以用其他方法hack。
不多说,直接上代码:
大多数方法的html都相同,所以写一个了,不同的再单独写出来。
(demo中有代码和效果)
HTML:
这种定位方法,纯粹是靠宽高和margin拼出来的,不灵活。
CSS:
#container {
width: 600px;
height: 500px;
border: 1px solid #000;
margin: auto;
}
#box {
width: 200px;
height: 200px;
margin: 150px 200px;
background-color: #0ff;
}
点击查看demo
利用负的margin来进行居中,需要知道固定宽高,限制比较大。
CSS:
#container {
position: relative;
width: 600px;
height: 500px;
border: 1px solid #000;
margin: auto;
}
#box {
position: absolute;
width: 200px;
height: 200px;
left: 50%;
top: 50%;
margin: -100px -100px;
background-color: #0ff;
}
点击查看demo
利用绝对定位居中,非常常用的一种方法。
CSS:
#container {
position: relative;
width: 600px;
height: 500px;
border: 1px solid #000;
margin: auto;
}
#box {
position: absolute;
width: 200px;
height: 200px;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
background-color: #0ff;
}
点击查看demo
利用table-cell来控制垂直居中。
CSS:
#container {
display: table-cell;
width: 600px;
height: 500px;
vertical-align: middle;
border: 1px solid #000;
}
#box {
width: 200px;
height: 200px;
margin: 0 auto;
background-color: #0ff;
}
点击查看demo
CSS3中引入的新布局方式,比较好用。缺点:IE9以及IE9一下不兼容。
CSS:
#container {
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
width: 600px;
height: 500px;
border: 1px solid #000;
margin: auto;
}
#box {
width: 200px;
height: 200px;
background-color: #0ff;
}
点击查看demo
这种方法灵活运用CSS中transform属性,较为新奇。缺点是IE9下不兼容。
CSS:
#container {
position: relative;
width: 600px;
height: 600px;
border: 1px solid #000;
margin: auto;
}
#box {
position: relative;
top: 50%;
left: 50%;
width: 200px;
height: 200px;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
background-color: #0ff;
}
点击查看demo
这种不确定宽高的居中,较为灵活。只需要保证left和right的百分数一样就可以实现水平居中,保证top和bottom的百分数一样就可以实现垂直居中。
CSS:
#container {
position: relative;
width: 600px;
height: 500px;
border: 1px solid #000;
margin: auto;
}
#box {
position: absolute;
left: 30%;
right: 30%;
top: 25%;
bottom: 25%;
background-color: #0ff;
}
点击查看demo
利用button做外容器,里边的块元素会自动垂直居中,只需要控制一下水平居中就可以达到效果。
HTML:
CSS:
button {
width: 600px;
height: 500px;
border: 1px solid #000;
}
div {
width: 200px;
height: 200px;
margin: 0 auto;
background-color: #0ff;
}
说到让一个div水平居中,立马想到最常用的就是margin:0 auto;但是这个的前提是必须知道盒子的宽度,盒子居中主要有两种情况:
一.确定盒子的宽度,解决办法有:
1.1 margin:0 auto;
1.2 position:relative;left:50%;margin-left:-0.5*width;(用绝对定位也可以)
二.不确定盒子宽度的,而且盒子宽度可变的,方法如下
2.1 position:relative:left:50%;transform:translateX(-50%);-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);//这里的50%是指盒子本身的50%;
2.2 width:fit-content;width:-moz-fit-content;width:-webket-fit-content;margin:auto;
利用margin,div1的宽减去div2的宽就是div2margin-left的数值:(100-40)/2=30
div1的高减去div2的高就是div2margin-top的数值:(100-40)/2=30
按 Ctrl+C 复制代码
demo
.div1{ width: 100px; height: 100px; border: 1px solid #000000;}
.div2{ width:40px ; height: 40px; background-color: green;}
.div22{
margin-left: 30px;margin-top: 30px;
}
第一种
利用css的 position属性,把div2相对于div1的top、left都设置为50%,然后再用margin-top设置为div2的高度的负一半拉回来,用marg-left设置为宽度的负一半拉回来,css如下设置
demo
.div1{ width: 100px; height: 100px; border: 1px solid #000000;}
.div2{ width:40px ; height: 40px; background-color: green;}
.div11{
position: relative;
}
.div22{
position: absolute;top:50%;left: 50%;margin-top: -20px;margin-left: -20px;
}
第二种
【】【】还是用css的position属性,如下的html
demo
.div1{ width: 100px; height: 100px; border: 1px solid #000000;}
.div2{ width:40px ; height: 40px; background-color: green;}
.div11{
position: relative;
}
.div22{
position: absolute;margin:auto; top: 0;left: 0;right: 0;bottom: 0;
}
第三种
利用css3的新增属性table-cell, vertical-align:middle;
demo
.div1{ width: 100px; height: 100px; border: 1px solid #000000;}
.div2{ width:40px ; height: 40px; background-color: green;}
.div11{
display: table-cell;vertical-align: middle;
}
.div22{
margin: auto;
}
第四种
demo
.div1{ width: 100px; height: 100px; border: 1px solid #000000;}
.div2{ width:40px ; background-color: green;}
.div11{
display: table-cell;vertical-align: middle;
}
.div22{
margin: auto;
}
div
居中方法
第五种方法
利用flexbox布局
直接在父元素上使用flexbox的布局
demo
.div1 {
width: 100px;
height: 100px;
border: 1px solid #000000;
}
.div2 {
height: 40px;
width: 40px;
background-color: green;
}
.div11 {
display: flex;
/*!*flex-direction: column;*!
可写可不写
*/
justify-content: center;
align-items: center;
}
第六种方法
利用transform的属性,注意子绝父相定位
缺点:需要支持Html5
demo
body {
margin: 100px auto;
position: relative;
}
.div1 {
width: 100px;
height: 100px;
border: 1px solid #000000;
background-color: red;
}
.div2 {
height: 40px;
width: 40px;
background-color: green;
}
.center {
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
我是外部盒子
我要居中
第七种
两者都要固定定位,不常用
缺点:需要设置position属性,网页复杂时容易扰乱页面布局,而且只是元素的起始位置居中
demo
.div1 {
width: 100px;
height: 100px;
border: 1px solid #000000;
background-color: red;
position: relative;
}
.div2 {
height: 40px;
width: 40px;
background-color: green;
margin:30px 30px;
}
.center{
position: fixed;
left: 50%;
}
我要居中
第八种方法
js事件的监听器的使用
1、当同一个对象使用.onclick的写法触发多个方法的时候,后一个方法会把前一个方法覆盖掉,也就是说,在对象的onclick事件发生时,只会执行最后绑定的方法。而用事件监听则不会有覆盖的现象,每个绑定的事件都会被执行。如下:
[javascript] view plain copy
最后只输出:第三个事件,因为后一个方法都把前一个方法覆盖掉了。
原生态的事件绑定函数addEventListener:
[javascript] view plain copy
输出:第一个监听事件 和 第二个监听事件
2、采用事件监听给对象绑定方法后,可以解除相应的绑定,写法如下:
[javascript] view plain copy
输出:第二个监听事件
3、解除绑定事件的时候一定要用函数的句柄,把整个函数写上是无法解除绑定的。
错误写法:
[javascript] view plain copy
正确写法:
[javascript] view plain copy
总结:对函数进行封装后的监听事件如下,兼容各大主流浏览器。
[javascript] view plain copy
[javascript] view plain copy
实例:
[html] view plain copy
转载 2012-10-11 作者: 我要评论
事件(Event)知识整理,本文由网上资料整理而来,需要的朋友可以参考下
鼠标事件
鼠标移动到目标元素上的那一刻,首先触发mouseover
之后如果光标继续在元素上移动,则不断触发mousemove
如果按下鼠标上的设备(左键,右键,滚轮……),则触发mousedown
当设备弹起的时候触发mouseup
目标元素的滚动条发生移动时(滚动滚轮/拖动滚动条。。)触发scroll
滚动滚轮触发mousewheel,这个要区别于scroll
鼠标移出元素的那一刻,触发mouseout
事件注册
平常我们绑定事件的时候用dom.onxxxx=function(){}的形式
这种方式是给元素的onxxxx属性赋值,只能绑定有一个处理句柄。
但很多时候我们需要绑定多个处理句柄到一个事件上,而且还可能要动态的增删某个处理句柄
下面的事件注册方式就能解决这个需求。
先介绍一下四个方法
复制代码代码如下:
//IE以外
target.addEventListener(type,listener,useCapture)
target.removeEventListener(type,listener,useCapture);
target :文档节点、document、window 或 XMLHttpRequest。
type :字符串,事件名称,不含“on”,比如“click”、“mouseover”、“keydown”等。
listener :实现了 EventListener 接口或者是 JavaScript 中的函数。
useCapture :是否使用捕捉,一般用 false。
//IE
target.attachEvent(type, listener);
target.detachEvent(type, listener);
target :文档节点、document、window 或 XMLHttpRequest。
type :字符串,事件名称,含“on”,比如“onclick”、“onmouseover”、“onkeydown”等。
listener :实现了 EventListener 接口或者是 JavaScript 中的函数。
两者使用的原理:可对执行的优先级不一样,实例讲解如下:
ele.attachEvent("onclick",method1);
ele.attachEvent("onclick",method2);
ele.attachEvent("onclick",method3);
执行顺序为method3->method2->method1
ele.addEventListener("click",method1,false);
ele.addEventListener("click",method2,false);
ele.addEventListener("click",method3,false);
执行顺序为method1->method2->method3
兼容后的方法
var func = function(){};
//例:addEvent(window,"load",func)
function addEvent(elem, type, fn) {
if (elem.attachEvent) {
elem.attachEvent('on' + type, fn);
return;
}
if (elem.addEventListener) {
elem.addEventListener(type, fn, false);
}
}
//例:removeEvent(window,"load",func)
function removeEvent(elem, type, fn) {
if (elem.detachEvent) {
elem.detachEvent('on' + type, fn);
return;
}
if (elem.removeEventListener) {
elem.removeEventListener(type, fn, false);
}
}
获取事件对象和事件源(触发事件的元素)
复制代码代码如下:
function eventHandler(e){
//获取事件对象
e = e || window.event;//IE和Chrome下是window.event FF下是e
//获取事件源
var target = e.target || e.srcElement;//IE和Chrome下是srcElement FF下是target
}
取消事件默认行为(例如点击一个后不跳转页面而是执行一个函数)
复制代码代码如下:
function eventHandler(e) {
e = e || window.event;
// 防止默认行为
if (e.preventDefault) {
e.preventDefault();//IE以外
} else {
e.returnValue = false;//IE
//注意:这个地方是无法用return false代替的
//return false只能取消元素
}
}
阻止事件冒泡
复制代码代码如下:
function myParagraphEventHandler(e) {
e = e || window.event;
if (e.stopPropagation) {
e.stopPropagation();//IE以外
} else {
e.cancelBubble = true;//IE
}
}
复制代码代码如下: 复制代码代码如下: 在JS中创建对象有很多种方法,而创建自定义类型的最常见的方式,就是使用组合使用构造函数模式和原型模式创建对象。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性,那么来看看为什么这种方式是最常用的。 依次来看: function createPerson(name,age,gender){ var obj = new Object(); obj.name = name; obj.age = age; obj.gender = gender; obj.sayName = function(){ alert(this.name); }; return obj; } //接下来就可以创建对象了var person = createPerson("Stan",0000,"male"); 如果创建多个这种类似的对象,当然很ok啦,但是有更好的模式创建对象。 function Person(name,age,gender){ this.name = name; this.age = age; this.gender = gender; this.sayName = function(){ alert(this.name); }; } //然后可以用new操作符来创建Person的新实例 var person = new Person("Stan",0000,"male"); //最直观的就是代码比工厂模式少吧。 //另外,创建自定义的构造函数意味着将来可以将它的实例标识为一种特定类型,这是构造函数模式胜过工厂模式的地方(努力理解中。) //也可以像下面这种创建并调用 Person("Stan",0000,"male"); window.sayName(); //或是在另一个对象的作用域中调用 var obj = new Object(); Person.call(obj,"Stan",0000,"male"); obj.sayName(); //这里是在obj对象的作用域中调用Person(),因此调用后obj就拥有了所有属性和sayName()方法 这里说说构造函数模式的问题,定义在构造函数中的方法在每次实例化的时候都会被创建一次,并且每次被创建的方法都是一个新的对象(JS中函数即对象),即创建两个完成同样任务的Function实例是没有必要的,也就是说,如果一个方法可以被共享使用的话,不应该这么做。如果写成下面这样: function Person(name,age,gender){ this.name = name; this.age = age; this.gender = gender; this.sayName = sayName; } function sayName(){ alert(this.name); } 这样把sayName()定义成全局函数,虽然解决了多个函数做同一样件事情而不用每次创建的问题,但是假如需要N个全局函数,那么我们这个自定义的引用类型就没有丝毫的封装性可言了。所以有更好的原型模式可以解决这个问题 3.原型模式 function Person(){} Person.prototype.name = "Stan"; Person.prototype.age = 0000; Person.prototype.gender = "male"; Person.prototype.sayName = function(){ alert(this.name); } var person = new Person(); person.sayName(); //原型对象中的所有属性和方法都是可以被实例所共享的 当我们在调用person.sayName()方法时,会先后执行两次搜索,先从对象实例本身开始,如果在实例中找到该方法,则调用 ,若没有找到,会继续搜索指针指向的原型对象,找到则调用方法。有一个问题,如果我们在实例中添加一个属性,而该属性与实例原型中的一个属性同名,该属性将会屏蔽掉原型中的那个属性,就像下面这样: function Person(){} Person.prototype.name = "Stan"; var person = new Person(); person.name = "Joe"; alert(person.name);//结果是Joe 即使将这个name属性设置为null,也只会在实例中设置这个属性,而不会恢复其指向原型的连接 。可以使用delete操作符完全的删除实例属性,从而可以重新访问到原型中的属性。像下面这样: function Person(){} Person.prototype.name = "Stan"; var person = new Person(); person.name = null; alert(person.name);//结果是null,而不是Stan //可以这样做: delete person.name; alert(person.name); 另外还可以把原型语法像下面这样写: function Person(){} Person.prototype = { name : "Stan", age : 0000, gender : "male", sayName : function(){ alert(this.name); } }; 这种写法实际上是重写了原型对象,所以接下来看一个问题,即原型的动态性 function Person(){} var person = new Person(); Person.prototype.name = "Stan"; alert(person.name); 虽然person实例是在添加新属性之前创建的,但是仍然可以立即在实例中访问到name属性,但是如果全部重写了原型对象,就会出问题了,像下面这样: function Person(){} var person = new Person(); Person.prototype = { name : "Stan", age : 0000, gender : "male", sayName : function(){ alert(this.name); } }; alert(person.name);//undefined 这是为什么呢?因为重写原型切断了现有原型(重写后的原型)与任何之前已经存在的对象实例之间的联系,person引用的仍然是最初的原型,这里person实例最初的原型中除了默认的一些属性外,是没有name属性的,所以就会undefined咯! 原型对象看似还可以,但它也是有问题的,什么问题呢,就是其共享的本性,分析下,原型中所有属性是被很多实例共享的,这种共享对于函数非常合适,对于那些包含基本值的属性也还行,因为我们还可以通过在实例上添加一个同名属性来隐藏掉原型中的对应属性(不会影响到其它的实例的属性),但是如果包含引用类型值的属性来说,问题就来了,看下面: function Person(){} Person.prototype = { colors : ["red","green","pink"] }; var person1 = new Person(); person1.colors.push("black"); var person2 = new Person(); alert(person2.colors); // red,green,pink,black 看到问题了吧,大多数时候,实例一般都是要属于自己的全部属性的,即我们不会这么单独使用原型模式,所以这才到今天我们要说的主题:组合使用构造函数模式和原型模式创建对象 function Person(name,age,gender){ this.name = name; this.age = age; this.gender = gender; this.colors = ["red","green","pink"]; } Person.prototype = { sayName : function(){ alert(this.name); } } var person1 = new Person("Stan",0000,"male"); var person2 = new Person("Joe",1111,"female"); person1.colors.push("black"); alert(person1.colors); // red,green,pink,black alert(person2.colors); // red,green,pink alert(person1.sayName == person2.sayName); // true 先说到这里吧。 这么基础的东西实在不应该再记录了,不过嘛,温故知新~就先从数据类型开始吧 js六大数据类型:number、string、object、Boolean、null、undefined string: 由单引号或双引号来说明,如"string" number:什么整数啊浮点数啊都叫数字,你懂的~ Boolean: 就是true和false啦 undefined:未定义,就是你创建一个变量后却没给它赋值~ null: 故名思久,null就是没有,什么也不表示 object: 这个我也很难解释的说。就是除了上面五种之外的类型 --------------------上面的都是浮云,下面的才是神马------------------------------ 数据类型判断之 typeof typeof可以解决大部分的数据类型判断,是一个一元运算,放在一个运算值之前,其返回值为一个字符串,该字符串说明运算数的类型,所以判断某个是否为String类型,可以直接 if(typeof(你的值) == "string"){} 以下是各种数据类型返回结果: ? 1 2 3 4 5 6 7 8 9 10 var a="string"; console.log(a); //string var a=1; console.log(a); //number var a=false; console.log(a); //boolean var a; console.log(typeof a); //undfined var a = null; console.log(typeof a); //object var a = document; console.log(typeof a); //object var a = []; console.log(a); //object var a = function(){}; console.log(typeof a) //function 除了可以判断数据类型还可以判断function类型 这样一来就很明显了,除了前四个类型外,null、对象、数组返回的都是object类型; 对于函数类型返回的则是function,再比如typeof(Date),typeof(eval)等。 然后这里就可以再引申出另一个灰常热门并且解决方法已普遍存在的问题,如何判断数据是个数组类型? ---------------------------------------其实这才是我的目的,咩~---------------------------------------------- js判断数组类型的方法 方法一之 instanceof instance,故名思义,实例,例子,所以instanceof 用于判断一个变量是否某个对象的实例,是一个三目运算式---和typeof最实质上的区别 a instanceof b?alert("true"):alert("false") //注意b值是你想要判断的那种数据类型,不是一个字符串,比如Array 举个栗子: ? 1 2 var a=[]; console.log(a instanceof Array) //返回true 方法二之 constructor 在W3C定义中的定义:constructor 属性返回对创建此对象的数组函数的引用 就是返回对象相对应的构造函数。从定义上来说跟instanceof不太一致,但效果都是一样的 如: (a instanceof Array) //a是否Array的实例?true or false (a.constructor == Array) // a实例所对应的构造函数是否为Array? true or false 举个栗子: ? 1 2 3 4 5 6 7 8 function employee(name,job,born){ this.name=name; this.job=job; this.born=born; } var bill=new employee("Bill Gates","Engineer",1985); console.log(bill.constructor); //输出function employee(name, jobtitle, born){this.name = name; this.jobtitle = job; this.born = born;} 那么判断各种类型的方法就是: ? 1 2 3 4 5 console.log([].constructor == Array); console.log({}.constructor == Object); console.log("string".constructor == String); console.log((123).constructor == Number); console.log(true.constructor == Boolean); -------------------------------------以下不是原创-------------------------------------- 较为严谨并且通用的方法: ? 1 2 3 4 function isArray(object){ return object && typeof object==='object' && Array == object.constructor; } !!注意: 使用instaceof和construcor,被判断的array必须是在当前页面声明的!比如,一个页面(父页面)有一个框架,框架中引用了一个页面(子页面),在子页面中声明了一个array,并将其赋值给父页面的一个变量,这时判断该变量,Array == object.constructor;会返回false; 原因: 1、array属于引用型数据,在传递过程中,仅仅是引用地址的传递。 方法三之 特性判断法 以上方法均有一定的缺陷,但要相信人民大众的智慧是无所不能及的,我们可根据数组的一些特性来判断其类型 ? 1 2 3 4 5 6 7 function isArray(object){ return object && typeof object==='object' && typeof object.length==='number' && typeof object.splice==='function' && //判断length属性是否是可枚举的 对于数组 将得到false !(object.propertyIsEnumerable('length')); } 有length和splice并不一定是数组,因为可以为对象添加属性,而不能枚举length属性,才是最重要的判断因子。 ps: 在这里普及下 propertyIsEnumerable 方法: object. propertyIsEnumerable(proName) 判断指定的属性是否可列举 备注:如果 proName 存在于 object 中且可以使用一个 For…In 循环穷举出来,那么 propertyIsEnumerable 属性返回 true。如果 object 不具有所指定的属性或者所指定的属性不是可列举的,那么 propertyIsEnumerable 属性返回 false。 propertyIsEnumerable 属性不考虑原型链中的对象。 示例: ? 1 2 var a = new Array("apple", "banana", "cactus"); document.write(a.propertyIsEnumerable(1)); 方法四之 最简单的方法 ? 1 2 3 function isArray(o) { return Object.prototype.toString.call(o) === ‘[object Array]‘; } 以上就是本文的全部内容,了解更多JavaScript的语法,大家可以查看:《JavaScript 参考教程》、《JavaScript代码风格指南》,也希望大家多多支持脚本之家。 因为无论是数组还是对象,对于typeof的操作返回值都为object,所以就有了区分数组类型和对象类型的需要: 方一:通过length属性:一般情况下对象没有length属性值,其值为undefiend,而数组的length值为number类型 缺点:非常不实用,当对象的属性存在length,且其值为number(比如类数组),则该方法失效,不建议使用,看看即可。 *方二:通过instanceof来判断区分 *方三:通过constructor *方四:通过toString()方法,数组原型和对象原型定义的toString()方法不同 原理参考:http://www.cnblogs.com/ziyunfei/archive/2012/11/05/2754156.html 方五:随便找一个数组仅有的方法,来判断数组和对象谁有该方法即可(样例以sort来举例) 总结:方法应用权重: 优先使用方四toString,因为该方法几乎无缺陷。 次之可以使用方二instanceof和方三constructor 剩下的方法玩玩即可,不实用 判断objectName是否是数组 基本数据类型也可以使用此方法。 1、2判断有误差。 a)length 有length和splice并不一定是数组,因为可以为对象添加属性,而不能枚举length属性,才是最重要的判断因子。 ES5方法 获取this对象的[[Class]]属性的值.[Class]]是一个内部属性,所有的对象都拥有该属性. 表明该对象的类型 其中 变量 这就是 ps: 关于 typeof 操作符 由于 需要注意的是 Undefined Null 如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为 实际上,undefined值是派生自null值的,因此ECMA-262规定对它们的相等性测试要返回true。 尽管null和undefined有这样的关系,但它们的用途完全不同。无论在什么情况下都没有必要把一个变量的值显式地设置为undefined,可是同样的规则对null却不适用。换句话说,只要意在保存对象的变量还没有真正保存对象,就应该明确地让该变量保存null值。这样做不仅可以体现null作为空对象指针的惯例,而且也有助于进一步区分null和undefined。 Boolean 该类型只有两个字面值:true和false。这两个值与数字值不是一回事,因此true不一定等于1,而false也不一定等于0。 虽然Boolean类型的字面值只有两个,但JavaScript中所有类型的值都有与这两个Boolean值等价的值。要将一个值转换为其对应的Boolean值,可以调用类型转换函数Boolean(),例如: 在这个例子中,字符串message被转换成了一个Boolean值,该值被保存在messageAsBoolean变量中。可以对任何数据类型的值调用Boolean()函数,而且总会返回一个Boolean值。至于返回的这个值是true还是false,取决于要转换值的数据类型及其实际值。下表给出了各种数据类型及其对象的转换规则。 数据类型 转换为true的值 转换为false的值 Boolean true false String 任何非空的字符串 ""(空字符串) Number 任何非0数值(包括无穷大) 0和NAN Object 任何对象 null Undefined 不适用 undefined 运行这个示例,就会显示一个警告框,因为字符串message被自动转换成了对应的Boolean值(true)。由于存在这种自动执行的Boolean转换,因此确切地知道在流控制语句中使用的是什么变量至关重要。 ps:使用!!操作符转换布尔值 对null与undefined等其他用隐式转换的值,用!操作符时都会产生true的结果,所以用两个感叹号的作用就在于将这些值转换为“等价”的布尔值; 这段例子,演示了在undifined和null时,用一个感叹号返回的都是true,用两个感叹号返回的就是false,所以两个感叹号的作用就在于,如果明确设置了变量的值(非null/undifined/0/”“等值),结果就会根据变量的实际值来返回,如果没有设置,结果就会返回false。 还有其他的小技巧,可以参考这12个JavaScript技巧 Number 这种类型用来表示整数和浮点数值,还有一种特殊的数值,即NaN(非数值 Not a Number)。这个数值用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)。例如,在其他编程语言中,任何数值除以0都会导致错误,从而停止代码执行。但在JavaScript中,任何数值除以0会返回NaN,因此不会影响其他代码的执行。 NaN本身有两个非同寻常的特点。首先,任何涉及NaN的操作(例如NaN/10)都会返回NaN,这个特点在多步计算中有可能导致问题。其次,NaN与任何值都不相等,包括NaN本身。例如,下面的代码会返回false。 String String类型用于表示由零或多个16位Unicode字符组成的字符序列,即字符串。字符串可以由单引号(')或双引号(")表示。 String类型的特殊性 string类型有些特殊,因为字符串具有可变的大小,所以显然它不能被直接存储在具有固定大小的变量中。由于效率的原因,我们希望JS只复制对字符串的引用,而不是字符串的内容。但是另一方面,字符串在许多方面都和基本类型的表现相似,而字符串是不可变的这一事实(即没法改变一个字符串值的内容),因此可以将字符串看成行为与基本类型相似的不可变引用类型 Boolean、Number、String 这三个是Javascript中的基本包装类型,也就是这三个其实是一个构造函数,他们是Function的实例,是引用类型,至于这里的String与以上说的String是同名,是因为其实上文说的String是指字符串,这里的String指的是String这个构造函数,上面那么写,是为了更好的理解,因为Javascript是松散类型的。我们可以看下String实例化的例子: 至于author这个会有length,substring等等这些方法,其实string只是String的一个实例,类似于C#中的String,和string. 注意,typeof 变量 如果值是"string" 的话,也就是这个变量是字符串,在Javascript中,字符串是基本类型,而在C#或Java中,字符串是引用类型,但是Javascript中的String是引用类型,因为它是Javascript中定义好的基本包装类型,在C#中,String跟string其实是一样的。 本帖只是简要的copy了一些JavaScript高级程序设计(第三版)内容,外加了自己侧重的角度,看本帖的朋友还是要看书啊,这里只是做个参考。 1、Symbol概述 JavaScript基本数据类型有6种:Undefined、Null、Boolean、String、Number、Object。 ES6新增了一种数据类型:Symbol,表示独一无二的值,Symbol最大的用途是用来定义对象的唯一属性名。 ES5的对象属性名都是字符串,容易造成属性名的冲突。如使用了一个其他人提供的对象,但又想为其添加新的方法(mixin模式),那么新方法的名字有可能与已有方法产生冲突。因此,需要保证每个属性的名字都是独一无二,以防止属性名的冲突。这就是ES6引入Symbol的原因。 Symbol值通过Symbol函数生成。 [javascript] view plain copy typeof运算符用于Symbol类型值,返回symbol。 [javascript] view plain copy Symbol类型的值是一个独一无二的值,Symbol函数的参数只是表示对当前Symbol值的描述,因此相同参数的Symbol函数的返回值是不相等的。 [javascript] view plain copy Symbol不是一个构造函数,如果用new Symbol会报错(Symbol是一个原始类型的值,不是对象)。 [javascript] view plain copy 由于Symbol值不是对象,所以不能添加属性。 [javascript] view plain copy Symbol值不能与其他类型的值进行运算。 [javascript] view plain copy Symbol值可以显式转为字符串,也可以转为布尔值,但是不能转为数值。 [javascript] view plain copy 2、作为对象属性名的Symbol 由于每一个Symbol值都是不相等的,这意味着Symbol值可以用于对象的属性名,保证不会出现同名的属性,这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。 对象的属性名可以有两种类型,一种是原来的字符串,另一种是新增的Symbol类型。凡是属性名属于Symbol类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。 通过方括号结构和Object.defineProperty,将对象的属性名指定为一个Symbol值。 方法一: [javascript] view plain copy 方法二: [javascript] view plain copy 方法三: [javascript] view plain copy 在对象的内部,使用Symbol值定义属性时,Symbol值必须放在方括号之中,如果不放在方括号中,该属性名就是字符串,而不是代表的Symbol值。 [javascript] view plain copy Symbol值作为对象属性名时,不能用点运算符。由于点运算符后面总是字符串,所以不会读取name作为标识名所指代的那个值,导致属性名实际上是一个字符串,而不是一个Symbol值。 [javascript] view plain copy 3、作为对象函数名的Symbol [javascript] view plain copy 4、获取对象属性的两种方法 1) Object.getOwnPropertySymbols()方法 返回只包含Symbol类型的属性名的数组 2) Object.getOwnPropertyNames()方法 返回只包含字符串类型的属性名的数组 [javascript] view plain copy 5、Symbol.for()和Symbol.keyFor()方法 1) Symbol.for()方法 类似于单例模式,首先在全局中搜索有没有以该参数为名称的Symbol值,如果有则返回该Symbol值,否则新建并返回一个以该参数为名称的Symbol值。 [javascript] view plain copy 2) Symbol.keyFor()方法 返回一个已创建的Symbol类型值的key,实质是检测该Symbol是否已创建。 [javascript] view plain copy 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhouziyu2011/arti 数据结构中的基础排序算法包括冒泡,选择和插入排序,它们的核心思想都是对一组数据按照一定的顺序重新排列,排列时用到的主要是一组嵌套的for循环,其中外循环遍历数组的每一项,内循环则用于比较元素。以下将按照升序排列为例。 1.冒泡排序 冒泡排序时数组的数据会像气泡一样从数组的一段漂浮到另一端,因此才有了冒泡这个命名。基本步骤如下: 1.依次两两比较相邻的元素,如果第一个比第二个大,则进行交换。 2.经过第一轮比较之后,最大的数已经出现在数组最后一个位置了。 3.然后再对除了最后一个元素外的所有数都重复一遍上述比较,结束后第二个的数会到达数组倒数第二个位置。 4.再依次对剩下的数进行重复,直到排序完毕。 下面看看代码描述: function bubbleSort(arr){ for(var i=0; i<arr.length; i++){ for(var j=0; j<arr.length-i; j++){ //当第一个数大于第二个时,交换它们 if(arr[j]>arr[j+1]){ var temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } //测试 var testArr = [35,22,1,56,88,25]; bubbleSort(testArr); alert(testArr); //输出1,22,25,35,56,88 2.选择排序 步骤如下: 1.从数组的开头起,将第一个元素和其他所有元素都进行一次比较,选择出最小的元素放在数组的第一个位置。 2.然后再从第二个元素开始,将第二个元素和除第一个之外的所有元素进行一次比较,选择出最小的元素放在数组的第二个位置。 3.对后面的第三,第四……的元素分别重复上面的步骤,知道所有的数据完成排序。 代码描述如下: function selectSort(arr){ var minIndex;//定义minIndex变量用于存储每一趟比较时的最小数的下标 for(var i=0; i<arr.length; i++){ minIndex = i; for(var j=i+1; j<arr.length; j++){ if(arr[minIndex]>arr[j]){ minIndex = j; } } //每轮比较后若arr[i]不是我们需要的最小那个数,则进行交换 if(minIndex!=i){ var temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; } } } //测试 var testArr = [35,22,1,56,88,25]; selectSort(testArr); alert(testArr); //输出1,22,25,35,56,88 3.插入排序 插入排序的思想非常简单,主要如下: 步骤: 1.首先将数组第1个数看成是一个有序序列。 2.将数组的第2个数按照关键字大小插入到这个有序序列中,插入后得到了一包含两个数的有序序列。 3.接下来再重复上面的步骤将第3,第4……第n-1个数分别插入到该有序序列中,最终得到一个包含n个数的有序序列。 代码描述: function insertSort(arr){ var temp; //temp变量用于临时存储待插入元素 for(var i=1; i<arr.length; i++){ temp = arr[i]; //从前往后查找插入位置 for(var j=i; j>0&&arr[j-1]>temp; j--){ arr[j]=arr[j-1]; //将大于temp的arr[j]元素后移 } arr[j]=temp; } } //测试 var testArr = [35,22,1,56,88,25]; insertSort(testArr); alert(testArr); //输出1,22,25,35,56,88 现在如果要在页面中使用video标签,需要考虑三种情况,支持Ogg Theora或者VP8(如果这玩意儿没出事的话)的(Opera、Mozilla、Chrome),支持H.264的(Safari、IE 9、Chrome),都不支持的(IE6、7、8)。好吧,现在让我们从技术层面来认识HTML 5的视频,包括video标签的使用,视频对象可以用到的媒介属性和方法,以及媒介事件。 Video标签的使用 Video标签含有src、poster、preload、autoplay、loop、controls、width、height等几个属性, 以及一个内部使用的标签。Video标签内除了可以包含标签外,还可以包含当指定的视频都不能 播放时,返回的内容。 (1) src属性和poster属性 你能想象src属性是用来干啥的。跟标签的一样,这个属性用于指定视频的地址。而poster属性用于指定一张图片,在当前视频数据无效时显示(预览图)。视频数据无效可能是视频正在加载,可能是视频地址错误等等。 (2) preload属性 这个属性也能通过名字了解用处,此属性用于定义视频是否预加载。属性有三个可选择的值:none、metadata、auto。如果不使用此属性,默认为auto。 None:不进行预加载。使用此属性值,可能是页面制作者认为用户不期望此视频,或者减少HTTP请求。 Metadata:部分预加载。使用此属性值,代表页面制作者认为用户不期望此视频,但为用户提供一些元数据(包括尺寸,第一帧,曲目列表,持续时间等等)。 Auto:全部预加载。 (3) autoplay属性 又是一个看名字知道用处的属性。Autoplay属性用于设置视频是否自动播放,是一个布尔属性。当出现时,表示自动播放,去掉是表示不自动播放。 注意,HTML中布尔属性的值不是true和false。正确的用法是,在标签中使用此属性表示true,此时属性要么没有值,要么其值恒等于他的名字 (此处,自动播放为或者);而在标签中不使用此属性表示false(此处不进行自动播放为)。 (4) loop属性 一目了然,loop属性用于指定视频是否循环播放,同样是一个布尔属性。 (5) controls属性 Controls属性用于向浏览器指明页面制作者没有使用脚本生成播放控制器,需要浏览器启用本身的播放控制栏。 控制栏须包括播放暂停控制,播放进度控制,音量控制等等。 每个浏览器默认的播放控制栏在界面上不一样。由于我浏览器的诡异问题,Firefox和Safari的Video标签不正常,所以这两个只能在网上找截图了。 (6) width属性和height属性 属于标签的通用属性了,这个不用多说。 (7) source标签 Source标签用于给媒体(因为audio标签同样可以包含此标签,所以这儿用媒体,而不是视频)指定多个可选择的(浏览器最终只能选一个)文件地址,且只能在媒体标签没有使用src属性时使用。 浏览器按source标签的顺序检测标签指定的视频是否能够播放(可能是视频格式不支持,视频不存在等等),如果不能播放,换下一个。此方法多用于兼容不同的浏览器。Source标签本身不代表任何含义,不能单独出现。 此标签包含src、type、media三个属性。 src属性:用于指定媒体的地址,和video标签的一样。 Type属性:用于说明src属性指定媒体的类型,帮助浏览器在获取媒体前判断是否支持此类别的媒体格式。 Media属性:用于说明媒体在何种媒介中使用,不设置时默认值为all,表示支持所有媒介。你想到标签的media属性了么?一样一样一样的。 (8) 一个完整的例子 这段代码在页面中定义了一个视频,此视频的预览图为poster的属性值,显示浏览器的默认媒体控制栏,预加载视频的元数据,循环播放,宽度为900像素,高度为240像素。 第一选择视频地址为第一个source标签的src属性值,视频类别为Ogg视频,视频编码译码器为Theora,音频编码译码器为Vorbis,播放媒 介为显示器;第二选择视频地址不再累述。如果你还要兼容IE的话,可以在最后一个source标签后再加上Flash播放器的标签集,或者使用一点 JavaScript代码。 上面是伪类的正确顺序,简称 lvha(love-ha)。你一直知道这个顺序但是为什么这样呢?原理是怎么样的? 原理 首先伪类的特殊性(应用优先级)是同样的,所以后出现的伪类会覆盖先出现的伪类(同时激活) 在css3之前,要实现圆角的效果可以通过图片或者用margin属性实现(可以参考这里:http://www.hicss.net/css-practise-of-image-round-box/)。实现过程很繁琐,但CSS3的到来简化了实现圆角的方式。 CSS3实现圆角需要使用border-radius属性,但因为浏览器兼容性的问题,在开发过程中要加私有前缀。 1 2 3 4 border-radius属性其实可以分为四个其他的属性: 1 2 3 4 5 下面用几个实例来展示border-radius的具体用法。 1、border-radius单个属性值: 1 2 1 2 3 4 5 6 效果: 2、border-radius是个属性值方式: 1 2 3 4 5 6 7 效果: 不过在开发的过程中(我的工作中),经常用到的是border-radius单属性值,设置4个不同圆角的情况很少。 border-radius的优势不仅仅在制作圆角的边框,还是利用border-radius属性来画圆和半圆。 1、制作半圆的方法: 元素的高度是宽度的一半,左上角和右上角的半径元素的高度一致(大于高度也是可以的,至少为height值)。 1 2 3 4 5 6 7 效果: 知道了如何画上半圆,就会举一反三画其他方向的圆了,这里不再赘述。 2、画实心圆的方法: 宽度和高度一致(正方形),然后四个角设置为高度或者宽度的1/2. 1 2 3 4 5 6 7 效果: 总结: CSS3实现圆角的方式既优雅又方便,但是兼容性不够好,如果需要考虑旧版本的浏览器的话,可以考虑优雅降级的方式。开始提到的两种方式的优点是兼容性好,但不够优雅。 据w3c上的官方解释,是这样子的: 写过border的人都知道border可以带四个参数分别设置四个边框(上左下右的顺序),同样的,border-radius也可以带四个参数,并且以顺时针的方向解析,上左,上右,下右,下左: 1 2 3 展示结果: 两个参数的时候,是上左和下右,上右和下左,比如.div1{border-radius: 2em 1em},就不截图了,直接demo 三个参数的时候,是上左,上右和下左,下右,比如.div1{border-radius: 2em 1em 3em},demo 那么以斜杠/分开后面的参数是怎么回事呢?是这样子的,第一个参数表示圆角的水平半径,第二个参数表示圆角的垂直半径,所以你现在就可以画一个左右不对称的圆角啦: 1 看到这里你会不会以如果四个圆角都要分别制定特殊的形状,是不是 2em/1em , 1em/0.5em, 3em/1em, 1em/1em像上面那个四个参数一样的设定(我就是这么以为的),答案是错!误!的!因为官方的解释就是前面放1-4后面放1-4啊!鱼不是被吃掉的就是被笨s的~ 1 2 3 按顺时针的顺序,斜杠/左边是四个圆角的水平半径,右边是四个圆角的垂直半径,但是通常我们很少写右边的参数,那就是默认右边等于左边的值。当然你也可以省略一些值,比如这样子写.div1{border-radius: 2em 1em 4em / 0.5em 3em;},解析顺序你就可以按照上面的自己推算一下啦。 页面本身是不具备保存历史数据的功能的,需要借助其它手段来实现,常用方法如下: 本篇文章主要是对JS刷新当前页面的几种方法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 reload 方法,该方法强迫浏览器刷新当前页面。 replace 方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,你不能通过“前进”和“后退”来访问已经被替换的URL。 在实际应用的时候,重新刷新页面的时候,我们通常使用: location.reload() 或者是 history.go(0) 来做。因为这种做法就像是客户端点F5刷新页面,所以页面的method="post"的时候,会出现"网页过期"的提示。那是因为Session的安全保护机制。可以想到: 当调用 location.reload() 方法的时候, aspx页面此时在服务端内存里已经存在, 因此必定是 IsPostback 的。如果有这种应用: 我们需要重新加载该页面,也就是说我们期望页面能够在服务端重新被创建, 我们期望是 Not IsPostback 的。这里,location.replace() 就可以完成此任务。被replace的页面每次都在服务端重新生成。 你可以这么写: location.replace(location.href); 返回并刷新页面: location.replace(document.referrer); 不要用 history.go(-1),或 history.back();来返回并刷新页面,这两种方法不会刷新页面。 附: 自动刷新页面的方法: 1.页面自动刷新:把如下代码加入区域中 2.页面自动跳转:把如下代码加入区域中 3.页面自动刷新js版 复制代码代码如下: //如何刷新包含该框架的页面用 //如何刷新另一个框架的页面用 如果想关闭窗口时刷新或者想开窗时刷新的话,在中调用以下语句即可。 开窗时刷新
Bootstrap、html5-boilerplate、Meteor、Semantic UI、Foundation、Materialize、Vue、Skeleton、Amaze UI、UIkit、Yui、kissy、MUI、Arale、JX、GMU、ZUI、Clouda Touch.js这些是目前比较流行的框架 目前比较流行的是:vue、react、angular 三大前端框架 前端特别流行的库很多,完全是根据不同需求来的。 前端是一个工作项目非常杂的职业岗位,以上我讲到的,只是我自己在工作中接触比较多的一些类型,其他还有很多更专业的库,例如使用D3.js进行复杂的3D图形和动画制作,随着Node.js的流行,还有更多的非浏览器平台的功能可以推广使用,甚至应用在浏览器端。 1).margin-top,margin-bottom不能正常显示时 一.有时会遇到外层中的子层使用margin-top不管用的情况;这里我们需要在子层的前后加上一个 div{height:0;overflow:hidden;} 例 CSS样式表中: #box {background-color:#eee;} #box p {margin-top: 20px;margin-bottom: 20px;text-align:center;} 解决方法:在P标签前后各加2个空的div: 二.网页中头部,中部,底部的居底部有时给个margin-bottom:10px;不管用也是要给个清除属性的.clear{clear:both;font-size:0;line-height:0;}在底部下加个 2).div层中高度自适应问题 网页前端科技人员在设计网页时不可能知道客户在要他们自己的网站内容页里加多少文字或图片内容 这时我们就不能规定div层的高度,为此应写成min-height:200px;height:auto!important;height: 200px;overflow:visible;这样ie7,ff,ie6浏览器的高度自适应问题就解决了,这些在 http://www.xueshengshu.com/网站中用到最多了。 3).div层中子层的居底部对齐问题 div中的定位问题有很多也很麻烦,但弄懂了就OK了,在一个大的div层中如何让子层的内容居底部 对齐就涉及到了position定位问题; 例 div层#box{position:relative;border:1px solidred;width:600px;hegiht:400px;} div子层#box .wrap{position:absolute;bottom:0;border:1px dashedblue;width:200px;height: 100px},最近写的网站中http://www.msgc.net.cn/就用到了 4).div层中清除clear属性的一小部分应用 在div中一个大的层里面有很多子层,若是加上边框在ie7、ie6中或许会正常显示,但是在ff中可能 只会成一条线了,此时在最外层的后面加上或者设 .wrapfix:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }后在每个浮动外框调用wrapfix;http://www.xueshengshu.com学生书网里用到最多了。 5).解决IE8下div移位、错位等兼容性问题 在标签后面的第一句话加上就OK了 6).单行文字居中与字体样式问题 在div中一个层中只有一行文字,要让这层中的文字居中,可设line-height的高度和层的高度一样,注意这一层中的文字不能换行,此外,设了line-height时再给定字体样式font:bold 14px "宋体";这时要把font:bold 14px "宋体";放在line-height的前面,否则字体样式不显示文字也不居中;或者将font:bold 14px "宋体";改成font-size:16px;font-weight:bold;font-family:"宋体";就OK了。 7).鼠标滑上去的特殊效果 往往为了达到显眼的效果,我们会写到一些好看的效果,方法一在样式表中写:ul li a{border:1px solid red;}ul li a:hoverimg{filter:alpha(opacity=40在ul标签中调用即可方法二:在样式表中写上:.hover img{filter:alpha(opacity=40);}在div中调用οnmοuseοver="this.className='hover'"οnmοuseοut="this.className=this.classtype"即可 8).IE6中高度不对问题 今天在div中给定了高度为1px,其它浏览器显示正常,可是ie6中显示的高度就不对了,这时我给样式表中加了个font-size:0px;line-height:0px;就好了 9).ul在外框里margin-top不起作用的问题 在div大框子里用了ul作导航的时候为了合ul层居中显示,设ul的样式表为margin-top:-15px不起作用了,此时应该将div大框设定高度后给个line-height与height一样的高度,ul层就自动居中了。 例如http://www.hopes-home.cn/main.aspx 10).ff中margin-top有时不起作用的问题 今天头晕脑涨的把这问题给解决了,这几天写标网都有累似问题,可是一直都是换个写法解决的,今天的这个办法也不只可行试试还是可以的,在一个div外框层中给个宽度例如,#div_wrap{width:280px;height:100%;} 其次在这个框子里设一个.div_top{widh:100%;font:bold12px "宋体";height:24px;line-height:24px;} .div_center{border:1px solid#dbdbdb;border-top:none;background:#fff;min-height:460px !important;height:auto!important;height:460px;overflow:visible;} 最后在这个div_center里套个ul li时经常会在ff中出问题,也就是在div_top与div_center中莫名的多了几个像素的空格,这时给ul样式表设个display:inline-table即可; 11).list-style-image的用法 div中经常用到新闻列表前面有图标的样式,有两种简单的方法 一.可以写成ul.menu{width:100%;} ul.menuli{background:url(em_img/small_icon.jpg) 5px center no-repeat;list-style-position:inside;padding-left:18px;}即可在各浏览器正常显示 二. 可以设ul.menu{width:80%;} ul.menuli{list-style-image:url(em_img/small_icon.jpg); } 此时新闻列表前的小图标即可在ie6,ie7,ie8,ff中都正常显示但,ie6需要不断的刷新才能正常显示小图标; 12). IE6 li:hover兼容问题
13).ie6下支持position:absolute; 最近写一个短信平台的页面用到的底部固定的层,在ff和ie7,ie8下都是好的,可到ie6下就不行了,转了整个地球终于出来了: background-attachment:fixed; } #bottomNav {background-color:#096; z-index:999; position:fixed; bottom:0; left:0;width:100%; _position:absolute; _top: expression_r(documentElement.scrollTop+ documentElement.clientHeight-this.offsetHeight); overflow:visible; } 样式表中调用即可!详细请见“高度自适应屏幕尺寸!” 14).border:none;与border:0;的区别 1.性能差异 【border:0;】把border设为“0”像素虽然在页面上看不见,但按border默认值理解,浏览器依然对border-width/border-color进行了渲染,即已经占用了内存值。 【border:none;】把border设为“none”即没有,浏览器解析“none”时将不作出渲染动作,即不会消耗内存值。 2.兼容性差异 兼容性差异只针对浏览器IE6、IE7与标签button、input而言,在win、win7、vista 的XP主题下均会出现此情况。 【border:none;】当border为“none”时似乎对IE6/7无效边框依然存在 【border:0;】当border为“0”时,感觉比“none”更有效,所有浏览器都一致把边框隐藏 总结: 1. 对比border:0;与border:none;之间的区别在于有渲染和没渲染,感觉他们和display:none;与visibility:hidden;的关系类似,而对于border属性的渲染性能对比暂时没找测试的方法,虽然认为他们存在渲染性能上的差异但也只能说是理论上。 2. 如何让border:none;实现全兼容?只需要在同一选择符上添加背景属性即可 对于border:0;与border:none;个人更向于使用,border:none;,因为border:none;毕竟在性能消耗没有争议,而且兼容性可用背景属性解决不足以成为障碍。 15).ie下。png的图片不会有灰色背景出现 注:首推PNG8,即使在IE6中它的透明背景也能被正确显示。PNG8使用的技巧是,输出时把“杂边”设置为和背景接近的颜色 1.几经周折终于把ie6下.png有色图问题解决了,原来IE6.0原本支持png8的索引色透明度,但不支持png或8位以上的alpha 透明度,在IE6.0下,非PNG8格式的透明图片部分,会显示为淡淡的灰绿色。在网页中头部加个代码即可! 2.在样式里写#png-container{ width: 300px; height: 150px; background: none; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../imgs/logoB.png',sizingMethod='crop');border:1px solid red;display:block; }到页面中调用
3. 将背景图片写成style="_filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../imgs/dialog/da_fr.png',sizingMethod='scale');background:url(../imgs/dialog/da_fr.png) no-repeat!important;_background: none transparent scroll repeat 0% 0%;);"即可。ff、ie7、ie6下都不会有灰色背景了,这个怎么又失灵了,唉害得我纠结了好几天!。 16).表格自动换行 唉,最讨厌表格了,可是编辑软件平台有很多报表要用到表格来写,搞的我郁闷半死,要想让表格里td的内容到了一定宽度自动换行就要先设一个全局样式table{table-layout:fixed;} td{word-break: break-all; word-wrap:break-word;}; 17).iframe高度自适应 给div加一个样式style="position:relative;" 再给iframe 加一个样式如下,只有把iframe定义成绝对定位后,才能自适应高度 style="position:absolute; height:100%;" 18).ie8下input的bug 我滴个孩来!一个小的两个input输入框,一个是文本框,一个是按钮,却怎么也接不到一起去,可把我给急坏了,这小问题花了我差不多一下午的时间,纠结半天终于给弄出来了,但不知原因,这么写就对了! 要定义input{ vertical-align:middle;}即可! 19).按钮的链接路径 编写网页前台时会碰到按钮的链接路径怎么给的问题!只要在button里加个οnclick="window.location.href='orderCheck.htm‘"即可!
20).图片加alt好处 网页中 中的alt是很重要的,这涉及到网页的亲和力问题(http://www.yixieshi.com/ucd/9345.html),网页中的图片若是不加alt在图片没加载出来的时候会什么信息也看不到,加了alt则在加载不出来图片的时候显示图片的信息便于用户查看信息! 21). 去除chrome浏览器下input和textarea点击选中框 取消chrome下input和textarea的聚焦边框: input,button,select,textarea{outline:none} 取消chrome下textarea可拖动放大: textarea{resize:none} 最后,写在一起,重置input和textarea的默认样式: input,button,select,textarea{outline:none} textarea{resize:none} 21).页面中流动条问题 打开一个空白页面,观察浏览器右侧,会发现IE浏览器会有一段滚动条的槽道,而Firefox浏览器下没有。 22). 手机, Adroid2.2, 平板电脑, 浏览器, mobile safari 最近给平板电脑做页面,经历了一番探索,搞定了。 下面来说说我的解决方案。 测试设备: GT-P1000 三星平板电脑(其实为大号手机) 操作系统:android2.1 浏览器:Mobile Safari/533.1 User Agent打印结果: Mozilla/5.0 (Linux; U; Android 2.1;zh-cn; GT-P1000 Build/FROYO) AppleWebKit/533 .1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 1. 在jsp页面顶上增加以下文档类型声明: Java代码 http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd"> http://www.w3.org/1999/xhtml"> 如果不加上文档类型声明的话,在浏览器里打开页面后,页面会根据移动设备屏幕的大小自动缩放页面,并且当点击输入框时,页面会自动放大,特别难看。加上声明之后,页面会展现原始大小,手指也可以拖动屏幕进行页面放大。 2. 普通的网页字体大小,在移动设备浏览器上看到的效果是字体变小 所以css的字体大小要做大一点。 我是研究了雅虎移动版的网站: http://hk.m.yahoo.com/ 23).页面中流动条问题 网页中改变input输入框的背景时,当输入的文字超过一定数字时,背景图片会跑,这时只要限定input的maxlength就行了! 24).input在google浏览器下若用背景图片写并且点击上去有效果的话会掉下来 解决的办法是将input里的value=""中加一个空格! 即写成value=" " 25).解决ff下面td的换行问题
26)巧妙clearfix解决css浮动问题 如何用clear来解决css浮动问题,应该是众多前端开发人员所关心的问题,是clear还是clearfix,其实我们最终一个目的就是让浮动产生更多的影响,最为一个前端人员,我们有必要深入研究和探讨... 万能float闭合,得知很多朋友都在使用下面的通用解决办法: 1.clear{clear:both;height:0;overflow:hidden;} 上诉办法是在需要清除浮动的地方加个div.clear或者br.clear,我们知道这样能解决基本清浮动问题。但是这种方法的最大缺陷就是改变了html结构,虽然只是加个div。 最优浮动闭合方案(这是我们推荐的): 1.clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden} 2.clearfix{*+height:1%;} 用法很简单,在浮动元素的父云素上添加class="clearfix"。你会发现这个办法也有个弊端,但的确是小问题。改变css写法就ok了: 1.clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden} 2.clearfix{*+height:1%;} 以上写法就避免了改变html结构,直接用css解决了。 很拉轰的浮动闭合办法: 1.clearfix{overflow:auto;_height:1%} 这种办法是我看国外的一篇文章得到的方案,测试了,百试不爽,真的很简单,很给力。喜欢的同学也可以试试这个办法。 这种方法是端友radom提供的,测试通过: 1.clearfix{overflow:hidden;_zoom:1;} chrome下input[type=text]的placeholder不垂直居中的问题解决 line-height: normal; line-height: 22px\9; 去掉超链接或按钮点击时的虚框线 a,a:hover,input,button{outline:none;blur:expression_r(this.onFocus=this.blur());} input:active {outline:none;}input::-moz-focus-inner{border:0px} 修改select默认的样式 select{background:none;width:400px;border:1pxsolid #d8d8d8;} option{vertical-align: middle;} 首先我们来回顾一下 2017 年新的前端技术和新的方向。微信跳一跳相信大部分的人都玩过,这个用 H5 编写的小游戏,曾经一度刷爆朋友圈,仅是这一款及其简单的小游戏,就带来了不容小觑的流量。这种状况的一个比较合理的解释是这很符合现代人的生活状态,可以用来消磨时间解解压;再者是基于简单的 H5 开发的,从技术层面来说也不是一个很难攻克的关。跳一跳火了之后,相继出现的还有悦动音符、欢乐坦克等多款微信小游戏,都有大量的用户群体。所以,在 2018 年符合现代潮流的 H5 小游戏会不会迎来它的春天?或者说,前端开发人员要不要入小游戏的坑? 说到前端,我们不得不提其三驾马车 React,Angular 和 Vue。2017年,React 继续在前端领域占据主导地位,备受期待的 React 16 也正式发布。值得关注的是 Facebook 将 React 的开源许可证由原来的 BSD+ 改成了对用户友好的 MIT,并将其 Jest、Flow、Immutable.js 和 GraphQL 等项目也更改为了 MIT 许可证。这种能减少代码重写易于重构的框架还是很受开发者欢迎的。但它是否能在 2018 年坐稳“王位”,还需不断完善整个框架的功能才是。 Angular 也不甘落后,在用户使用群体上,它排名第二。并且也在2017年发布了两个大版本,Angular 4 优化了视图引擎、减少代码体积;Angular 5 中包含了像是编译器的改进,能更快的构建/重建。基本上说Angular这个框架是比较完整的,但是对于复杂的界面开发就不是那么友好了。所以他的地位一直在遭受挑战,而框架中的黑马 Vue 大有替代之势,2017年,Vue 依然越来越受欢迎,该框架提供基于组件的架构。它已经被包括 GitLab 在内的许多大型公司采用,在 Stack Overflow 上的关注度居高不下。所以会是Vue的2018年?不要去猜测2018年学习哪个框架会更好,先打好基础的架构。 2017年前端出现的热词之一必然有PWA。PWA(Progressive Web App)是 Google 于 2016 年提出的概念,2017 年已被迅速采用。可显著提高加载速度、可离线工作、可被添加至主屏、全屏执行、推送通知消息等等。国内有不少公司实践了PWA,例如饿了么、阿里等。今年的谷歌开发者大会上也提到过这个概念。但是对于开发者而言,目前大部分的文档和资料都是以英文文档的形式存在,研究PWA的中文资料很少。但是PWA不能包含原生OS相关代码。PWA仍然是网站,只是在缓存、通知、后台功能等方面表现更好。Electron程序相当于包裹OS原生启动器(Launcher)的网站,2018年,许多Electron程序可能转化为PWA。 GraphQL 这个东西,或许在国内鲜有闻之。但是,它仍是一项不错的技术,同时在调查中,也体现出不俗的潜力。GraphQL有很多优点,不再管理多个端点并获取不必要的数据,GraphQL 允许客户端声明式地定义所需的数据,并从单个端点检索所有数据。这也证实了它在刚出现时就被认为是革命性的 API 工具。或将代替 Rest 在后端的地位。但是目前来说它的特性不是特别优秀,也会有不断的bug,可当SkyWalking在 5.0版本中采用GraphQL作为新一代接口语言后,团队成员不约而同的发出感慨--"未来已来"。那这个前端有什么联系?好好利用 GraphQL ,对于你开发前端的后端接口nodeJS有很大的帮助。 TypeScript,微软老大开发的语言,号称弥补了 JavaScript 的所有缺陷。一经问世 ,就发展迅猛,出处打着要取代JavaScript的旗号。TypeScript 由微软创建,也是新版 Angular 采用的语言,其强类型正是优势所在。 而 Flow 则提供了一种更加灵活的方式来引入类型,而不需要进行重构。语言没有好坏之分,谁取代谁是很难的,有幸看到的是两门语言的并驾齐驱吧。(部分内容来自:前端大全) 技术是不断的发展着的,前端现在也不单单是做几个页面那么简单,基础的架构以及与后端的数据交互都是学习前端需要了解的。你不仅要懂得前端发展的风向,掌握风向就掌握了第一生产力。你还要有完美的技术,让web界面每一处的运行都很通畅,让用户有更好的体验。所以说做前端也需要掌握一套完整的开发体系,眼下的 2018 年我们该如何构建一个成熟的前端开发体系?如何以最佳实践的方式进行团队开发?3.24 深圳源创会前端专场,开源中国邀请腾讯、阿里、华为大咖齐聚,为你探索H5的性能天花板,把当下流行的技术进行彻底的剖析,教你构建一个成熟的开发体系。另有各种意想不到的惊喜,还不来源创会充充电?给你一个报名链接>>>带上你所有的疑惑过来吧。 下面列出的 HTML5 的新元素,以及对它们的描述。 HTML5 提供的新元素可以构建更好的文档结构: 标签 描述 定义文档内的文章。 定义页面内容之外的内容。 定义与其他文本不同的文本方向。 定义用户可查看或隐藏的额外细节。 定义对话框或窗口。 定义 定义自包含内容,比如图示、图表、照片、代码清单等等。 定义文档或节的页脚。 定义文档或节的页眉。 定义文档的主内容。 定义重要或强调的内容。 定义用户能够从弹出菜单调用的命令/菜单项目。 定义已知范围(尺度)内的标量测量。 定义文档内的导航链接。 定义任务进度。 定义在不支持 ruby 注释的浏览器中显示什么。 定义关于字符的解释/发音(用于东亚字体)。 定义 ruby 注释(用于东亚字体)。 定义文档中的节。 定义 定义日期/时间。 定义可能的折行(line-break)。 阅读更多有关 HTML5 语义的内容。 标签 描述 定义输入控件的预定义选项。 定义键对生成器字段(用于表单)。 定义计算结果。 阅读更多有关 HTML 表单元素中新老元素。 新的输入类型 新的输入属性 学习 HTML 输入类型中的所有新老输入类型。 学习 HTML 输入属性中的所有输入属性。 HTML5 允许四种不同的属性语法。 该例演示 标签中使用的不同语法: 标签 描述 Empty disabled> Unquoted value=John> Double-quoted value="John Doe"> Single-quoted value='John Doe'> 在 HTML5 中,根据属性所需,可能会使用所有这四种语法。 标签 描述 定义使用 JavaScript 的图像绘制。 定义使用 SVG 的图像绘制。 阅读更多有关 HTML5 Canvas 的内容。 阅读更多有关 HTML5 SVG 的内容。 标签 描述 定义声音或音乐内容。 定义外部应用程序的容器(比如插件)。 定义 定义 定义视频或影片内容。 阅读更多有关 HTML5 视频的内容。 阅读更多有关 HTML5 音频的内容。 [数据结构] 数组与链表的优缺点和区别 2016年11月15日 16:25:00 阅读数:6627 数组 是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素。但是如果要在数组中增加一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样的道理,如果想删除一个元素,同样需要移动大量元素去填掉被移动的元素。如果应用需要快速访问数据,很少插入和删除元素,就应该用数组。 链表 中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起,每个结点包括两个部分:一个是存储 数据元素 的 数据域,另一个是存储下一个结点地址的 指针。 数组从栈中分配空间, 对于程序员方便快速,但自由度小。 链表从堆中分配空间, 自由度大但申请管理比较麻烦. 数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费。 链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项) 1、存取方式上,数组可以顺序存取或者随机存取,而链表只能顺序存取; 2、存储位置上,数组逻辑上相邻的元素在物理存储位置上也相邻,而链表不一定; 3、存储空间上,链表由于带有指针域,存储密度不如数组大; 4、按序号查找时,数组可以随机访问,时间复杂度为O(1),而链表不支持随机访问,平均需要O(n); 5、按值查找时,若数组无序,数组和链表时间复杂度均为O(1),但是当数组有序时,可以采用折半查找将时间复杂度降为O(logn); 6、插入和删除时,数组平均需要移动n/2个元素,而链表只需修改指针即可; 7、空间分配方面: 一、进程 进程控制块(PCB):PCB不但可以记录进程的属性信息,以便操作系统对进程进行控制和管理,而且PCB标志着进程的存在,操作系统根据系统中是否有该进程的进程控制块PCB而知道该进程存在与否。系统建立进程的同时就建立该进程的PCB,在撤销一个进程时,也就撤销其PCB,故进程的PCB对进程来说是它存在的具体的物理标志和体现。一般PCB包括以下三类信息:进程标识信息;处理器状态信息;进程控制信息。 由程序段、相关的数据段和PCB三部分构成了进程实体(又称进程印像),一般,我们把进程实体就简称为进程。 为防止进程之间彼此干扰和破坏,每个进程都拥有一个独立的地址空间和其它资源,除了共享全局变量外,不允许其它进程的访问。但是同一进程中的不同线程往往是为了提高并发性以及进行相互之间的合作而创建的,它们共享进程的内存地址空间和资源,如每个线程都可以访问它们所属进程地址空间中的所有地址,如一个线程的堆栈可以被其它线程读、写,甚至完全清除。 (5)系统开销: 由于在创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O设备等。因此,操作系统为此所付出的开销将显著地大于在创建或撤消线程时的开销。类似的,在进程切换时,涉及到整个当前进程CPU环境的保存环境的设置以及新被调度运行的CPU环境的设置,而线程切换只需保存和设置少量的寄存器的内容,并不涉及存储器管理方面的操作,可见,进程切换的开销也远大于线程切换的开销。此外,由于同一进程中的多个线程具有相同的地址空间,致使他们之间的同步和通信的实现也变得比较容易。在有的系统中,现成的切换、同步、和通信都无需操作系统内核的干预。 (6)支持多处理机系统: 作者:岳逢楽 这个问题我理解为:如何把一个Web程序的前端和后端联系起来。以下内容基于此理解进行回答。 先不考虑AJAX,从简单的说起。 前端和后端之所以需要对接,是因为前端页面只负责提供视图没有内容,而后端只提供内容,两者所谓的对接,就是把后端的内容放在前端页面预留出来的位置上。(虽然说是前端后端,但这一对接实际发生在服务器端)。 很明显其中的作者名称‘Aeolia’和发布日期‘2013-08-07’要替换掉
//从数据库获得数据,存在变量writer和date中 ?> =============================================================== package * import * public class Servlet extends HttpServlet { public void 处理GET请求的方法{ //1,从数据库获得数据,存为变量writer和date //2,把变量writer和date设置为request的属性 //3,调用要跳转的JSP页面 } } JSP文件 <% //从request里把writer和date取出来。 %> class Controller < ApplicationController def index //数据库里取article对象 //把article对象的数据respond到视图中 end end 视图文件 如果是前端做好了,那就是根据后端部分将数据填上了。 一种方式是后端程序员拿着你这个页面直接改,插入数据。这个适合一些模板类的工具例如PHP,http://ASP.NET,JSP,此外还有形式上相似的比如rhtml、django模板、Velocity等等。PHP中有一个也致力于此的库叫Smarty处理一些简单的情形还是非常不错的。 一种方式是ajax取数据,也就是让后端暴露出数据,让前端取回来填充页面。除了XML格式,json格式也比较流行。这种情况下是前端完成剩余的部分,前端和后端需要约定好数据格式的细节。 html+css、javascript、mysql、php、xml、http协议、WebService、linux系统 俗话说的好,冰冻三尺并非一日之寒。如果你能静下心来慢慢的看完我写的以下文章,会对你想要学习或者已经在学习当中的同学会起到一个比较不错的效果! 学习web前端,是一个漫长的路程,这是针对我自身的经历告诉正在看这篇文章的你。如果你现在抱有的态度是学学看或者没有一定的耐心我真诚的告诉你放弃吧!Web前端想要学习好,真的是一个漫长的过程。有的人现在有可能已经工作了,有的人有可能现在正在上学。关于我,现在已经工作了我并没有选择什么学习班或者培训班去专门的学习web前端!再说我也没有时间跟金钱投资在学习!从而极少数人会坚持下来的一条路。自学! 1,首先推荐关于已经在上班的同学时间规划做一个说明! 正常上班中午休息两个小时拿出来学习,也就是中午除掉中午吃饭半个小时完全够用,剩下的一个半小时拿出来用作学习。下午6:00下班吃饭会耽误20分钟也就是说6:20-22:00的时间是拿出来学习?不要告诉自己中午要睡觉什么的一切是借口!现在你还年轻需要那么多睡眠干嘛?以上我说的这种习惯,不要是强迫性的。我的学习进度就是这样的!粗略计算已经坚持1年8个月。如果你能,我相信你一定能成功的学会web前端,并且完全不需要花费大量的时间跟金钱! 2,针对正在上学的同学,时间真的多了!多不多你自己清楚! 首先第一步你要学会的就是html+css这也是最基础的东西,html跟css达到一个什么标准呢?只要能够做出一个简单的网站就可以了!最起码的html标签、表单、浮动、内联转块状、图片定位、有序列表、无序列表、伪类、什么是div?Div是干嘛的?最好会使用firefox bug做一些简单的调错firefox bug这个工具后期也会用到!学习Html花费不要太长时间,做多不要超过一个星期。以下是html+css的一个思维导图希望对你有用!
今天的文章就先更新到这!继续关注我的博客更新!有关自学的同学不懂得也可以在下面留言我会在第一时间回答大家的问题!或者直接在博客软文频道中查找。相关学习内容笔记!再或者都不知道怎么学的我这边也有学习的教程全是系统话的教程!是关于燕十八老师的教程!也是我正在看的!现在已经更新到了16大节课!蛮不错的教程!公益讲师!不要去淘宝买哦!有想要学习的直接跟我要就好!不需要花那一份钱!省下的钱可以自己买些书看看多好!对吧,下一篇见! 作者:知乎用户 目前以上答案似乎都只是再说闭包是个什么样子。补充一点吧。 近似正确的短答案:闭包就是一个函数把外部的那些不属于自己的对象也包含(闭合)进来了。 短答案:JavaScript中的闭包,无非就是变量解析的过程。 首先看一段话: 看个简单版的例子: (function(){ var hello="hello,world"; function welcome(hi){ alert(hi); //解析到作用域链的第一个对象的属性 alert(hello); //解析到作用域链的第二个对象的属性 } welcome("It's easy"); })(); 这里之所以可以弹出hello,world,原因就是变量解析时在welcome函数作用域链的第一个对象上找不到hello属性,然后就去第二个对象上找去了(结果还真找到了)。 所以,JavaScript中的所谓的高大上的闭包其实很简单,根本上还是变量解析。而之所以可以实现,还是因为变量解析会在作用域链中依次寻找对应属性的导致的。 js闭包真是十分十分重要的,再怎么强调也不过分,因为他是js能力提升中无法绕过的一 环,几乎每次面试必问的问题,因为在回答的时候.你的答案的深度,对术语的理解以及js内部解释器的运作方式的描述,都是可以看出你js实际水平的.即使 你没答对,也能让考官对你的水平有个评估。所以一定要掌握吃透,理解!! 要理解闭包,首先你要理解js几个很基本的特性:执行环境、作用域链、垃圾回收机制、函数嵌套。 执行环境 作用域链 垃圾回收机制 各种专业文献上的“闭包”定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数(欢迎指正)。 闭包可以用在许多地方。它的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。 举个栗子: function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 nAdd(); result(); // 1000 在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。 然而,由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。 如果看到这里还是不是很懂的话,转载了一篇很好的文章,http://www.felixwoo.com/archives/247“>这里写链接内容 一、什么是闭包? function a() { var i = 0; function b() { alert(++i); } return b; } var c = a(); c(); 这段代码有两个特点: 三、闭包内的微观世界 function f(x) { var g = function () { return x; } return g; } var h = f(1); alert(h()); 这段代码中变量h指向了f中的那个匿名函数(由g返回)。 四、闭包的应用场景 function Constructor(...) { var that = this; var membername = value; function membername(...) {...} } 以上3点是闭包最基本的应用场景,很多经典案例都源于此。 五、Javascript的垃圾回收机制 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 下面就是我的学习笔记,对于Javascript初学者应该是很有用的。 一、变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域。 变量的作用域无非就是两种:全局变量和局部变量。 Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量。 function f1(){ var n=999; } alert(n); // error 这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量! function f1(){ n=999; } f1(); alert(n); // 999 二、如何从外部读取局部变量? 出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。 那就是在函数的内部,再定义一个函数。 function f1(){ var n=999; function f2(){ alert(n); // 999 } } 在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量, 对f1就是不可见的。这就是Javascript语言特有的"链式作用域"结构(chain scope),子对象会 "一级一级" 地向上寻找所有父对象的变量。 所以,父对象的所有变量,对子对象都是可见的,反之则不成立。 既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗! function f1(){ var n=999; function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 三、闭包的概念 上一节代码中的f2函数,就是闭包。 各种专业文献上的"闭包"(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。 由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。 所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。 四、闭包的用途 闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。 怎么来理解这句话呢?请看下面的代码。 function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 nAdd(); result(); // 1000 在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。 这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。 为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1, 因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。 这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。 其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包, 所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。 五、使用闭包的注意点 1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。 解决方法是,在退出函数之前,将不使用的局部变量全部删除。 2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method), 把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。 六、思考题 如果你能理解下面两段代码的运行结果,应该就算理解闭包的运行机制了。 代码片段一。 var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){//alert(this.name);//My Object return function(){ return this.name;// 空 }; } }; alert(this.name);// The Window alert(object.getNameFunc()()); // 空 代码片段二。 var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name; }; } }; alert(object.getNameFunc()()); // My Object 一层访问一层,不能跨层访问 先来谈谈变量的作用域 局部作用域: 需要注意的是,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量! 再来看一个代码: 很有趣吧,第一个输出居然是undefined,原本以为它会访问外部的全局变量(scope=”global”),但是并没有。这可以算是javascript的一个特点,只要函数内定义了一个局部变量,函数在解析的时候都会将这个变量“提前声明”: 然而,也不能因此草率地将局部作用域定义为:用var声明的变量作用范围起止于花括号之间。 但是javascript不同,并没有所谓的块级作用域,javascript的作用域是相对函数而言的,可以称为函数作用域: 那什么是作用域链? 执行环境(execution context) 每个函数运行时都会产生一个执行环境,而这个执行环境怎么表示呢?js为每一个执行环境关联了一个变量对象。环境中定义的所有变量和函数都保存在这个对象中。 上面代码执行情况演示: 了解了环境变量,再详细讲讲作用域链。 标识符解析是沿着作用域链一级一级地搜索标识符地过程。搜索过程始终从作用域链地前端开始,然后逐级向后回溯,直到找到标识符为止(如果找不到标识符,通常会导致错误发生)—-《JavaScript高级程序设计》 那作用域链地作用仅仅只是为了搜索标识符吗? outer()内部返回了一个inner函数,当调用outer时,inner函数的作用域链就已经被初始化了(复制父函数的作用域链,再在前端插入自己的活动对象),具体如下图: 像上面这种内部函数的作用域链仍然保持着对父函数活动对象的引用,就是闭包(closure) 闭包有两个作用: 返回结果很出乎意料吧,你肯定以为依次返回0,1,但事实并非如此 那怎么才能让result数组函数返回我们所期望的值呢? 虽然的到了期望的结果,但是又有人问这算闭包吗?调用内部函数的时候,父函数的环境变量还没被销毁呢,而且result返回的是一个整型数组,而不是一个函数数组! 当调用outer,for循环内i=0时的作用域链图如下: 关于闭包经常会看到这么一道题: 《javascript高级程序设计》一书给出的解释是: this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被作为某个对象调用时,this等于那个对象。不过,匿名函数具有全局性,因此this对象同常指向window 视界云 已认证的官方帐号 110 人赞同了该回答 CDN 全称:Content Delivery Network或Content Ddistribute Network,即内容分发网络 基本思路: 尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。 目的: 解决因分布、带宽、服务器性能带来的访问延迟问题,适用于站点加速、点播、直播等场景。使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度和成功率。 控制时延无疑是现代信息科技的重要指标,CDN的意图就是尽可能的减少资源在转发、传输、链路抖动等情况下顺利保障信息的连贯性。 CDN就是扮演者护航者和加速者的角色,更快准狠的触发信息和触达每一个用户,带来更为极致的使用体验。 而且CDN这个快递员很是聪明 TA还承建了很多家快递点,就近快递(缓存) TA善于优化快递路径(调度) 基础架构:最简单的CDN网络由一个DNS服务器和几台缓存服务器组成:
服务模式: 简单地说,CDN是一个经策略性部署的整体系统,包括分布式存储、负载均衡、网络请求的重定向和内容管理4个要件,而内容管理和全局的网络流量管理(Traffic Management)是CDN的核心所在。 通过用户就近性和服务器负载的判断,CDN确保内容以一种极为高效的方式为用户的请求提供服务。 举例说明: 国内访问量较高的网站、直播、视频平台,均使用CDN网络加速技术,虽然网站的访问巨大,但无论在什么地方访问都会感觉速度很快。而一般的网站如果服务器在网通,电信用户访问很慢,如果服务器在电信,网通用户访问又很慢。 通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的cache服务器内,通过DNS负载均衡的技术,判断用户来源就近访问cache服务器取得所需的内容,解决Internet网络拥塞状况,提高用户访问网站的响应速度,如同提供了多个分布在各地的加速器,以达到快速、可冗余的为多个网站加速的目的。 CDN服务最初用于确保快速可靠地分发静态内容,这些内容可以缓存,最适合在网速庞大的网络中存储和分发,该网络在几十多个国家的十几个网络中的覆盖CDN网络服务器。由于动态内容必须通过互联网来传输,因此要提供快速的网络体验。如今的CDN可谓是大文件、小文件、点播、直播、动静皆宜!
主要特点: 1、本地Cache加速,提高了企业站点(尤其含有大量图片和静态页面站点)的访问速度,并大大提高以上性质站点的稳定性 2、镜像服务消除了不同运营商之间互联的瓶颈造成的影响,实现了跨运营商的网络加速,保证不同网络中的用户都能得到良好的访问质量。 3、远程加速 远程访问用户根据DNS负载均衡技术 智能自动选择Cache服务器,选择最快的Cache服务器,加快远程访问的速度 4、带宽优化 自动生成服务器的远程Mirror(镜像)cache服务器,远程用户访问时从cache服务器上读取数据,减少远程访问的带宽、分担网络流量、减轻原站点WEB服务器负载等功能。 5、集群抗攻击 广泛分布的CDN节点加上节点之间的智能冗余机制,可以有效地预防黑客入侵以及降低各种D.D.o.S攻击对网站的影响,同时保证较好的服务质量 。 关键技术: 内容发布:它借助于建立索引、缓存、流分裂、组播(Multicast)等技术 内容路由:它是整体性的网络负载均衡技术,通过内容路由器中的重定向(DNS)机制,在多个远程POP上均衡用户的请求,以使用户请求得到最近内容源的响应; 内容交换:它根据内容的可用性、服务器的可用性以及用户的背景,在POP的缓存服务器上,利用应用层交换、流分裂、重定向(ICP、WCCP)等技术,智能地平衡负载流量; 性能管理:它通过内部和外部监控系统,获取网络部件的状况信息,测量内容发布的端到端性能(如包丢失、延时、平均带宽、启动时间、帧速率等),保证网络处于最佳的运行状态。 适用范围:
一般来说以资讯、内容等为主的网站,具有一定访问体量的网站 例如资讯网站、政府机构网站、行业平台网站、商城等以动态内容为主的网站 例如论坛、博客、交友、SNS、网络游戏、搜索/查询、金融等。提供http下载的网站 例如软件开发商、内容服务提供商、网络游戏运行商、源码下载等有大量流媒体点播应用的网站 例如:拥有视频点播平台的电信运营商、内容服务提供商、体育频道、宽频频道、在线教育、视频博客等 1.CDN加速是对网站所在服务器加速,还是对其域名加速? CDN是只对网站的某一个具体的域名加速。如果同一个网站有多个域名,则访客访问加入CDN的域名获得加速效果,访问未加入CDN的域名,或者直接访问IP地址,则无法获得CDN效果。 2.CDN和镜像站点比较有何优势? CDN对网站的访客完全透明,不需要访客手动选择要访问的镜像站点,保证了网站对访客的友好性。 3.CDN和双线机房相比有何优势? 常见的双线机房只能解决网通和电信互相访问慢的问题,其它ISP(譬如教育网,移动网,铁通)互通的问题还是没得到解决。 4.CDN使用后,原来的网站是否需要做修改,做什么修改? 一般而言,网站无需任何修改即可使用CDN获得加速效果。只是对需要判断访客IP程序,才需要做少量修改。 5.为什么我的网站更新后,通过CDN后看到网页还是旧网页,如何解决? 由于CDN采用各节点缓存的机制,网站的静态网页和图片修改后,如果CDN缓存没有做相应更新,则看到的还是旧的网页。 6.能不能让CDN不缓存某些即时性要求很高的网页和图片? 只需要使用动态页面,asp,php,jsp等动态技术做成的页面不被CDN缓存,无需每次都要刷新。或者采用一个网站两个域名,一个启用CDN,另外一个域名不用CDN,对即时性要求高的页面和图片放在不用CDN的域名下。 7.网站新增了不少网页和图片,这些需要使用URL推送吗? 后来增加的网页和图片,不需要使用URL推送,因为它们本来就不存在缓存中。 8.网站用CDN后,有些地区反映无法访问了,怎么办? CDN启用后,访客不能访问网站有很多种可能,可能是CDN的问题,也可能是源站点出现故障或者源站点被关闭,还可能是访客自己所在的网络出现问题,甚至我们实际故障排除中,还出现过客户自己计算机中毒,导致无法访问网站。 9.哪些情况不适用于CDN?
备注:此类极端状况不建议您使用CDN服务 一个页面由两部分组成: 当 DOM 元素的属性发生变化 (如 color) 时, 浏览器会通知 render 重新描绘相应的元素, 此过程称为 repaint。 如果该次变化涉及元素布局 (如 width), 浏览器则抛弃原有属性, 重新计算并把结果传递给 render 以重新描绘页面元素, 此过程称为 reflow。 这两个过程是很耗费浏览器性能的, 从 IE 系列和 Chrome 渲染页面速度上的差距即可看出渲染引擎计算对应值和呈现并不一定高效, 而每次对元素的操作都会发生 repaints 或 reflow, 因此编写 DOM 交互时如果不注意就会导致页面性能低下. 1.解析HTML代码并生成一个 DOM 树。 2.解析CSS文件,顺序为:浏览器默认样式->自定义样式->页面内的样式。 3.生成一个渲染树(render tree)。这个渲染树和DOM树的不同之处在于,它是受样式影响的。它不包括那些不可见的节点。 4.当渲染树生成之后,浏览器就会在屏幕上“画”出所有渲染树中的节点。 不管页面发生了重绘还是重排,它们都会影响性能(最可怕的是重排 ,应尽量避免) 下列情况会发生重排 怎么减少重排?说一下我的方法: 1.分离读写操作 var curLeft=div.offsetLeft; var curTop=div.offsetTop; div.style.left=curLeft+1+'px'; div.style.top=curTop+1+'px'; 2.样式集中改变 可以添加一个类,样式都在类中改变 3.可以使用absolute脱离文档流。 4.使用 display:none ,不使用 visibility,也不要改变 它的 z-index 5.能用css3实现的就用css3实现。 如何在浏览器中查看页面渲染时间 1.打开开发者工具:点击TimeLine 左侧有个小圆点 点击刷新页面会录制整个页面加载出来 时间的分配情况。如下图 下面具体的说一下这几个过程:点击 Event Log :单独勾选Loading项会显示html 和 css 加载时间。如下图: 解析完DOM+css之后会生成一个渲染树 Render Tree,就是 dom 和 css 的一一对应关系。 DOM+css= Render Tree layout: 重排 ,又叫回流。 paint:重绘 也可以在Event Log里看的到,这里就不附图了。 重排重绘这些步骤都是在cpu中发生的。 最后 到 compostite Layers阶段,cpu 把生成的 BitMap(位图)传输到GPU,渲染到屏幕。 css3就是在GPU发生的:transform opacity。 在 GPU发生的属性比较高效。所以css3性能比较高。 小结: 渲染的三个阶段 Layout ,Paint,Composite Layers。 修改不同的css属性会触发不同阶段。 触发的阶段越前,渲染的代价越高。 浏览器重绘与重排的性能优化 2016年11月25日 21:54:30 阅读数:3152 了解了浏览器渲染原理之后 当DOM变化影响了元素的几何属性(宽、高改变等等) 如果DOM变化仅仅影响的了背景色等等非几何属性 不管页面发生了重绘还是重排,它们都会影响性能(重绘还好一些) 页面布局和元素几何属性的改变就会导致重排 不同的条件下发生重排的范围及程度会不同 举个小例子 我们修改了元素的left、top、width、height属性 但是我们现在想要修改样式后在控制台打印 千万不要写这样的代码,因为发生了4次重排 以下属性或方法会刷新渲染队列 我们在修改样式过程中,要尽量避免使用上面的属性 了解了原理我们就可以对上面的代码进行优化 这样就仅仅发生1次重排了,原因相信大家已经很清晰了 还是我们最初修改样式的代码 虽然现代浏览器有渲染队列的优化机制 这样只需要修改DOM一次一并处理 不过有一点要注意,cssText会覆盖已有的行间样式 除了cssText以外,我们还可以通过修改class类名来进行样式修改 这种办法可维护性好,还可以帮助我们免除显示性代码 我觉得缓存真是万金油,哪种性能优化都少不了它 这种读操作完就执行写操作造成了2次重排 这也相当于是分离读写操作了 现在我们想要向ul中循环添加大量li 我可以做出下面的优化 上面的方法减少重绘和重排的原理很简单 而改变元素就分别使用了隐藏元素、文档碎片和克隆元素 -->横向提权(修改个人数据);纵向提权(添加用户); XSSvsCSRF:XSS 是实现 CSRF 的诸多途径中的一条,但绝对不是唯一的一条。一般习惯上把通过 XSS 来实现的 CSRF 称为 XSRF。 例如,一论坛网站的发贴是通过 GET 请求访问,点击发贴之后 JS 把发贴内容拼接成目标 URL 并访问: http://example.com/bbs/create_post.php?title=标题&content=内容 那么,我只需要在论坛中发一帖,包含一链接: http://example.com/bbs/create_post.php?title=我是脑残&content=哈哈只要有用户点击了这个链接,那么他们的帐户就会在不知情的情况下发布了这一帖子。可能这只是个恶作剧,但是既然发贴的请求可以伪造,那么删帖、转帐、改密码、发邮件全都可以伪造。 总体来说,目前防御 CSRF 的诸多方法还没几个能彻底无解的,只能通过提高攻击门槛尽可能的防御。 针对表单比较可行的解决方案遵循三步: 1.在用户登录时,设置一个CSRF的随机token,同时种植在用户的cookie中,当用户浏览器关闭或者再次登录、退出时,清除token; 2.在表单中,生成一个隐藏域,它的值就是cookie中随机token 3.表单提交后,在web服务器端,判断表单中是token是否和用户cookie中的token一致,如果不一致或者为空,就判断为CSRF攻击。 当出现GET请求修改用户数据时,一旦在url中出现了csrftoken,当前页面就不允许出现用户定义的站外链接,否则攻击者可以诱惑用户点击攻击者定义的链接,访问在自己的网站,从refer中,获取url中的csrftoken。 作者:李上天 马三立小品〈逗你玩〉中的小偷就利用xss突破了防盗系统。 防盗系统启动: 小偷来 正常工作: 漏洞: csrf是让用户在不知情的情况,冒用其身份发起了一个请求 欢迎新用户,张三
事件委托
例如,你有一个很多行的大表格,在每个上绑定点击事件是个非常危险的想法,因为性能是个大问题。流行的做法是使用事件委托。
事件委托描述的是将事件绑定在容器元素上,然后通过判断点击的target子元素的类型来触发相应的事件。
事件委托依赖于事件冒泡,如果事件冒泡到table之前被禁用的话,那以下代码就无法工作了。
myTable.onclick = function () {
e = e || window.event;
var targetNode = e.target || e.srcElement;
// 测试如果点击的是TR就触发
if (targetNode.nodeName.toLowerCase() === 'tr') {
alert('You clicked a table row!');
}
}
事件(Event)知识整理(二)
事件流
DOM同时支持两种事件模型:捕获型事件和冒泡型事件
并且每当某一事件发生时,都会经过捕获阶段->处理阶段->冒泡阶段(有些浏览器不支持捕获)
捕获阶段是由上层元素到下层元素的顺序依次。而冒泡阶段则正相反。
如下图
当事件触发时body会先得到有事件发生的信息,然后依次往下传递,直到到达最详细的元素。这就是事件捕获阶段。
还记得事件注册方法ele.addEventListener(type,handler,flag)吧,Flag是一个Boolean值,true表示事件捕捉阶段执行,false表示事件冒泡阶段执行。
接着就是事件冒泡阶段。从下往上 依次执行事件处理函数(当然前提是当前元素为该事件注册了事件句柄)。
在这个过程中,可以阻止事件的冒泡,即停止向上的传递。
阻止冒泡有时是很有必要的,例如
本意是如果点击div中按钮以外的位置时执行funcA,点击button时执行funcB。但是实际点击button时就会先后执行funcB,funcA。
而如果在button的事件句柄中阻止冒泡的话,div就不会执行事件句柄了。组合构造
先简单介绍在JS中创建对象的方式有如下几种:
这种模式就是抽象了创建具体对象的过程,也是最基本的一种设计模式,就像下面这样咯:
2. 构造函数模式
我们创建的每个函数都 一个prototype属性,这个属性是一个指针,指向一个对象(原型对象),使用原型对象的好处是不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。就像下面这样:
所谓的原型的动态性,即随时可以为原型添加属性和方法,并且修改能够立即在所有对象实例中反映出来,像下面这样:
怎么组合呢,其实就是用构造函数模式定义实例属性(不会被共享),而用原型模式用于定义方法和共享的属性,另外这种组合模式还支持向构造函数传递参数,像下面这样:判断数组类型
2、每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array;切记,不然很难跟踪问题!
怎么区分数组和对象
判断一个变量类型是数组还是对象
var arr = [1, 2, 3];
var obj = {
name: 'lyl',
age: 18,
1: 'name'
}
console.log(arr instanceof Array); //true
console.log(obj instanceof Array); //false
var arr = [1, 2, 3];
var obj = {
name: 'lyl',
age: 18,
1: 'name'
}
console.log(arr.constructor === Array); //true
console.log(obj.constructor === Array); //false
var arr = [1, 2, 3];
var obj = {
name: 'lyl',
age: 18,
1: 'name'
}
console.log(Object.prototype.toString.call(arr) === '[object Array]'); //true
console.log(Object.prototype.toString.call(boj) === '[object Array]'); //false
var arr = [1, 2, 3];
var obj = {
name: 'lyl',
age: 18,
1: 'name'
}
console.log(arr.sort === Array.prototype.sort); //true
console.log(obj.sort === Array.prototype.sort); //false
1、objectName instanceof Array
2、objectName.constructor == Array
(
123).constructor ==
Number
// true
a)在不同 iframe 中创建的 Array 并不共享 prototype
b)即使为true,也有可能不是数组。
function SubArray(){
}
SubArray.prototype = [];
myArray = new SubArray;
alert(myArray instanceof Array)3、特性判断
b)splice
c)length不可枚举 function isArray(
object){
return
object &&
typeof
object===
'object' &&
typeof
object.length===
'number' &&
typeof
object.splice===
'function' &&
//判断length属性是否是可枚举的 对于数组 将得到false !(
object.propertyIsEnumerable(
'length'));
}
4、Array.isArray(objectName);
5、Object.prototype.toString.call(objectName)
Object.prototype.toString.call(objectName) === ‘[object Array]‘;Js数据类型
js的基本数据类型有哪些?
ECMAScript
中有5中简单数据类型(也称为基本数据类型): Undefined
、Null
、Boolean
、Number
和String
。还有1中复杂的数据类型————Object
,Object
本质上是由一组无序的名值对组成的。Undefined
、Null
、Boolean
、Number
都属于基本类型。Object
、Array
和Function
则属于引用类型,String
有些特殊,具体的会在下面展开分析。ECMAScript
中用var
关键字来定义变量,因为js
是弱类型的,所以无法确定变量一定会存储什么值,也就不知道变量到底会是什么类型,而且变量的类型可以随时改变。ECMAScript
是松散类型的来由,所谓松散类型就是可以用来保存任何类型的数据。es6
中新增了let
命令来声明变量、const
命令声明一个只读的常量。let
的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效。const
一旦声明,常量的值就不能改变。let
、const
这里不做展开讨论,可以参考 阮一峰 - ECMAScript 6 入门js
中的变量是松散类型的,所以它提供了一种检测当前变量的数据类型的方法,也就是typeof关键字.
通过typeof
关键字,对这5种数据类型会返回下面的值(以字符串形式显示)undefined
---------- 如果值未定义 Undefined
boolean
---------- 如果这个值是布尔值 Boolean
string
---------- 如果这个值是字符串 String
number
---------- 如果这个值是数值类型 Number
object
---------- 如果这个值是对象或null
Object
typeof null
返回为object
,因为特殊值null
被认为是一个空的对象引用。Undefined
类型只有一个值,即特殊的undefined
。在使用var
声明变量但未对其加以初始化时,这个变量的值就是undefined
。不过,一般建议尽量给变量初始化,但是在早期的js
版本中是没有规定undefined
这个值的,所以在有些框架中为了兼容旧版浏览器,会给window
对象添加undefined
值。window
[
'undefined']
=
window[
'undefined']
;
//或者
window
.
undefined
=
window.
undefined;
Null
类型是第二个只有一个值的数据类型,这个特殊的值是null
。从逻辑角度来看,null
值表示一个空对象指针,而这也正是使用typeof
操作符检测null
时会返回object
的原因。
var car
=
null;
console.
log(
typeof car)
;
// "object"null
而不是其他值。这样一来,只要直接检测null
值就可以知道相应的变量是否已经保存了一个对象的引用了。
例如:
if(car
!=
null)
{
//对car对象执行某些操作
}console
.
log(
undefined
==
null)
;
//true
var message
=
'Hello World';
var messageAsBoolean
=
Boolean(message)
;
var message
=
'Hello World';
if(message)
{
alert(
"Value is true")
;
}
!!一般用来将后面的表达式强制转换为布尔类型的数据(boolean),也就是只能是true或者false;var
foo
;
alert
(
!foo)
;//undifined情况下,一个感叹号返回的是true; alert
(
!goo)
;//null情况下,一个感叹号返回的也是true; var
o
={flag:true};
var
test
=!!o.
flag;//等效于var test=o.flag||false; alert
(test)
;alert
(
NaN
==
NaN)
;
//falsevar
name
=
String(
"jwy")
;alert
(
typeof name)
;//"string"var
x
=new
String(
'12345')
typeof
x
//objectx
='12345'typeof
x
//stringvar
author
=
"Tom";alert
(
typeof name)
;//"string"Es6 symbol
编码实现插入排序
Html5视频是哪个标签 video
经常会使用到伪类的是哪一个标签 a
a:link{color:#f30;}
a:visited{color:#000;}
a:hover{color:#fff;}
a:active{color:#f99;}
lvha 规则是由于CSS特殊性导致,css特殊性有一个按顺序的规则(同一条css规则,后出现会覆盖前面的同样规则)
在这里,比如把hover放在active后面,那么实际你在激活(active)链接的时候就触发了hover伪类,hover在后面覆盖了active的颜色,所以始终无法看到active的颜色
如果把visited放在hover的后面,那么已经访问过的链接始终触发visited伪类,根据第一条会覆盖hover里面的颜色。
其实 link visited 这两个伪类,并不需要顺序关系。(他们两的位置可以交换)Css3中圆角是哪个属性 boder-radius
CSS3属性之圆角效果——border-radius属性
-webkit-border-radius
-moz-border-radius
-ms-border-radius
-o-border-radius
border-radius-top-left
/*
左上角*/
border-radius-top-right
/*
右上角*/
border-radius-bottom-right
/*
右下角*/
border-radius-bottom-left
/*
左下角*/
//
提示:按顺时针方式
//HTML
清单
class="roundedCorner">
.roundedCorner{
width:100px;
height:100px;
background-color:#f90;
border-radius:10px;//
左上,右上,右下,坐下都是10px
}
//HTML清单
.roundedCorner2{
width:100px;
height:100px;
background-color:#f99;
border-radius:20px
10px
5px
2px;
}
.semi-circle{
width:100px;
height:50px;//
高度是宽度的一半
background-color:#000;
border-radius:50px
50px
0
0;//
左上和右上至少为height值
}
.circle{
width:100px;
height:100px;
background-color:#cb18f8;
border-radius:50px;
}
border-radius: 1-4 length|% / 1-4 length|%;
1-4指的是radius的四个值,length和%指的是值的单位。
.box{
border-radius: 5px
10px
20px
50px
}
.div1{border-radius: 2em/1em}
.div1{
border-radius:10px
20px
30px
40px/40px
30px
20px
10px
}
;怎么实现一个页面刷新了当前所填写的信息还在
语法:location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当前页。true, 则以 GET 方式,从服务端取最新的页面, 相当于客户端点击 F5("刷新")
语法: location.replace(URL)
document.referrer //前一个页面的URL
Javascript刷新页面的几种方法:
1 history.go(0)
2 location.reload()
3 location=location
4 location.assign(location)
5 document.execCommand('Refresh')
6 window.navigate(location)
7 location.replace(location)
8 document.URL=location.href
其中20指每隔20秒刷新一次页面.
其中20指隔20秒后跳转到http://www.jb51.net页面
JS刷新框架的脚本语句
关闭时刷新使用过哪些框架
使用过哪些库
近段时间所遇到的感觉比较困难的难题和怎么解决的
最近关注哪些技术
关闭浏览器cookie立即失效,而且只是针对于user页面失效
项目,对行业的理解
Html5新增元素
HTML5 中的新元素
新的语义/结构元素
新的表单元素
新的输入类型
HTML5 - 新的属性语法
HTML5 图像
新的媒介元素
数据结构:链表和数组的比较
概述
如果要访问链表中一个元素,需要从第一个元素开始,一直找到需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了,只要修改元素中的指针就可以了。如果应用需要经常插入和删除元素你就需要用链表。内存存储区别
逻辑结构区别
总结
数组在静态存储分配情形下,存储元素数量受限制,动态存储分配情形下,虽然存储空间可以扩充,但需要移动大量元素,导致操作效率降低,而且如果内存中没有更大块连续存储空间将导致分配失败;
链表存储的节点空间只在需要的时候申请分配,只要内存中有空间就可以分配,操作比较灵活高效;操作系统:进程和线程的描述
进程:指在系统中能独立运行并作为资源分配的基本单位,它是由一组机器指令、数据和堆栈等组成的,是一个能独立运行的活动实体。
注意,进程一般有三个状态:就绪状态、执行状态和等待状态【或称阻塞状态】;进程只能由父进程建立,系统中所有的进程形成一种进程树的层次体系;挂起命令可由进程自己和其他进程发出,但是解除挂起命令只能由其他进程发出。
进程的特征:
1.动态性:进程的实质是程序的一次执行过程,进程是动态产生,动态消亡的。
2.并发性:任何进程都可以同其他进程一起并发执行。
3.独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位。
4.异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进。
二、线程
线程:线程是进程中的一个实体,作为系统调度和分派的基本单位。Linux下的线程看作轻量级进程。
线程的性质:
1.线程是进程内的一个相对独立的可执行的单元。若把进程称为任务的话,那么线程则是应用中的一个子任务的执行。
2.由于线程是被调度的基本单元,而进程不是调度单元。所以,每个进程在创建时,至少需要同时为该进程创建一个线程。即进程中至少要有一个或一个以上的线程,否则该进程无法被调度执行。
3.进程是被分给并拥有资源的基本单元。同一进程内的多个线程共享该进程的资源,但线程并不拥有资源,只是使用他们。
4.线程是操作系统中基本调度单元,因此线程中应包含有调度所需要的必要信息,且在生命周期中有状态的变化。
5.由于共享资源【包括数据和文件】,所以线程间需要通信和同步机制,且需要时线程可以创建其他线程,但线程间不存在父子关系。
多线程使用的情形:前台和后台工作情况;异步处理工作情况;需要加快执行速度情况;组织复杂工作的情况;同时有多个用户服务请求的情况等。
线程机制的优点:
多线程运行在同一个进程的相同的地址空间内,和采用多进程相比有以下优点:
1.创建和撤销线程的开销较之进程要少。创建线程时只需要建立线程控制表相应的表目,或有关队列,而创建进程时,要创建PCB表和初始化,进入有关进程队列,建立它的地址空间和所需资源等。
2.CPU在线程之间开关时的开销远比进程要少得多。因开关线程都在同一地址空间内,只需要修改线程控制表或队列,不涉及地址空间和其他工作。
3.线程机制也增加了通讯的有效性。进程间的通讯往往要求内核的参与,以提供通讯机制和保护机制,而线程间的通讯是在同一进程的地址空间内,共享主存和文件,无需内核参与。
三、进程和线程的区别
(1)调度:
在传统的操作系统中,CPU调度和分派的基本单位是进程。而在引入线程的操作系统中,则把线程作为CPU调度和分派的基本单位,进程则作为资源拥有的基本单位,从而使传统进程的两个属性分开,线程编程轻装运行,这样可以显著地提高系统的并发性。同一进程中线程的切换不会引起进程切换,从而避免了昂贵的系统调用,但是在由一个进程中的线程切换到另一进程中的线程,依然会引起进程切换。
(2)并发性:
在引入线程的操作系统中,不仅进程之间可以并发执行,而且在一个进程中的多个线程之间也可以并发执行,因而使操作系统具有更好的并发性,从而更有效地提高系统资源和系统的吞吐量。例如,在一个为引入线程的单CPU操作系统中,若仅设置一个文件服务进程,当它由于某种原因被封锁时,便没有其他的文件服务进程来提供服务。在引入线程的操作系统中,可以在一个文件服务进程设置多个服务线程。当第一个线程等待时,文件服务进程中的第二个线程可以继续运行;当第二个线程封锁时,第三个线程可以继续执行,从而显著地提高了文件服务的质量以及系统的吞吐量。
(3)拥有资源:
不论是引入了线程的操作系统,还是传统的操作系统,进程都是拥有系统资源的一个独立单位,他可以拥有自己的资源。一般地说,线程自己不能拥有资源(也有一点必不可少的资源),但它可以访问其隶属进程的资源,亦即一个进程的代码段、数据段以及系统资源(如已打开的文件、I/O设备等),可供同一个进程的其他所有线程共享。
(4)独立性:
在同一进程中的不同线程之间的独立性要比不同进程之间的独立性低得多。这是因为
在多处理机系统中,对于传统的进程,即单线程进程,不管有多少处理机,该进程只能运行在一个处理机上。但对于多线程进程,就可以将一个进程中的多个线程分配到多个处理机上,使它们并行执行,这无疑将加速进程的完成。因此,现代处理机OS都无一例外地引入了多线程。前后台怎么链接的
链接:https://www.zhihu.com/question/21444314/answer/18245559
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
所以服务器端进行的活动如下:
接收用户请求——》找到负责处理的程序——》处理程序找到要传输给用户的前端页面——》该前端页面留出位置——》后端到数据库取数据——》后端把数据放在前端留出来的位置上——》结合成真正用户看到的html文件——》传输给用户。
(写完发现下面可以不用看了,没有办法用三言两语说清楚,最后你还是得找本书来看)
以博客中常见的输出文章的作者信息为例:
具体方法看你后台用的是什么技术:
1,后台php
把HTML文件改为php文件
2,后台JSP
Servlet文件(*代表此处有省略)
把HTML文件改为JSP文件
==============================================================
3,Ruby on Rails
controller文件
把HTML文件后面添加后缀erb,为index.html.erb,放在视图文件夹下
采用这种方式,前端做好页面后面就帮不上忙了,只能让后端去熟悉你前端的设计,让后你作为前端稍微解释一下一些细节。
这种方式的缺点是很依赖前后端的沟通,而且几乎没法实现测试驱动开发。
于是这种方式有各种变种,比如Ember.js,knockout.js,backbone.js这些工具使用的方式。很多时候需要给数据先设计一个schema,未必是前端或者后端写,可能是在项目前期约定好的,前端和后端就按照预先约定好的做正确的实现就可以了,这些库会帮你把数据在恰当的位置显示出来,并实现一些交互功能。
作者:知乎用户
链接:https://www.zhihu.com/question/21444314/answer/18249432
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。举例说明怎么学习一项技能
解释并写一个闭包,以及什么地方用得到
链接:https://www.zhihu.com/question/34547104/answer/59515735
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
每次定义一个函数,都会产生一个作用域链(scope chain)。当JavaScript寻找变量varible时(这个过程称为变量解析),总会优先在当前作用域链的第一个对象中查找属性varible ,如果找到,则直接使用这个属性;否则,继续查找下一个对象的是否存在这个属性;这个过程会持续直至找到这个属性或者最终未找到引发错误为止。
运行结果很简单,一个弹窗It's easy.一个弹窗hello,world。
分析过程如下:
对于函数welcome(),定义welcome的时候会产生一个作用域链对象,为了表示方便,记作scopechain。scopechain是个有顺序的集合对象。
每调用一个函数时(执行函数时),系统会为该函数创建一个封闭的局部的运行环境,即该函数的执行环境。函数总是在自己的执行环境中执行,如读写局部变量、 函数参数、运行内部逻辑。创建执行环境的过程包含了创建函数的作用域,函数也是在自己的作用域下执行的。从另一个角度说,每个函数执行环境都有一个作用域 链,子函数的作用域链包括它的父函数的作用域链。
简单来说,作用域链就是函数在定义的时候创建的,用于寻找使用到的变量的值的一个索引,而他内部的规则是,把函数自身的本地变量放在最前面,把自身的父级 函数中的变量放在其次,把再高一级函数中的变量放在更后面,以此类推直至全局对象为止.当函数中需要查询一个变量的值的时候,js解释器会去作用域链去查 找,从最前面的本地变量中先找,如果没有找到对应的变量,则到下一级的链上找,一旦找到了变量,则不再继续.如果找到最后也没找到需要的变量,则解释器返 回undefined。
一般来说,一个函数在执行开始的时候,会给其中定义的变量划分内存空间保存,以备后面的语句所用,等到函数执行完毕返回了,这些变量就被认为是无用的了. 对应的内存空间也就被回收了.下次再执行此函数的时候,所有的变量又回到最初的状态,重新赋值使用.但是如果这个函数内部又嵌套了另一个函数,而这个函数 是有可能在外部被调用到的.并且这个内部函数又使用了外部函数的某些变量的话.这种内存回收机制就会出现问题.如果在外部函数返回后,又直接调用了内部函 数,那么内部函数就无法读取到他所需要的外部函数中变量的值了.所以js解释器在遇到函数定义的时候,会自动把函数和他可能使用的变量(包括本地变量和父 级和祖先级函数的变量(自由变量))一起保存起来.也就是构建一个闭包,这些变量将不会被内存回收器所回收,只有当内部的函数不可能被调用以后(例如被删 除了,或者没有了指针),才会销毁这个闭包,而没有任何一个闭包引用的变量才会被下一次内存回收启动时所回收.
由于在js语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制回收。
闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
相信很少有人能直接看懂这句话,因为他描述的太学术。其实这句话通俗的来说就是:JavaScript中所有的function都是一个闭包。不过一般来说,嵌套的function所产生的闭包更为强大,也是大部分时候我们所谓的“闭包”。看下面这段代码:
1、函数b嵌套在函数a内部;
2、函数a返回函数b。
引用关系如图:
这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:
当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。
让我们说的更透彻一些。所谓“闭包”,就是在构造函数体内定义另外的函数作为目标对象的方法函数,而这个对象的方法函数反过来引用外层函数体中的临时 变量。这使得只要目标 对象在生存期内始终能保持其方法,就能间接保持原构造函数体当时用到的临时变量值。尽管最开始的构造函数调用已经结束,临时变量的名称也都消失了,但在目 标对象的方法内却始终能引用到该变量的值,而且该值只能通这种方法来访问。即使再次调用相同的构造函数,但只会生成新对象和方法,新的临时变量只是对应新 的值,和上次那次调用的是各自独立的。
二、闭包有什么作用?
简而言之,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需 要依赖a中的变量。这是对闭包作用的非常直白的描述,不专业也不严谨,但大概意思就是这样,理解闭包需要循序渐进的过程。
在上面的例子中,由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c(),i都是自加1后alert出i的值。
如果要更加深入的了解闭包以及函数a和嵌套函数b的关系,我们需要引入另外几个概念:函数的执行环境(excution context)、活动对象(call object)、作用域(scope)、作用域链(scope chain)。以函数a从定义到执行的过程为例阐述这几个概念。
当定义函数a的时候,js解释器会将函数a的作用域链(scope chain)设置为定义a时a所在的“环境”,如果a是一个全局函数,则scope chain中只有window对象。
当执行函数a的时候,a会进入相应的执行环境(excution context)。
在创建执行环境的过程中,首先会为a添加一个scope属性,即a的作用域,其值就为第1步中的scope chain。即a.scope=a的作用域链。
然后执行环境会创建一个活动对象(call object)。活动对象也是一个拥有属性的对象,但它不具有原型而且不能通过JavaScript代码直接访问。创建完活动对象后,把活动对象添加到a 的作用域链的最顶端。此时a的作用域链包含了两个对象:a的活动对象和window对象。
下一步是在活动对象上添加一个arguments属性,它保存着调用函数a时所传递的参数。
最后把所有函数a的形参和内部的函数b的引用也添加到a的活动对象上。在这一步中,完成了函数b的的定义,因此如同第3步,函数b的作用域链被设置为b所被定义的环境,即a的作用域。
到此,整个函数a从定义到执行的步骤就完成了。此时a返回函数b的引用给c,又函数b的作用域链包含了对函数a的活动对象的引用,也就是说b可以访问到a中定义的所有变量和函数。函数b被c引用,函数b又依赖函数a,因此函数a在返回后不会被GC回收。
当函数b执行的时候亦会像以上步骤一样。因此,执行时b的作用域链包含了3个对象:b的活动对象、a的活动对象和window对象,如下图所示:
如图所示,当在函数b中访问一个变量的时候,搜索顺序是:
先搜索自身的活动对象,如果存在则返回,如果不存在将继续搜索函数a的活动对象,依次查找,直到找到为止。
如果函数b存在prototype原型对象,则在查找完自身的活动对象后先查找自身的原型对象,再继续查找。这就是Javascript中的变量查找机制。
如果整个作用域链上都无法找到,则返回undefined。
小结,本段中提到了两个重要的词语:函数的定义与执行。文中提到函数的作用域是在定义函数时候就已经确定,而不是在执行的时候确定(参看步骤1和3)。用一段代码来说明这个问题:
假设函数h的作用域是在执行alert(h())确定的,那么此时h的作用域链是:h的活动对象->alert的活动对象->window对象。
假设函数h的作用域是在定义时确定的,就是说h指向的那个匿名函数在定义的时候就已经确定了作用域。那么在执行的时候,h的作用域链为:h的活动对象->f的活动对象->window对象。
如果第一种假设成立,那输出值就是undefined;如果第二种假设成立,输出值则为1。
运行结果证明了第2个假设是正确的,说明函数的作用域确实是在定义这个函数的时候就已经确定了。
保护函数内的变量安全。以最开始的例子为例,函数a中i只有函数b才能访问,而无法通过其他途径访问到,因此保护了i的安全性。
在内存中维持一个变量。依然如前例,由于闭包,函数a中i的一直存在于内存中,因此每次执行c(),都会给i自加1。
通过保护变量的安全实现JS私有属性和私有方法(不能被外部访问)
私有属性和方法在Constructor外是无法被访问的
在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。作用域
作用域链
作用域
变量的作用域无非就是两种:全局变量和局部变量。
全局作用域:
最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的: var outerVar = "outer";
function fn(){
console.log(outerVar);
}
fn();//result:outer
和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,最常见的例如函数内部 function fn(){
var innerVar = "inner";
}
fn();
console.log(innerVar);// ReferenceError: innerVar is not defined
<script> function fn(){
innerVar = "inner";
}
fn();
console.log(innerVar);// result:inner
<script> var scope = "global";
function fn(){
console.log(scope);//result:undefined
var scope = "local";
console.log(scope);//result:local;
}
fn();
<script> var scope = "global";
function fn(){
var scope;//提前声明了局部变量
console.log(scope);//result:undefined
scope = "local";
console.log(scope);//result:local;
}
fn();
javascript并没有块级作用域
那什么是块级作用域?
像在C/C++中,花括号内中的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的,比如下面的c语言代码:for
(
int i =
0; i <
10; i++){
//i
的作用范围只在这个
for循环
}
printf
(
"%d",&i);
//error
<script> for(var i = 1; i < 10; i++){
//coding
}
console.log(i); //10
作用域链(Scope Chain)
我的理解就是,根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问。
想要知道js怎么链式查找,就得先了解js的执行环境
全局执行环境是最外围的执行环境,全局执行环境被认为是window对象,因此所有的全局变量和函数都作为window对象的属性和方法创建的。
js的执行顺序是根据函数的调用来决定的,当一个函数被调用时,该函数环境的变量对象就被压入一个环境栈中。而在函数执行之后,栈将该函数的变量对象弹出,把控制权交给之前的执行环境变量对象。
举个例子:
<script> var scope = "global";
function fn1(){
return scope;
}
function fn2(){
return scope;
}
fn1();
fn2();
当某个函数第一次被调用时,就会创建一个执行环境(execution context)以及相应的作用域链,并把作用域链赋值给一个特殊的内部属性([scope])。然后使用this,arguments(arguments在全局环境中不存在)和其他命名参数的值来初始化函数的活动对象(activation object)。当前执行环境的变量对象始终在作用域链的第0位。
以上面的代码为例,当第一次调用fn1()时的作用域链如下图所示:
(因为fn2()还没有被调用,所以没有fn2的执行环境)
可以看到fn1活动对象里并没有scope变量,于是沿着作用域链(scope chain)向后寻找,结果在全局变量对象里找到了scope,所以就返回全局变量对象里的scope值。
再来看一段代码:
<script> function outer(){
var scope = "outer";
function inner(){
return scope;
}
return inner;
}
var fn = outer();
fn();
一般来说,当某个环境中的所有代码执行完毕后,该环境被销毁(弹出环境栈),保存在其中的所有变量和函数也随之销毁(全局执行环境变量直到应用程序退出,如网页关闭才会被销毁)
但是像上面那种有内部函数的又有所不同,当outer()函数执行结束,执行环境被销毁,但是其关联的活动对象并没有随之销毁,而是一直存在于内存中,因为该活动对象被其内部函数的作用域链所引用。
具体如下图:
outer执行结束,内部函数开始被调用
outer执行环境等待被回收,outer的作用域链对全局变量对象和outer的活动对象引用都断了 闭包
第一个就是可以读取自身函数外部的变量(沿着作用域链寻找)
第二个就是让这些外部变量始终保存在内存中
关于第二点,来看一下以下的代码:
<script> function outer(){
var result = new Array();
for(var i = 0; i < 2; i++){//注:i是outer()的局部变量
result[i] = function(){
return i;
}
}
return result;//返回一个函数对象数组
//这个时候会初始化result.length个关于内部函数的作用域链
}
var fn = outer();
console.log(fn[0]());//result:2
console.log(fn[1]());//result:2
来看一下调用fn[0]()
的作用域链图:
可以看到result[0]函数的活动对象里并没有定义i这个变量,于是沿着作用域链去找i变量,结果在父函数outer的活动对象里找到变量i(值为2),而这个变量i是父函数执行结束后将最终值保存在内存里的结果。
由此也可以得出,js函数内的变量值不是在编译的时候就确定的,而是等在运行时期再去寻找的。
看一下result的活动对象里有一个arguments,arguments对象是一个参数的集合,是用来保存对象的。
那么我们就可以把i当成参数传进去,这样一调用函数生成的活动对象内的arguments就有当前i的副本。
改进之后:
<script> function outer(){
var result = new Array();
for(var i = 0; i < 2; i++){
//定义一个带参函数
function arg(num){
return num;
}
//把i当成参数传进去
result[i] = arg(i);
}
return result;
}
var fn = outer();
console.log(fn[0]);//result:0
console.log(fn[1]);//result:1
确实如此,那就让arg(num)函数内部再定义一个内部函数就好了:
这样result返回的其实是innerarg()函数
<script> function outer(){
var result = new Array();
for(var i = 0; i < 2; i++){
//定义一个带参函数
function arg(num){
function innerarg(){
return num;
}
return innerarg;
}
//把i当成参数传进去
result[i] = arg(i);
}
return result;
}
var fn = outer();
console.log(fn[0]());
console.log(fn[1]());
由上图可知,当调用innerarg()时,它会沿作用域链找到父函数arg()活动对象里的arguments参数num=0.
上面代码中,函数arg在outer函数内预先被调用执行了,对于这种方法,js有一种简洁的写法
function outer(){
var result =
new
Array();
for(
var i =
0; i <
2; i++){
//定义一个带参函数 result[i] =
function(num){
function innerarg(){
return num;
}
return innerarg;
}(i);
//预先执行函数写法
//把i当成参数传进去 }
return result;
}
关于this对象
var name =
"The Window";
var object = {
name :
"My Object",
getNameFunc :
function(){
return
function(){
return
this.name;
};
}
};
alert(object.getNameFunc()());
//result:The WindowCdn
再通俗点说就是在网速一定的前提下,CDN就像网络中快递员小哥
TA不是在用蛮力瞎跑、乱撞
还会对包裹进行更合理的重新打包(协议优化)
Q & A
CDN对每个节点都有可用性检查,不合格的节点会第一时间剔出,从而保证了极高的可用率,而镜像站点无法实现这一点。
CDN部署简单,对原站基本不做任何改动即可生效。
而CDN是访问者就近取数据,而CDN的节点遍布各ISP,从而保证了网站到任意ISP的访问速度。另外CDN因为其流量分流到各节点的原理,天然获得抵抗网络攻击的能力。
为了解决这个问题,CDN管理面板中提供了URL推送服务,来通知CDN各节点刷新自己的缓存。
在URL推送地址栏中,输入具体的网址或者图片地址,则各节点中的缓存内容即被统一删除,并且当即生效。
如果需要推送的网址和图片太多,可以选择目录推送,输入 http://www.kkk.com/news 即可以对网站下news目录下所有网页和图片进行了刷新。
客户报告故障时,可随时联系我们24小时技术部进行处理。重绘和重排,以及怎么解决
DOM:描述该页面的结构
render:描述 DOM 节点 (nodes) 在页面上如何呈现
页面渲染的过程如下:
我们知道了浏览器听过渲染树计算布局后,就开始绘制页面元素
但是渲染树并不是一成不变的,在我们的脚本当中
它是可能改变的重绘与重排
浏览器此时需要重新计算元素几何属性
并且页面中其他元素的几何属性可能会受影响
这样渲染树就发生了改变,也就是重新构造RenderTree渲染树
这个过程叫做重排(reflow)
此时就发生了重绘(repaint)而不是重排
因为布局没有发生改变
能避免要尽量避免触发重排
下列情况会发生重排
某些情况甚至会重排整个页面,比如滑动滚动条浏览器的优化:渲染队列
比如我们想用js中修改一个div元素的样式
写下了以下代码div.style.left
= '10
px';
div.style.top
= '10
px';
div.style.width
= '20
px';
div.style.height
= '20
px';
满足我们发生重排的条件
理论上会发生4次重排
但是实际上只会发生1次重排
这是因为我们现代的浏览器都有渲染队列的机制
当我改变了元素的一个样式会导致浏览器发生重排或重绘时
它会进入一个渲染队列
然后浏览器继续往下看,如果下面还有样式修改
那么同样入队
直到下面没有样式修改
浏览器会按照渲染队列批量执行来优化重排过程,一并修改样式
这样就把本该4次的重排优化为1次
div.style.left
= '10
px';
console.log
(
div.offsetLeft);
div.style.top
= '10
px';
console.log
(
div.offsetTop);
div.style.width
= '20
px';
console.log
(
div.offsetWidth);
div.style.height
= '20
px';
console.log
(
div.offsetHeight);
有同学可能不懂了,不是说浏览器有渲染队列优化机制吗?
为什么这样写就会发生4次重排
因为offsetLeft/Top/Width/Height非常叼
它们会强制刷新队列要求样式修改任务立刻执行
想一想其实这么做是有道理的
毕竟浏览器不确定在接下来的代码中你是否还会修改同样的样式
为了保证获得正确的值,它不得不立刻执行渲染队列触发重排(错的不是我,是这个世界)
重绘与重排的性能优化
分离读写操作
div
.style.left =
'10px';
div
.style.top =
'10px';
div
.style.width =
'20px';
div
.style.height =
'20px';
console.log(
div.offsetLeft);
console.log(
div.offsetTop);
console.log(
div.offsetWidth);
console.log(
div.offsetHeight);
把所有的读操作移到所有写操作之后
效率高多了
这是其中一种优化的方法样式集中改变
div
.style.left =
'10px';
div
.style.top =
'10px';
div
.style.width =
'20px';
div
.style.height =
'20px';
但是古董浏览器效率仍然底下,触发了4次重排
即便这样,我们仍然可以做出优化
我们需要cssText属性合并所有样式改变div
.style.cssText =
'left:10px;top:10px;width:20px;height:20px;';
仅仅触发了1次重排
而且只用了一行代码,看起来相对干净一些
如果想保留原有行间样式,这样做div
.style.cssText +=
';left:10px;';
div.className = '
new-
class';
(有一点点性能影响,改变class需要检查级联样式,不过瑕不掩瑜)缓存布局信息
div
.style.left =
div.offsetLeft +
1 +
'px';
div
.style.top =
div.offsetTop +
1 +
'px';
缓存可以进行优化var
curLeft =
div.offsetLeft;
var
curTop =
div.offsetTop;
div
.style.left = curLeft +
1 +
'px';
div
.style.top = curTop +
1 +
'px';
优化为1次重排元素批量修改
(如果ul还不存在,最好的办法是先循环添加li到ul,然后再把ul添加到文档,1次重排)var
ul =
document.getElementById(
'demo');
for
(
var i =
0; i <
1e5; i++){
var li =
document.createElement(
'li');
var text =
document.createTextNode(i);
li.appendChild(text);
ul.appendChild(li);
}
var
ul =
document.getElementById(
'demo');
ul.style.display =
'none'; <--
for
(
var i =
0; i <
1e5; i++){
var li =
document.createElement(
'li');
var text =
document.createTextNode(i);
li.appendChild(text);
ul.appendChild(li);
}
ul.style.display =
'block'; <--
var
ul =
document.getElementById(
'demo');
var
frg =
document.createDocumentFragment(); <--
for
(
var i =
0; i <
1e5; i++){
var li =
document.createElement(
'li');
var text =
document.createTextNode(i);
li.appendChild(text);
frg.appendChild(li); <--
}
ul.appendChild(frg); <--
var
ul = document.getElementById(
'demo');
var
clone = ul.cloneNode(
true); <--
for
(
var i =
0; i <
1e5; i++){
var li = document.createElement(
'li');
var text = document.createTextNode(i);
li.appendChild(text);
clone.appendChild(li); <--
}
ul.parentNode.replaceChild(
clone,ul); <--
上面的方法我认为仅仅是理论上可以优化重排重绘次数
现代浏览器的优化可能会超过我们的想象Xss和csrf
XSS:跨站脚本攻击,注入攻击的一种。攻击者利用应用程序的动态展示功能,在HTML页面中嵌入恶意代码。当用户浏览该页时,这些嵌入在html的恶意代码就会被执行,用户浏览器被攻击者控制。。。。
1.盗取用户cookie,伪造用户身份
2.控制用户浏览器
3.结合浏览器及其插件漏洞,下载病毒木马到浏览者的计算机运行
4.衍生URL跳转漏洞
5.官网挂钓鱼网站
6.蠕虫攻击
CSRF:跨站请求伪造(冒充用户之手,伪造请求)。
严格意义上来说,CSRF 不能分类为注入攻击,因为 CSRF 的实现途径远远不止 XSS 注入这一条。通过 XSS 来实现 CSRF 易如反掌,但对于设计不佳的网站,一条正常的链接都能造成 CSRF。
链接:https://www.zhihu.com/question/34445731/answer/86381916
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
妈妈:给我看着衣服
小孩:好的
小孩:你是谁?
小偷:我叫张三
小孩:妈妈,有人偷衣服
妈妈:谁?
小孩:张三
小偷被捉
小孩:你是谁?
小偷:我叫逗你玩
小孩:妈妈,有人偷衣服
妈妈:谁?
小孩:逗你玩
妈妈:。。。
小偷:你妈妈喊你去买洗衣粉
----------------------------------------------
补充一下,XSS本质是Html注入,和SQL注入差不多。
SQL、Html、人类语言都是指令和数据混在一起,都存在注入风险(程序根据分隔符、标签识别指令和数据,人类则是根据语境、语义和日常经验判断)。
比如注册用户时,用户输入“张三”并提交,服务端会生成“ 你可能感兴趣的:(综合一)