-
Notifications
You must be signed in to change notification settings - Fork 0
/
content.json
1 lines (1 loc) · 288 KB
/
content.json
1
[{"title":"博客转移Vuepress","date":"2020-01-05T12:05:01.000Z","path":"2020/01/05/博客改为使用Vuepress/","text":"这个博客运行大概有4年了吧,但其实自己也没怎么认真去打理,可能是因为没有什么访问量吧,目前发现很多文档其实都用了Vuepress,自己也打算练练手,着手换到Vuepress上。","comments":true,"tags":[{"name":"随笔","slug":"随笔","permalink":"https://guohui8.github.io/tags/随笔/"}]},{"title":"es6模块与 commonJS规范的区别","date":"2017-10-01T12:05:01.000Z","path":"2017/10/01/es6模块与 commonJS规范的区别/","text":"es6 { export : ‘可以输出多个,输出方式为 {}’ , export default : ‘ 只能输出一个 ,可以与export 同时输出,但是不建议这么做’, 解析阶段确定对外输出的接口,解析阶段生成接口, 模块不是对象,加载的不是对象, 可以单独加载其中的某个接口(方法), 静态分析,动态引用,输出的是值的引用,值改变,引用也改变,即原来模块中的值改变则该加载的值也改变, this 指向undefined } commonJS { module.exports = … : ‘只能输出一个,且后面的会覆盖上面的’ , exports. … : ‘ 可以输出多个’, 运行阶段确定接口,运行时才会加载模块, 模块是对象,加载的是该对象, 加载的是整个模块,即将所有的接口全部加载进来, 输出是值的拷贝,即原来模块中的值改变不会影响已经加载的该值, this 指向当前模块 }","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"vuex学习实践笔记","date":"2017-06-19T12:05:01.000Z","path":"2017/06/19/vuex学习实践笔记/","text":"Vuex是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 栗如(travel store): 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667import * as types from '../types'//数据const state = { travelsList: [], searchKey: { page: 0, limit: 20 }, scroll: true}//用户行为(可以处理异步),触发 mutations 来改变 stateconst actions = { /** * 获取约跑步列表 */ getTravelsList({ commit }) { if(state.scroll) { commit(types.GET_TRAVELS_PAGE_NUM) commit(types.COM_LOADING_STATUS, true), commit(types.GET_TRAVELS_SCORLL_STATUS, false) api.TravelsList() .then(res => { console.log(res) commit(types.COM_LOADING_STATUS, false), commit(types.GET_TRAVELS_SCORLL_STATUS, true) commit(types.GET_TRAVELS_LIST, res) }) } }, /** * 参加 */ joinTravel({ commit }, id) { ... }}//可以过滤 state 中的数据const getters = { travelsList: state => state.travelsList, travelListIndex: state => state.travelsList.slice(0,4)}//唯一能改变 state 的方法(纯函数)const mutations = { [types.GET_TRAVELS_LIST](state, res) { if(state.searchKey.page <= 1) { state.travelsList = res.data } else { state.travelsList = state.travelsList.concat(res.data) } }, [types.GET_TRAVELS_SEARCH_KEY](state, params) { state.searchKey = params }, [types.GET_TRAVELS_PAGE_NUM](state) { state.searchKey['page'] += 1 }, [types.GET_TRAVELS_SCORLL_STATUS](state, status) { state.scroll = status }}//导出一个 travel store 模块export default { state, actions, getters, mutations} 每一个 Vuex 应用的核心就是 store(仓库)。”store” 基本上就是一个容器,它包含着你的应用中大部分的状态(state)数据。 Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交(commit) mutations。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。 用一张图来理解一下 客户端(Client) -> action -> mutations -> state -> 客户端 可以看出在vuex中数据是单一流向的:视图(view)触发action,action提交(commit)到mutations,mutations改变state(数据),state的改变,相应的组件也会相应的更新。 1.State 单一状态树,唯一数据源,能够直接清晰的读懂数据的结构。 1.1在 Vue 组件中获得数据123456789101112131415//storeconst state = { travelsList: [], searchKey: { page: 0, limit: 20 }, scroll: true}//在view中直接获取data () { return { scroll: this.$store.state.scroll }}, 1.2mapState 辅助函数12345678910computed: mapState([ // 映射 this.scroll 为 this.$store.state.scroll 'scroll'])//或对象展开运算符computed: { ...mapState({ 'scroll' })} 2.Getters 对state数据进行过滤或直接返回 2.1在 Vue 组件中获得Getters数据1234567891011//storeconst getters = { travelsList: state => state.travelsList, travelListIndex: state => state.travelsList.slice(0,4)}//在view中直接获取data () { return { travelListIndex: this.$store.getters.travelListIndex }}, 2.2mapGetters 辅助函数12345678910computed: mapGetters([ // 映射 this.travelListIndex 为 this.$store.state.travelListIndex 'travelListIndex'])//或对象展开运算符computed: { ...mapGetters({ 'travelListIndex' })} 3.Mutations 要更改 Vuex 的 store 中的数据,唯一方法是提交 mutation。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行数据更改的地方。 1234567891011const mutations = { //使用常量替代 Mutation 事件类型 [types.GET_TRAVELS_LIST](state, res) { if(state.searchKey.page <= 1) { state.travelsList = res.data } else { state.travelsList = state.travelsList.concat(res.data) } }, ...} 当我们在这改变数据时,其它引用此state数据的 Vue 组件也会自动得到更新。 4.Actions 用户的一些行为,来提交到mutations改变数据。可在这进行异步操作。 1234567891011121314151617181920const actions = { //es6的参数解构 getTravelsList({ commit }) { if(state.scroll) { commit(types.GET_TRAVELS_PAGE_NUM) commit(types.COM_LOADING_STATUS, true), commit(types.GET_TRAVELS_SCORLL_STATUS, false) api.TravelsList() .then(res => { console.log(res) commit(types.COM_LOADING_STATUS, false), commit(types.GET_TRAVELS_SCORLL_STATUS, true) commit(types.GET_TRAVELS_LIST, res) }) } }, joinTravel({ commit }, id) { ... }} 4.1分发 Action12345created() { if (this.travelListIndex.length == 0) { this.$store.dispatch('getTravelsList') }}, 4.2mapActions 辅助函数12345methods: { ...mapActions([ 'getTravelsList' // 映射 this.getTravelsList() 为 this.$store.dispatch('getTravelsList') ]),} 5.Modules 当应用变得很大时,store 对象会变得臃肿不堪。为了解决这个问题,Vuex 允许我们将 store 分割到模块(module)。每个模块拥有自己的 state、mutation、action、getters 12345678910111213141516171819const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... }}const moduleB = { state: { ... }, mutations: { ... }, actions: { ... }}const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB }})store.state.a // -> moduleA 的状态store.state.b // -> moduleB 的状态","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"跟大师学摄影","date":"2017-05-02T12:05:01.000Z","path":"2017/05/02/跟大师学摄影/","text":"","comments":true,"tags":[{"name":"相册","slug":"相册","permalink":"https://guohui8.github.io/tags/相册/"}]},{"title":"时光里,我们都是赶路人","date":"2017-04-03T12:05:01.000Z","path":"2017/04/03/时光里,我们都是赶路人/","text":"慢慢觉着时光开始沉淀了,如一抹繁华的艳阳,从夏日旁晚清凉的池塘中滑落,悄然走进了秋日的诗行。彼处,依旧是微风不燥,岁月静好。万里黄沙之上,依旧有人沉腕拨镫,疾书一行字:“相忘于江湖”。其实在光阴里,我们都是赶路人,终归有一天日子将会过得如烟火湮灭那般平静且丰盈。正如微风,拂过草地上的清露,在林间流动之际,那些路边的小花儿开也不再张扬。 素白的光阴里,短暂的相遇邂逅,我们转身便策马扬鞭,奔向远方。而在时光荏苒里随心事渐渐寂寞的日子里,谁又繁华了悲伤,疼痛了幸福。最后,又是谁背负着沉重的枷锁,固守仅存的坚持,明知无望却忍着寂寥划过了逆流的哀痛,终于嗅到了春。 曾经,我们都不停奔赴着自己最美的风景,却一直在放弃。暮然回首之际,夜幕却依旧如期降临,举目四望,偌大的桌边只我一人,空对,一盏冰冷的茶。才明白那些曾相伴走过一遭的人,那些当初索然无味的问候,那些毫无方向的旅途,那些种种过往的云烟,原来才是这世间的所有懂得的馈赠,也许只有光阴知道,桃之夭夭灼灼其华的默契,日久弥深,却又宛如初见,忽尔盛开,。 每每念起沈园遗梦,心中倍感凄凉。时常做想悠游放荡如陆游在遇上唐婉那一刹间,眼帘中饱含是情、是怨、是思、还是怜。如若是我,定会上前一步,浅浅微笑,谢谢你给了我这一段清浅的韶光,愿你别空负了我的流年。","comments":true,"tags":[{"name":"随笔","slug":"随笔","permalink":"https://guohui8.github.io/tags/随笔/"}]},{"title":"webpack工程化","date":"2017-03-26T12:05:01.000Z","path":"2017/03/26/webpack工程化/","text":"一、webpack是什么 webpack is a module bundler. webpack takes modules with dependencies and generates static assets representing those modules webpack 是一个模块打包工具,输入为包含依赖关系的模块集,输出为打包合并的前端静态资源。在上一节的前端工程化中,已经介绍过,webpack 是同时支持 AMD 和 CommonJs 的模块定义方式,不仅如此,webpack 可以将任何前端资源视为模块,如 css,图片,文本。 二、为什么要使用它在 webpack 出现之前,已经有了一些打包工具,如 Browserify、grunt、gulp… 这些打包工具工具功能单一,只能完成特定的任务,然而 web 前端工程是复杂的,一个 webapp 对于业务代码的要求可能有: 代码可以分块,实现按需加载 首屏加载时间要尽量减少 需要集成一些第三方库 webpack 的出现正式为了解决这些问题,在 webpack 中,提供了一下这些功能: 1.代码分块: webpack 有两种类型的模块依赖,一种是同步的,一种是异步的。在打包的过程中可以将代码输出为代码块(chunk),代码块可以实现按需加载。 异步加载的代码块通过分割点(spliting point)来确定。2.Loaders: Webpack 本身只会处理 Javascript,为了实现将其他资源也定义为模块,并转化为 Javascript, Webpack 定义 loaders , 不同的 loader 可以将对应的资源转化为 Javascript 模块。3.智能的模块解析: webpack 可以很容易将第三方库转化为模块集成到项目代码中,模块的依赖可以用表达式的方式(这在其他打包工具中是没有支持的),这种模块依赖叫做动态模块依赖。4.插件系统: webpack 的可定制化在于其插件系统,其本身的很多功能也是通过插件的方式实现,插件系统形成了 webpack 的生态,是的可以使用很多开源的第三方插件。 三、webpack 核心思想1.万物皆模块: 在 webpack 的世界中,除了 Javascript,其他任何资源都可以当做模块的方式引用。2.按需加载: webapp 的优化关键在于代码体积,当应用体积增大,实现代码的按需加载是毕需,这也是 webpack 出现的根本原因。3.可定制化: 任何一个工具都不可能解决所有问题,提供解决方案才是最可行的,webpack 基于可定制化的理念构建,通过插件系统,配置文件,可以实现大型项目的定制需求。 四、安装配置在此之前你应该已经安装了 node.js. 全局安装webapck或webpack-dev-server(开启一个本地服务) 12$ npm install webpack -g$ npm install webpack-dev-server -g 在项目中安装webpack和webpack-dev-server 12$ npm install webpack --save-dev$ npm install webpack-dev-server --save-dev webpack使用 1234567//name.jslet name = 'hzzly'export default name//index.jsimport name from './name'document.getElementById('app').textContent = `hello~${name}` 1.命令行的使用 1$ webpack src/index.js dist/bundle.js 语法:webpack 要打包的文件 打包输出的文件 2.配置文件的使用在项目目录下创建 webpack.config.js如下(简单的配置): 12345678910111213141516171819202122232425262728var webpack = require('webpack')module.exports = { entry: './src/index.js', //入口 output: { path: './dist/', //输出路径 filename: 'bundle.js' //输出文件名 }, module: { loaders: [ { test: /\\.js[x]?$/, exclude: /node_modules/, loader: 'babel-loader', //处理.js或.jsx文件loader query: { presets: ['env'] } }, { test: /\\.css$/, loader: "style-loader!css-loader" //处理.css文件loader }, { test: /\\.(png|jpg)$/, loader: 'url-loader?limit=8192' //处理图片loader } ] }} 执行: 123$ webpack//或开启本地服务器并实时监听文件变化$ webpack-dev-server --inline --colors --hot","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Promise的那些事","date":"2017-03-15T12:05:01.000Z","path":"2017/03/15/Promise的那些事/","text":"说说promise Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。 所谓Promise,简单说就是一个容器(对象),里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。 接触过promise的的都知道它的应用场景和用途,Promise可以用来避免异步操作函数里的嵌套回调(callback hell)问题,因为解决异步最直接的方法是回调嵌套,将后一个的操作放在前一个操作的异步回调里,但如果操作多了,就会有很多层的嵌套(回调地狱)。 12345678910$.ajax(url1, function(data1){ // do something... $.ajax(url2, function(data2){ // do something... $.ajax(url3, function(data3){ // do something... done(data3); // 返回数据 }) });}); Promise学术点的描述: promise代表一个异步操作的执行返回状态,这个执行返回状态在promise对象创建时未必已知。它允许你为异步操作的成功或失败指定处理方法。 这使得异步方法可以像同步方法那样返回值:异步方法会返回一个包含了原返回状态的 promise 对象来替代原返回状态。 Promise的表现如果使用回调方法处理多个操作的异步场景,判断某个操作成功或失败的控制在于声明的匿名函数里面,使用Promise对象则可以重新定义异步执行的状态和控制逻辑。 promise的最重要的特点就是它把我们处理任何函数调用的成功或者失败的方式规范成了可预测的形式,特别是如果这个调用实际上的异步的。 Promise中有几个状态: pending: 初始状态。 非 fulfilled 或 rejected。 resolved: 成功的操作。也有的成为fulfilled 。 rejected: 失败的操作。 状态转换关系为: pending->resolved(fulfilled),pending->rejected。 Promise对象有以下两个特点: 对象的状态不受外界影响,Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败) 一旦状态改变,就不会再变,任何时候都可以得到这个结果。 用法说了这么多,直接上代码。 123456789101112131415var promise = new Promise((resolve, reject) => { // do somthing, maybe async if (success){ return resolve(res); } else { return reject(err); }}); promise.then(res => { // do something... e.g console.log(res);}, err => { // deal the err.}) 或封装成方法 1234567891011121314151617function fetch(data) { return new Promise((resolve, reject) => { // do somthing, maybe async if (success){ resolve(res); } else { reject(err); } })} fetch(data) .then(res => { console.log(res) }, err => { // deal the err. }) 异步嵌套回调123456789101112131415161718192021222324252627function loadAsync1(){ return new Promise((resolve, reject) => { //异步操作 setTimeout(() => { console.log('异步任务1'); resolve('异步任务1传过来的值'); }, 2000); }); }function loadAsync2(data1){ return new Promise((resolve, reject) => { //异步操作 setTimeout(() => { console.log('异步任务2'); resolve('异步任务2传过来的值'); }, 2000); }); }function loadAsync3(data2){ return new Promise((resolve, reject) => { //异步操作 setTimeout(() => { console.log('异步任务3'); resolve('异步任务3传过来的值'); }, 2000); }); } 有返回值 12345678loadAsync1() .then(data1 => { return loadAsync2(data1) }) .then(data2 => { return loadAsync3(data2) }) .then(okFn, failFn) 没有返回值 12345678loadAsync1() .then(data1 => { loadAsync2(data1) }) .then(data2 =>{ loadAsync3(data2) }) .then(res => console.log(res)) 输出的值为: 异步任务1异步任务1传过来的值异步任务2异步任务2传过来的值异步任务3异步任务3传过来的值 promise.all方法 Promise.all 可以接收一个元素为 Promise 对象的数组作为参数,当这个数组里面所有的 Promise 对象都变为 resolve 时,该方法才会返回。 12345678910111213141516var p1 = new Promise((resolve) => { setTimeout(() => { resolve("第一个promise"); }, 3000);}); var p2 = new Promise((resolve) => { setTimeout(() => { resolve("第二个promise"); }, 1000);}); Promise.all([p1, p2]) .then((result) => { console.log(result); // ["第一个promise", "第二个promise"] }); 上面的代码中,all接收一个数组作为参数,p1,p2是并行执行的,等两个都执行完了,才会进入到then,all会把所有的结果放到一个数组中返回,所以我们打印出我们的结果为一个数组。 值得注意的是,虽然p2的执行顺序比p1快,但是all会按照参数里面的数组顺序来返回结果。all的使用场景类似于,玩游戏的时候,需要提前将游戏需要的资源提前准备好,才进行页面的初始化。 promise.race方法 Promise.race 可以接收一个元素为 Promise 对象的数组作为参数,这个数组里面所有的 Promise 对象进行竞速,完成一个即可。 12345678910111213141516171819202122var p1 = new Promise((resolve) => { setTimeout(() => { console.log('异步任务1执行完成'); resolve("第一个promise"); }, 3000);}); var p2 = new Promise((resolve) => { setTimeout(() => { console.log('异步任务2执行完成'); resolve("第二个promise"); }, 1000);}); Promise.race([p1, p2]) .then((result) => { console.log(result); });//异步任务2执行完成//第二个promise//异步任务1执行完成 在then里面的回调开始执行时,p1 并没有停止,仍旧在执行。于是再过2秒后,输出了他们结束的标志。 这个race有什么用呢?使用场景还是很多的,比如我们可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作,代码如下: 123456789101112131415161718192021222324252627282930/请求某个图片资源function requestImg(){ var p = new Promise(function(resolve, reject){ var img = new Image(); img.onload = function(){ resolve(img); } img.src = 'xxxxxx'; }); return p;}//延时函数,用于给请求计时function timeout(){ var p = new Promise(function(resolve, reject){ setTimeout(function(){ reject('图片请求超时'); }, 5000); }); return p;}Promise .race([requestImg(), timeout()]) .then(function(results){ console.log(results); }) .catch(function(err){ console.log(err); }); requestImg函数会异步请求一张图片,我把地址写为”xxxxxx”,所以肯定是无法成功请求到的。timeout函数是一个延时5秒的异步操作。我们把这两个返回Promise对象的函数放进race,于是他俩就会赛跑,如果5秒之内图片请求成功了,那么遍进入then方法,执行正常的流程。如果5秒钟图片还未成功返回,那么timeout就跑赢了,则进入catch,报出“图片请求超时”的信息。 一道常见面试题1234567891011121314151617setTimeout(function() { console.log(1)}, 0); new Promise(function executor(resolve) { console.log(2); for( var i=0 ; i<10000 ; i++ ) { i == 9999 && resolve(); } console.log(3);}).then(function() { console.log(4);}); console.log(5);“2 3 5 4 1” 情景传入一个token,根据这个token请求一次网络,然后获取用户ID,将获取的用户ID访问数据库,获取用户信息 12345678910111213141516171819202122232425262728293031323334353637var request = function (token) { return new Promise((resolve, reject)=> { setTimeout(()=> { token ? resolve(2) : reject('token error'); },1000) });}; var find = function (id) { return new Promise((resolve, reject)=> { setTimeout(()=> { id ? resolve(id + '-info') : reject('id error'); },1000) });}; request('token') .then(function (id) { return find(id); }) .then(function (info) { console.log( info); }); co(function *() { var id = yield request('token'); var info = yield find(id); console.log(id, info);}); (async function () { var id = await request('token'); var info = await find(id); console.log(id, info);})();","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Fetch学习笔记","date":"2017-03-08T12:05:01.000Z","path":"2017/03/08/Fetch学习笔记/","text":"fetch 与XMLHttpRequest(XHR)类似,fetch()方法允许你发出AJAX请求。区别在于Fetch API使用Promise,因此是一种简洁明了的API,比XMLHttpRequest更加简单易用。 比较XMLHttpRequest(传统Ajax)创建步骤: 创建XMLHttpRequest对象,也就是创建一个异步调用对象 创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息 发送HTTP请求 处理响应,获取异步调用返回的数据 可以发现,主要的不同点在于:传统Ajax使用事件处理器,而不是Promise对象,并且请求的发起完全依赖于xhr对象所提供的方法。 fetch语法12345678910fetch(url) .then(function(response) { return response.json(); }) .then(function(data) { console.log(data); }) .catch(function(e) { console.log("Oops, error"); }); 使用 ES6 的 箭头函数 1234fetch(url) .then(response => response.json()) .then(data => console.log(data)) .catch(e => console.log("Oops, error", e)) 使用 async/await 来做最终优化: 123456789(async function () { try { let response = await fetch(url); let data = response.json(); console.log(data); } catch(e) { console.log("Oops, error", e); }})(); 使用 await 后,写异步代码就像写同步代码一样爽。await 后面可以跟 Promise 对象,表示等待 Promise resolve() 才会继续向下执行,如果 Promise 被 reject() 或抛出异常则会被外面的 try…catch 捕获。 如果还不了解async/await,可以移步👉es6Async这篇博客 GET请求123456789fetch(url, { method: "GET", //默认 headers:{ "Accept": "application/json, text/plain, */*" }}).then(response => response.json()).then(data => console.log(data)).catch(e => console.log("Oops, error", e)) POST请求1234567891011fetch(url, { method: "POST", headers: { "Accept": "application/json, text/plain, */*", "Content-type":"application:/x-www-form-urlencoded; charset=UTF-8" }, body: "name=hzzly&age=22"}).then(response => response.json()).then(data => console.log(data)).catch(e => console.log("Oops, error", e)) 使用Fetch请求发送凭证 要使用Fetch发送带有诸如cookie之类的凭证的请求。你可以在选项对象中将credentials属性值设置为“include”: 123fetch(url,{ credentials: "include"}) 封装POST请求123456789101112131415161718192021222324252627282930313233//将对象拼接成 name=hzzly&age=22 的字符串形式function params(obj) { let result = '' for(let item in obj) { result += `&${item}=${obj[item]}` } if(result) { result = result.slice(1) } return result}function post(url, paramsObj) { let result = fetch(url, { methods: 'POST', credentials: "include" headers: { "Accept": "application/json, text/plain, */*", "Content-type":"application:/x-www-form-urlencoded; charset=UTF-8" }, body: params(paramsObj) }) return result}let obj = { name: 'hzzly', age: 22}post(url, obj) .then(response => response.json()) .then(data => console.log(data)) .catch(e => console.log("Oops, error",","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"sessionStorage与localStorage","date":"2017-02-06T12:05:01.000Z","path":"2017/02/06/sessionStorage与localStorage/","text":"sessionStorage 数据的存储仅特定于某个会话中,也就是说数据只保持到浏览器关闭,当浏览器关闭后重新打开这个页面时, 之前的存储已经被清除。 localStorage 是一个持久化的存储,它并不局限于会话。除非主动删除数据,否则数据是永远不会过期的。 一、localStorage和sessionStorage操作 localStorage和sessionStorage都具有相同的操作方法,例如setItem、getItem和removeItem等 1.setItem存储value12sessionStorage.setItem("name", "hzzly");localStorage.setItem("blog", "hzzly.github.io"); 2.getItem获取value12let name = sessionStorage.getItem("name");let blog = localStorage.getItem("blog"); 3.removeItem删除key12sessionStorage.removeItem("name");localStorage.removeItem("blog"); 4.clear清除所有的key/value12sessionStorage.clear();localStorage.clear(); 5.其他操作方法:点操作和[] web Storage不但可以用自身的setItem,getItem等方便存取,也可以像普通对象一样用点(.)操作符,及[]的方式进行数据存储及读取,像如下的代码: 12345678910//存localStorage.name = "hzzly"; localStorage["age"] = "21"; sessionStorage.name = "hzzly"; sessionStorage["age"] = "21";//取let name1 = localStorage.namelet age1 = localStorage["age"]let name2 = sessionStorage.namelet age2 = sessionStorage["age"] 6.localStorage和sessionStorage的key和length属性实现遍历 sessionStorage和localStorage提供的key()和length可以方便的实现存储的数据遍历,例如下面的代码: 123456var storage = window.localStorage; for (var i=0, len = storage.length; i < len; i++){ let key = storage.key(i); let value = storage.getItem(key); console.log(key + "=" + value); } 二、实例 storage只能存储字符串的数据,对于JS中常用的数组或对象却不能直接存储,可以用下面两个方法进行转换: JSON.stringify() 用于从一个对象解析出字符串 JSON.parse() 用于从一个字符串中解析出json对象 1.localStorage/sessionStorage存取数组123456//存let language = ['HTML/HTML5', 'CSS/CSS3', 'JavaScript', 'Vue', 'React']localStorage.language = JSON.stringify(language)sessionStorag.language = JSON.stringify(language)//取let storageLanguage = JSON.parse(localStorage.language) 2.localStorage存取对象1234567891011//存let myInfo = { 'name': 'hzzly', 'age': 21, 'school': 'ECUT', 'city': 'NanChang'}localStorage.myInfo = JSON.stringify(myInfo)sessionStorag.myInfo = JSON.stringify(myInfo)//取let storageLanguage = JSON.parse(localStorage.myInfo)","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Express与MongoDB的缠绵","date":"2017-02-03T12:05:01.000Z","path":"2017/02/03/Express与MongoDB的缠绵/","text":"前奏Express 是什么? Express 是一个基于 Node.js 平台的极简、灵活的 web 应用开发框架,它提供一系列强大的特性,帮助你创建各种 Web 和移动设备应用。 全局安装express脚手架 1$ npm install express-generator -g 创建express项目 1234$ express myapp$ cd myapp$ npm install$ DEBUG=myapp npm start MongoDB与Mongoose? MongoDB是一个对象数据库,是用来存储数据的;存储的数据格式为JSON。 Mongoose是封装了MongoDB操作(增删改查等)的一个对象模型库,是用来操作这些数据的。 安装MongoDB:https://www.mongodb.com/download-center?jmp=nav 安装Mongoose: 1$ npm install mongoose --save 一、连接MongoDB 在项目根目录下新建/lib/mongo.js 123var mongoose = require("mongoose");var db = mongoose.connect('mongodb://localhost:27017/myblog');module.exports = db 要连接的数据库为myblog 二、Schema 一种以文件形式存储的数据库模型骨架,无法直接通往数据库端,不具备对数据库的操作能力,仅仅只是数据库模型在程序片段中的一种表现,可以说是数据属性模型(传统意义的表结构),又或着是“集合”的模型骨架 新建一个用户Schema 在项目根目录下新建/models/users.js 12345678910111213141516var mongoose = require("mongoose");var db = require('../lib/mongo');//一个用户模型var UserSchema = new mongoose.Schema({ username : { type:String }, password : {type: String}, avatar : {type: String}, age : { type:Number, default:0 }, description : { type: String}, email : { type: String }, github : { type: String }, time : { type:Date, default:Date.now }});//创建Modelvar UserModel = db.model("user", UserSchema );module.exports = UserModel user:数据库中的集合名称,当我们对其添加数据时如果user已经存在,则会保存到其目录下,如果不存在,则会创建user集合,然后在保存数据。 拥有了Model,我们也就拥有了操作数据库的金钥匙,就可以使用Model来进行增删改查的具体操作。 Entity Entity–由Model创建的实体,使用save方法保存数据,Model和Entity都有能影响数据库的操作,但Model比Entity更具操作性。所以此项目主要用的Model。 12345678910111213var UserEntity = new UserModel({ name : "hzzly", age : 21, email: "hjingren@aliyun.com", github: 'https://github.com/hzzly'});UserEntity.save(function(error,doc){ if(error){ console.log("error :" + error); }else{ console.log(doc); }}); 三、封装数据库的CURD 在lib文件下新建api.js 采用Promise封装对数据库的操作,避免回调地狱,使得代码能够更好的被读懂和维护。 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879var UserModel = require('../models/users');module.exports = { /** * 添加数据 * @param {[type]} data 需要保存的数据对象 */ save(data) { return new Promise((resolve, reject) => { //model.create(保存的对象,callback) UserModel.create(data, (error, doc) => { if(error){ reject(error) }else{ resolve(doc) } }) }) }, find(data={}, fields=null, options={}) { return new Promise((resolve, reject) => { //model.find(需要查找的对象(如果为空,则查找到所有数据), 属性过滤对象[可选参数], options[可选参数], callback) UserModel.find(data, fields, options, (error, doc) => { if(error){ reject(error) }else{ resolve(doc) } }) }) }, findOne(data) { return new Promise((resolve, reject) => { //model.findOne(需要查找的对象,callback) UserModel.findOne(data, (error, doc) => { if(error){ reject(error) }else{ resolve(doc) } }) }) }, findById(data) { return new Promise((resolve, reject) => { //model.findById(需要查找的id对象 ,callback) UserModel.findById(data, (error, doc) => { if(error){ reject(error) }else{ resolve(doc) } }) }) }, update(conditions, update) { return new Promise((resolve, reject) => { //model.update(查询条件,更新对象,callback) UserModel.update(conditions, update, (error, doc) => { if(error){ reject(error) }else{ resolve(doc) } }) }) }, remove(conditions) { return new Promise((resolve, reject) => { //model.update(查询条件,callback) UserModel.remove(conditions, (error, doc) => { if(error){ reject(error) }else{ resolve(doc) } }) }) }} 四、使用 在/routers/index.js中使用 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849var api = require('../lib/api');router.post('/login', function(req, res, next) { var user = { username : req.body.username, password: req.body.password }; api.findOne(user) .then(result => { console.log(result) })})router.post('/sign_up', function(req, res, next) { var user = { username : req.body.username, password: req.body.password, email: req.body.email }; api.save(user) .then(result => { console.log(result) })})router.get('/user_list', function(req, res, next) { //返回所有用户 api.find({}) .then(result => { console.log(result) }) //返回只包含一个键值name、age的所有记录 api.find({},{name:1, age:1, _id:0}) .then(result => { console.log(result) }) //返回所有age大于18的数据 api.find({"age":{"$gt":18}}) .then(result => { console.log(result) }) //返回20条数据 api.find({},null,{limit:20}) .then(result => { console.log(result) }) //查询所有数据,并按照age降序顺序返回数据 api.find({},null,{sort:{age:-1}}) //1是升序,-1是降序 .then(result => { console.log(result) })})","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"JavaScript操作DOM的那些坑","date":"2016-12-17T12:05:01.000Z","path":"2016/12/17/JavaScript操作DOM的那些坑/","text":"js在操作DOM中存在着许多跨浏览器方面的坑,本文花了我将近一周的时间整理,我将根据实例整理那些大大小小的“坑”。 DOM的工作模式是:先加载文档的静态内容、再以动态方式对它们进行刷新,动态刷新不影响文档的静态内容。 PS:IE 中的所有 DOM 对象都是以 COM 对象的形式实现的,这意味着 IE 中的 DOM可能会和其他浏览器有一定的差异。 Node 接口 特性/方法 类型/返回类型 说 明 nodeName String 节点的名字;根据节点的类型而定义 nodeValue String 节点的值;根据节点的类型而定义 nodeType Number 节点的类型常量值之一 ownerDocument Document 返回某元素的根元素 firstChild Node 指向在childNodes列表中的第一个节点 lastChild Node 指向在childNodes列表中的最后一个节点 childNodes NodeList 所有子节点的列表 previousSibling Node 返回选定节点的上一个同级节点,若不存在,则返回null nextSibling Node 返回被选节点的下一个同级节点,若不存在,则返回null hasChildNodes() Boolean 如果当前元素节点拥有子节点,返回true,否则返回false attributes NamedNodeMap 返回包含被选节点属性的 NamedNodeMap appendChild(node) node 将node添加到childNodes的末尾 removeChild(node) node 从childNodes中删除node replaceChild(newnode, oldnode) Node 将childNodes中的oldnode替换成newnode insertBefore Node 在已有子节点之前插入新的子节点 firstChild 相当于 childNodes[0];lastChild 相当于childNodes[box.childNodes.length - 1]。 nodeType返回结点的类型123--元素结点返回1--属性结点返回2--文本结点返回3 innerHTML 和 nodeValue12345对于文本节点,nodeValue 属性包含文本。对于属性节点,nodeValue 属性包含属性值。nodeValue 属性对于文档节点和元素节点是不可用的。 两者区别 12box.childNodes[0].nodeValue = '<strong>abc</strong>';//结果为:<strong>abc</strong>abcbox.innerHTML = '<strong>abc</strong>';//结果为:abc nodeName属性获得结点名称123--对于元素结点返回的是标记名称,如:<a herf><a>返回的是"a"--对于属性结点返回的是属性名称,如:class="test" 返回的是test--对于文本结点返回的是文本的内容 tagName1document.getElementByTagName(tagName):返回一个数组,包含对这些结点的引用 getElementsByTagName()方法将返回一个对象数组 HTMLCollection(NodeList),这个数组保存着所有相同元素名的节点列表。 1document.getElementsByTagName('*');//获取所有元素 PS:IE 浏览器在使用通配符的时候,会把文档最开始的 html 的规范声明当作第一个元素节点。 1234document.getElementsByTagName('li');//获取所有 li 元素,返回数组document.getElementsByTagName('li')[0];//获取第一个 li 元素,HTMLLIElementdocument.getElementsByTagName('li').item(0);//获取第一个 li 元素,HTMLLIElementdocument.getElementsByTagName('li').length;//获取所有 li 元素的数目 节点的绝对引用:12345返回文档的根节点:document.documentElement返回当前文档中被击活的标签节点:document.activeElement返回鼠标移出的源节点:event.fromElement返回鼠标移入的源节点:event.toElement返回激活事件的源节点:event.srcElement 节点的相对引用:(设当前对节点为node)12345678返回父节点:node.parentNode || node.parentElement(IE)返回子节点集合(包含文本节点及标签节点):node.childNodes返回子标签节点集合:node.children返回子文本节点集合:node.textNodes返回第一个子节点:node.firstChild返回最后一个子节点:node.lastChild返回同属下一个节点:node.nextSibling返回同属上一个节点:node.previousSibling 节点信息123是否包含某节点:node.contains()是否有子节点node.hasChildNodes() 创建新节点123createDocumentFragment()--创建文档碎片节点createElement(tagname)--创建标签名为tagname的元素createTextNode(text)--创建包含文本text的文本节点 获取鼠标点击事件的位置1234567891011121314151617181920212223document.onclick = mouseClick;function mouseClick(ev){ ev = ev || window.event;//window.event用来兼容IE var x = 0; var y = 0; if(ev.pageX){ x = ev.pageX; y = ev.pageY; }else if(ev.clientX){ var offsetX = 0 , offsetY = 0; if(document.documentElement.scrollLeft){ offsetX = document.documentElement.scrollLeft; offsetY = document.documentElement.scrollTop; }else if(document.body){ offsetX = document.body.scrollLeft; offsetY = document.body.scrollTop; } x = ev.clientX + offsetX; y = ev.clientY + offsetY; } alert("你点击的位置是 x="+ x + " y=" + y);} 以下所描述的属性在chrome和Safari 都很给力的支持了。 问题一:Firefox,Chrome、Safari和IE9都是通过非标准事件的pageX和pageY属性来获取web页面的鼠标位置的。pageX/Y获取到的是触发点相对文档区域左上角距离,以页面为参考点,不随滑动条移动而变化 问题二:在IE 中,event 对象有 x, y 属性(事件发生的位置的 x 坐标和 y 坐标)火狐中没有。在火狐中,与event.x 等效的是event.pageX。event.clientX 与 event.pageX 有微妙的差别(当整个页面有滚动条的时候),不过大多数时候是等效的。 offsetX:IE特有,chrome也支持。鼠标相比较于触发事件的元素的位置,以元素盒子模型的内容区域的左上角为参考点,如果有boder,可能出现负值 问题三:scrollTop为滚动条向下移动的距离,所有浏览器都支持document.documentElement。 其余参照:http://segmentfault.com/a/119… 参照表(+为支持,-为不支持): 1234567891011offsetX/offsetY:W3C- IE+ Firefox- Opera+ Safari+ chrome+x/y:W3C- IE+ Firefox- Opera+ Safari+ chrome+layerX/layerY:W3C- IE- Firefox+ Opera- Safari+ chrome+pageX/pageY:W3C- IE- Firefox+ Opera+ Safari+ chrome+clientX/clientY:W3C+ IE+ Firefox+ Opera+ Safari+ chrome+screenX/screenY:W3C+ IE+ Firefox+ Opera+ Safari+ chrome+ 查看下方DEMO:你会发现offsetX在Firefox下是undefined,在chrome和IE则会正常显示。 https://jsfiddle.net/f4am208m…点击预览 offsetLeft和style.left区别123451.style.left返回的是字符串,比如10px。而offsetLeft返回的是数值,比如数值102.style.left是可读写的,offsetLeft是只读的3.style.left的值需要事先定义(在样式表中定义无效,只能取到在html中定义的值),否则取到的值是空的 getComputedStyle与currentStylegetComputedStyle()接受两个参数:要取得计算样式的元素和一个伪元素,如果不需要伪元素,则可以是null。然而,在IE中,并不支持getComputedStyle,IE提供了currentStyle属性。 getComputedStyle(obj , false ) 是支持 w3c (FF12、chrome 14、safari):在FF新版本中只需要第一个参数,即操作对象,第二个参数写“false”也是大家通用的写法,目的是为了兼容老版本的火狐浏览器。缺点:在标准浏览器中正常,但在IE6/7/8中不支持 12345678910111213141516 window.onload=function(){ var oBtn=document.getElementById('btn'); var oDiv=document.getElementById('div1'); oBtn.onclick=function(){ //alert(oDiv.style.width); //写在样式表里无法读取,只能得到写在行内的 //alert(getComputedStyle(oDiv).width); //适用于标准浏览器 IE6、7、8不识别 //alert(oDiv.currentStyle.width); //适用于IE浏览器,标准浏览器不识别 if(oDiv.currentStyle){ alert(oDiv.currentStyle.width); }else{ alert(getComputedStyle(oDiv).width); } };}; 取消表单提交123456789101112131415161718192021222324252627282930313233<script type="text/javascript"> function listenEvent(eventObj,event,eventHandler){ if(eventObj.addEventListener){ eventObj.addEventListener(event,eventHandler,false); }else if(eventObj.attachEvent){ event = "on" + event; eventObj.attachEvent(event,eventHandler); }else{ eventObj["on" + event] = eventHandler; } } function cancelEvent(event){ if(event.preventDefault){ event.preventDefault();//w3c }else{ event.returnValue = true;//IE } } window.onload = function () { var form = document.forms["picker"]; listenEvent(form,"submit",validateFields); }; function validateFields(evt){ evt = evt ? evt : window.event; ... if(invalid){ cancelEvent(evt); } }</script> 确定浏览器窗口的尺寸对于主流浏览器来说,比如IE9、Firefox,Chrome和Safari,支持名为innerWidth 和 innerHeight的窗口对象属性,它返回窗口的视口区域,减去任何滚动条的大小。IE不支持innerWidth 和 innerHeight 1234567891011121314151617<script type="text/javascript"> function size(){ var w = 0, h=0; if(!window.innerWidth){ w = (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth); h = (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight); }else{ w = window.innerWidth; h = window.innerHeight; } return {width:w,height:h}; } console.log(size());//Object { width: 1366, height: 633 }</script> 实用的 JavaScript 方案(涵盖所有浏览器): 123var w=window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;var h=window.innerHeight || document.documentElement.clientHeight|| document.body.clientHeight; 对于 IE 6、7、8的方案如下: 12document.documentElement.clientHeightdocument.documentElement.clientWidth 或者 12document.body.clientHeightdocument.body.clientWidth Document对象的body属性对应HTML文档的<body>标签。Document对象的documentElement属性则表示 HTML文档的根节点。 attributes 属性attributes 属性返回该节点的属性节点集合。 1234567document.getElementById('box').attributes//NamedNodeMapdocument.getElementById('box').attributes.length;//返回属性节点个数document.getElementById('box').attributes[0]; //Attr,返回最后一个属性节点document.getElementById('box').attributes[0].nodeType; //2,节点类型document.getElementById('box').attributes[0].nodeValue; //属性值document.getElementById('box').attributes['id']; //Attr,返回属性为 id 的节点document.getElementById('box').attributes.getNamedItem('id'); //Attr setAttribute 和 getAttribute在IE中是不认识class属性的,需改为className属性,同样,在Firefox中,也是不认识className属性的,Firefox只认识class属性,所以通常做法如下: 12element.setAttribute(class, value); //for firefoxelement.setAttribute(className, value); //for IE IE:可以使用获取常规属性的方法来获取自定义属性,也可以使用getAttribute()获取自定义属性Firefox:只能使用getAttribute()获取自定义属性. 解决方法:统一通过getAttribute()获取自定义属性 123456document.getElementById('box').getAttribute('id');//获取元素的 id 值document.getElementById('box').id;//获取元素的 id 值document.getElementById('box').getAttribute('mydiv');//获取元素的自定义属性值document.getElementById('box').mydiv//获取元素的自定义属性值, IE 不支持非document.getElementById('box').getAttribute('class');//获取元素的 class 值,IE 不支持document.getElementById('box').getAttribute('className');//非 IE 不支持 PS:在 IE7 及更低版本的IE浏览器中,使用 setAttribute()方法设置 class 和 style 属性是没有效果的,虽然 IE8 解决了这个bug,但还是不建议使用。 removeAttribute()方法12removeAttribute()可以移除 HTML 属性。document.getElementById('box').removeAttribute('style');//移除属性 PS:IE6 及更低版本不支持 removeAttribute()方法。 跨浏览器事件Event对象123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293<!doctype html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> #drop{ width: 300px; height: 200px; background-color: #ff0000; padding: 5px; border: 2px solid #000000; } #item{ width: 100px; height: 100px; background-color: #ffff00; padding: 5px; margin: 20px; border: 1px dashed black; } *[draggable = true]{ -moz-user-select: none; -webkit-user-select: none; cursor: move; } </style></head><body><div> <p>将金黄色的小方块拖到红色的大方块中,不兼容IE7及以下浏览器,兼容主流浏览器!</p></div><div id="item" draggable="true"></div><div id="drop"></div><script type="text/javascript"> function listenEvent(target,type,handler){ if(target.addEventListener){//w3c target.addEventListener(type,handler,false); }else if(target.attachEvent){//IE type = "on" + type; target.attachEvent(type,handler);//IE }else{ target["on" + type] = handler; } } //取消事件 function cancelEvent(e){ if(e.preventDefault){ e.preventDefault();//w3c }else{ e.returnValue = false;//IE } } //取消传递 function cancelPropagation(e){ if(e.stopPropagation){ e.stopPropagation();//w3c }else{ e.cancelBubble = true;//IE } } window.onload = function () { var target = document.getElementById('drop'); listenEvent(target,'dragenter',cancelEvent); listenEvent(target,"dragover",dragOver); listenEvent(target,'drop', function (evt) { cancelPropagation(evt); evt = evt || window.event; evt.dataTransfer.dropEffect = 'copy'; var id = evt.dataTransfer.getData('Text'); target.appendChild(document.getElementById(id)); }); var item = document.getElementById('item'); item.setAttribute("draggable",'true'); listenEvent(item,'dragstart', function (evt) { evt = evt || window.event; evt.dataTransfer.effectAllowed = 'copy'; evt.dataTransfer.setData('Text',item.id); }); }; function dragOver(evt){ if(evt.preventDefault) evt.preventDefault(); evt = evt || window.event; evt.dataTransfer.dropEffect = 'copy'; return false; }</script></body></html> dataTransfer 对象 属性 描述 dropEffect 设置或获取拖曳操作的类型和要显示的光标类型 effectAllowed 设置或获取数据传送操作可应用于该对象的源元素 方法 描述 clearData 通过 dataTransfer 或 clipboardData 对象从剪贴板删除一种或多种数据格式 getData 通过 dataTransfer 或 clipboardData 对象从剪贴板获取指定格式的数据 setData 以指定格式给 dataTransfer 或 clipboardData 对象赋予数据 HTML5拖拽的浏览器支持Internet Explorer 9、Firefox、Opera 12、Chrome 以及 Safari 5 支持拖放 为了使元素可拖动,需把 draggable 属性设置为 true : 1<img draggable="true" /> 事件 描述 dragstart 拖拽事件开始 drag 在拖动操作上 dragenter 拖动到目标上,用来决定目标是否接受放置 dragover 拖动到目标上,用来决定给用户的反馈 drop 放置发生 dragleave 拖动离开目标 dragend 拖动操作结束 上述代码的一些浏览器兼容性: 12345678910111.为了兼容IE,我们将`window.event`赋给 `evt`,其他浏览器则会正确将接收到的`event`对象赋给`evt`。2.w3c使用addEventListener来为事件元素添加事件监听器,而IE则使用attachEvent。addEventListener为事件冒泡到的当前对象,而attachEvent是window3.对于事件类型,IE需要加`on + type`属性,而其他浏览器则不用4.对于阻止元素的默认事件行为,下面是w3c和IE的做法: e.preventDefault();//w3c e.returnValue = false;//IE 5.对于取消事件传播,w3c和IE也有不同的处理机制: e.stopPropagation();//w3c e.cancelBubble = true;//IE 跨浏览器获取目标对象12345678//跨浏览器获取目标对象function getTarget(ev){ if(ev.target){//w3c return ev.target; }else if(window.event.srcElement){//IE return window.event.srcElement; }} 对于获取触发事件的对象,w3c和IE也有不同的做法: 12event.target;//w3cevent.srcElement;//IE 我们可以使用三目运算符来兼容他们: 1obj = event.srcElement ? event.srcElement : event.target; innerText的问题innerText在IE中能正常工作,但是innerText在FireFox中却不行。 12345678<p id="element"></p><script type="text/javascript"> if(navigator.appName.indexOf("Explorer") >-1){ document.getElementById('element').innerText = "my text"; } else{ document.getElementById('element').textContent = "my text"; }</script> 跨浏览器获取和设置innerText12345678910111213//跨浏览器获取innerTextfunction getInnerText(element){ return (typeof element.textContent == 'string') ? element.textContent : element.innerText;} //跨浏览器设置innerTextfunction setInnerText(element,text){ if(typeof element.textContent == 'string'){ element.textContent = text; }else{ element.innerText = text; }} oninput,onpropertychange,onchange的用法onchange触发事件必须满足两个条件: 123a)当前对象属性改变,并且是由键盘或鼠标事件激发的(脚本触发无效)b)当前对象失去焦点(onblur); onpropertychange的话,只要当前对象属性发生改变,都会触发事件,但是它是IE专属的; 1oninput是onpropertychange的非IE浏览器版本,支持firefox和opera等浏览器,但有一点不同,它绑定于对象时,并非该对象所有属性改变都能触发事件,它只在对象value值发生改变时奏效。 访问XMLHTTPRequest对象1234567<script type="text/javascript"> if(window.XMLHttpRequest){ xhr = new XMLHttpRequest();//非IE }else if(window.ActiveXObject){ xhr = new ActiveXObject("Microsoft.XMLHttp");//IE }</script> 禁止选取网页内容123456问题: FF需要用CSS禁止,IE用JS禁止 解决方法: IE: obj.onselectstart = function() {return false;} FF: -moz-user-select:none; 三大不冒泡事件所有浏览器的focus/blur事件都不冒泡,万幸的是大部分浏览器支持focusin/focusout事件,不过可恶的firefox连这个都不支持。 12IE6、7、8下 submit事件不冒泡。IE6、7、8下 change事件要等到blur时才触发。 万恶的滚轮事件滚轮事件的支持可谓是乱七八糟,规律如下: 123456789IE6-11 chrome mousewheel wheelDetla 下 -120 上 120firefox DOMMouseScroll detail 下3 上-3firefox wheel detlaY 下3 上-3IE9-11 wheel deltaY 下40 上-40chrome wheel deltaY 下100 上-100 关于鼠标滚轮事件,IE支持mousewheel,火狐支持DOMMouseScroll。判断鼠标滚轮是向上还是向下,IE是通过wheelDelta属性,而火狐是通过detail属性 事件委托方法123//事件委托方法 IE:document.body.onload = inject; //Function inject()在这之前已被实现 FF:document.body.onload = inject(); HTML5 的浏览器支持情况 来源地址:http://fmbip.com/litmus/ 查询操作查询通过指的是通过一些特征字符串来找到一组元素,或者判断元素是不是满足字符串。 12345678910111213141516171. IE6/7不区分id和nam在IE6/7下使用getElementById和getElementsByName时会同时返回id或name与给定值相同的元素。由于name通常由后端约定,因此我们在写JS时,应保证id不与name重复。2. IE6/7不支持getElementsByClassName和querySelectorAll 这两个函数从IE8开始支持的,因此在IE6/7下,我们实际可以用的只有getElementByTagName。3. IE6/7不支持getElementsByTagName('*')会返回非元素节点 要么不用*,要么自己写个函数过滤一下。4. IE8下querySelectorAll对属性选择器不友好 几乎所有浏览器预定义的属性都有了问题,尽量使用自定义属性或者不用属性选择器。5. IE8下querySelectorAll不支持伪类 有时候伪类是很好用,IE8并不支持,jquery提供的:first、:last、:even、:odd、:eq、:nth、:lt、:gt并不是伪类,我们在任何时间都不要使用它们。6. IE9的matches函数不能处理不在DOM树上的元素只要元素不在dom树上,一定会返回false,实在不行把元素丢在body里面匹配完了再删掉吧,当然了我们也可以自己写匹配函数以避免回流。 资料参考:http://w3help.org/zh-cn/kb/,","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"JavaScript实现常用排序算法","date":"2016-12-08T12:05:01.000Z","path":"2016/12/08/JavaScript实现常用排序算法/","text":"1、插入排序1)算法简介 插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。 2)算法描述和实现 一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下: 123456从第一个元素开始,该元素可以认为已经被排序;取出下一个元素,在已经排序的元素序列中从后向前扫描;如果该元素(已排序)大于新元素,将该元素移到下一位置;重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;将新元素插入到该位置后;重复步骤2~5。 JavaScript代码实现: 12345678910111213141516function insertionSort(array) { if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') { for (var i = 1; i < array.length; i++) { var key = array[i]; var j = i - 1; while (j >= 0 && array[j] > key) { array[j + 1] = array[j]; j--; } array[j + 1] = key; } return array; } else { return 'array is not an Array!'; }} 3)算法分析 123最佳情况:输入数组按升序排列。T(n) = O(n)最坏情况:输入数组按降序排列。T(n) = O(n2)平均情况:T(n) = O(n2) 二、二分插入排序1)算法简介 二分插入(Binary-insert-sort)排序是一种在直接插入排序算法上进行小改动的排序算法。其与直接插入排序算法最大的区别在于查找插入位置时使用的是二分查找的方式,在速度上有一定提升。 2)算法描述和实现 一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下: 1234从第一个元素开始,该元素可以认为已经被排序;取出下一个元素,在已经排序的元素序列中二分查找到第一个比它大的数的位置;将新元素插入到该位置后;重复上述两步。 JavaScript代码实现: 12345678910111213141516171819202122function binaryInsertionSort(array) { if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') { for (var i = 1; i < array.length; i++) { var key = array[i], left = 0, right = i - 1; while (left <= right) { var middle = parseInt((left + right) / 2); if (key < array[middle]) { right = middle - 1; } else { left = middle + 1; } } for (var j = i - 1; j >= left; j--) { array[j + 1] = array[j]; } array[left] = key; } return array; } else { return 'array is not an Array!'; }} 3)算法分析 123最佳情况:T(n) = O(nlogn)最差情况:T(n) = O(n2)平均情况:T(n) = O(n2) 三、选择排序1)算法简介 选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。 2)算法描述和实现 n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下: 123初始状态:无序区为R[1..n],有序区为空;第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1..i-1]和R(i..n)。该趟排序从当前无序区中选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R[i+1..n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;n-1趟结束,数组有序化了。 JavaScript代码实现: 12345678910111213141516171819function selectionSort(array) { if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') { var len = array.length, temp; for (var i = 0; i < len - 1; i++) { var min = array[i]; for (var j = i + 1; j < len; j++) { if (array[j] < min) { temp = min; min = array[j]; array[j] = temp; } } array[i] = min; } return array; } else { return 'array is not an Array!'; }} 3)算法分析 123最佳情况:T(n) = O(n2)最差情况:T(n) = O(n2)平均情况:T(n) = O(n2) 四、冒泡排序1)算法简介 冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。 2)算法描述和实现 具体算法描述如下: 1234比较相邻的元素。如果第一个比第二个大,就交换它们两个;对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;针对所有的元素重复以上的步骤,除了最后一个;重复步骤1~3,直到排序完成。 JavaScript代码实现: 1234567891011121314function bubbleSort(arr){ //外层循环,共要进行arr.length次求最大值操作 for(var i=0;i<arr.length;i++){ //内层循环,找到第i大的元素,并将其和第i个元素交换 for(var j=i;j<arr.length;j++){ if(arr[i]<arr[j]){ //交换两个元素的位置 var temp=arr[i]; arr[i]=arr[j]; arr[j]=temp; } } }} 五、快速排序1)算法简介 快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。 2)算法描述和实现 快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下: 123从数列中挑出一个元素,称为 "基准"(pivot);重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。 JavaScript代码实现: 1234567891011121314151617181920212223242526272829var quickSort = function(arr) { if (arr.length <= 1) { return arr; } var pivotIndex = Math.floor(arr.length / 2); var pivot = arr.splice(pivotIndex, 1)[0]; var left = []; var right = []; for (var i = 0; i < arr.length; i++){ if (arr[i] < pivot) { left.push(arr[i]); } else { right.push(arr[i]); } } return quickSort(left).concat([pivot], quickSort(right));}; 六、堆排序1)算法简介 堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。 2)算法描述和实现 具体算法描述如下: 123将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无序区;将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。 JavaScript代码实现: 1234567891011121314151617181920212223242526272829303132333435363738394041424344/*方法说明:堆排序@param array 待排序数组*/ function heapSort(array) { if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') { //建堆 var heapSize = array.length, temp; for (var i = Math.floor(heapSize / 2); i >= 0; i--) { heapify(array, i, heapSize); } //堆排序 for (var j = heapSize - 1; j >= 1; j--) { temp = array[0]; array[0] = array[j]; array[j] = temp; heapify(array, 0, --heapSize); } } else { return 'array is not an Array!'; }}/*方法说明:维护堆的性质@param arr 数组@param x 数组下标@param len 堆大小*/function heapify(arr, x, len) { if (Object.prototype.toString.call(arr).slice(8, -1) === 'Array' && typeof x === 'number') { var l = 2 * x, r = 2 * x + 1, largest = x, temp; if (l < len && arr[l] > arr[largest]) { largest = l; } if (r < len && arr[r] > arr[largest]) { largest = r; } if (largest != x) { temp = arr[x]; arr[x] = arr[largest]; arr[largest] = temp; heapify(arr, largest, len); } } else { return 'arr is not an Array or x is not a number!'; }} 3)算法分析 123最佳情况:T(n) = O(nlogn)最差情况:T(n) = O(nlogn)平均情况:T(n) = O(nlogn) 七、归并排序1)算法简介 归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。 2)算法描述和实现 具体算法描述如下: 123把长度为n的输入序列分成两个长度为n/2的子序列;对这两个子序列分别采用归并排序;将两个排序好的子序列合并成一个最终的排序序列。 JavaScript代码实现: 123456789101112131415161718192021222324252627function mergeSort(array, p, r) { if (p < r) { var q = Math.floor((p + r) / 2); mergeSort(array, p, q); mergeSort(array, q + 1, r); merge(array, p, q, r); }}function merge(array, p, q, r) { var n1 = q - p + 1, n2 = r - q, left = [], right = [], m = n = 0; for (var i = 0; i < n1; i++) { left[i] = array[p + i]; } for (var j = 0; j < n2; j++) { right[j] = array[q + 1 + j]; } left[n1] = right[n2] = Number.MAX_VALUE; for (var k = p; k <= r; k++) { if (left[m] <= right[n]) { array[k] = left[m]; m++; } else { array[k] = right[n]; n++; } }} 3)算法分析 123最佳情况:T(n) = O(n)最差情况:T(n) = O(nlogn)平均情况:T(n) = O(nlogn) 八、桶排序1)算法简介 桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。 2)算法描述和实现 具体算法描述如下: 1234设置一个定量的数组当作空桶;遍历输入数据,并且把数据一个一个放到对应的桶里去;对每个不是空的桶进行排序;从不是空的桶里把排好序的数据拼接起来。 JavaScript代码实现: 12345678910111213141516171819202122232425262728293031323334/*方法说明:桶排序@param array 数组@param num 桶的数量*/function bucketSort(array, num) { if (array.length <= 1) { return array; } var len = array.length, buckets = [], result = [], min = max = array[0], regex = '/^[1-9]+[0-9]*$/', space, n = 0; num = num || ((num > 1 && regex.test(num)) ? num : 10); for (var i = 1; i < len; i++) { min = min <= array[i] ? min : array[i]; max = max >= array[i] ? max : array[i]; } space = (max - min + 1) / num; for (var j = 0; j < len; j++) { var index = Math.floor((array[j] - min) / space); if (buckets[index]) { // 非空桶,插入排序 var k = buckets[index].length - 1; while (k >= 0 && buckets[index][k] > array[j]) { buckets[index][k + 1] = buckets[index][k]; k--; } buckets[index][k + 1] = array[j]; } else { //空桶,初始化 buckets[index] = []; buckets[index].push(array[j]); } } while (n < num) { result = result.concat(buckets[n]); n++; } return result;} 3)算法分析 桶排序最好情况下使用线性时间O(n),桶排序的时间复杂度,取决与对各个桶之间数据进行排序的时间复杂度,因为其它部分的时间复杂度都为O(n)。很显然,桶划分的越小,各个桶之间的数据越少,排序所用的时间也会越少。但相应的空间消耗就会增大。 九、计数排序1)算法简介 计数排序(Counting sort)是一种稳定的排序算法。计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C来将A中的元素排到正确的位置。它只能对整数进行排序。 2)算法描述和实现 具体算法描述如下: 1234找出待排序的数组中最大和最小的元素;统计数组中每个值为i的元素出现的次数,存入数组C的第i项;对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。 JavaScript代码实现: 12345678910111213141516function countingSort(array) { var len = array.length, B = [], C = [], min = max = array[0]; for (var i = 0; i < len; i++) { min = min <= array[i] ? min : array[i]; max = max >= array[i] ? max : array[i]; C[array[i]] = C[array[i]] ? C[array[i]] + 1 : 1; } for (var j = min; j < max; j++) { C[j + 1] = (C[j + 1] || 0) + (C[j] || 0); } for (var k = len - 1; k >=0; k--) { B[C[array[k]] - 1] = array[k]; C[array[k]]--; } return B;} 3)算法分析 当输入的元素是n 个0到k之间的整数时,它的运行时间是 O(n + k)。计数排序不是比较排序,排序的速度快于任何比较排序算法。由于用来计数的数组C的长度取决于待排序数组中数据的范围(等于待排序数组的最大值与最小值的差加上1),这使得计数排序对于数据范围很大的数组,需要大量时间和内存。","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"利用canvas实现时钟效果","date":"2016-12-08T12:05:01.000Z","path":"2016/12/08/利用canvas实现时钟效果/","text":"你需要知道的: canvas标签只是图形容器,您必须使用脚本来绘制图形。默认大小:宽300px,高150px; getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。——获取上下文对象。getContext("2d") 对象属性和方法,可用于在画布上绘制文本、线条、矩形、圆形等等。 fillRect(l,t,w,h):默认颜色是黑色 strokeRect(l,t,w,h):带边框的方块。默认一像素黑色边框 setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。 beginPath():定义开始绘制路径, 它把当前的点设置为 (0,0)。 当一个画布的环境第一次创建,beginPath()方法会被显式地调用。closePath():结束绘制路径(将起点与终点进行连接) 1* 绘制圆形 arc( x,y,半径,起始弧度,结束弧度,旋转方向)x,y:起始位置弧度与角度的关系:弧度=角度*Math.PI/180旋转方向:顺时针(默认:false,逆时针:true) 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394<!DOCTYPE HTML><html lang="en-US"><head> <meta charset="UTF-8"> <title></title> <script> window.onload = function(){ var oC = document.getElementById('ch1'); var oGC = oC.getContext('2d'); function drawClock(){ var x = 200; //指定坐标 var y = 200; var r = 150; //指定钟表半径 oGC.clearRect(0,0,oC.width,oC.height);//清空画布 var oDate = new Date(); //创建日期对象 var oHours = oDate.getHours();//获取时间 var oMin = oDate.getMinutes(); var oSen = oDate.getSeconds(); var oHoursValue = (-90 + oHours*30 + oMin/2)*Math.PI/180; //设置时针的值 var oMinValue = (-90 + oMin*6)*Math.PI/180; var oSenValue = (-90 + oSen*6)*Math.PI/180; oGC.beginPath();//开始 for(var i=0;i<60;i++){ //i为60,代表着时钟的60个小刻度 oGC.moveTo(x,y); oGC.arc(x,y,r,6*i*Math.PI/180,6*(i+1)*Math.PI/180,false); //循环从6度到12度 } oGC.closePath(); oGC.stroke(); oGC.fillStyle ='white'; //覆盖住小刻度的黑色线 oGC.beginPath(); oGC.moveTo(x,y); oGC.arc(x,y,r*19/20,0,360*(i+1)*Math.PI/180,false); oGC.closePath();//结束 oGC.fill(); oGC.lineWidth = 3; //设置时钟圆盘大刻度的粗细值 oGC.beginPath(); //开始画大的时钟刻度 for(i=0;i<12;i++){ //i为12,代表着时钟刻度的12大格 oGC.moveTo(x,y); oGC.arc(x,y,r,30*i*Math.PI/180,30*(i+1)*Math.PI/180,false); // 间隔为30度,弧度=角度*Math.PI/180 } oGC.closePath(); oGC.stroke(); oGC.fillStyle ='white'; //覆盖住大刻度的黑色线 oGC.beginPath(); oGC.moveTo(x,y); oGC.arc(x,y,r*18/20,360*(i+1)*Math.PI/180,false); oGC.closePath(); oGC.fill();//表盘完成 oGC.lineWidth = 5;//设置时针宽度 oGC.beginPath();//开始绘制时针 oGC.moveTo(x,y); oGC.arc(x,y,r*10/20,oHoursValue,oHoursValue,false);//设置时针大小和弧度 oGC.closePath(); oGC.stroke(); oGC.lineWidth = 3;//设置分针宽度 oGC.beginPath();//开始绘制分针 oGC.moveTo(x,y); oGC.arc(x,y,r*14/20,oMinValue,oMinValue,false);//设置分针大小和弧度 oGC.closePath(); oGC.stroke(); oGC.lineWidth = 1;//设置秒针宽度 oGC.beginPath();//开始绘制秒针 oGC.moveTo(x,y); oGC.arc(x,y,r*19/20,oSenValue,oSenValue,false);//设置秒针大小和弧度 oGC.closePath(); oGC.stroke(); } setInterval(drawClock,1000);//设置定时器,让时钟运转起来 drawClock(); }; </script></head><body> <canvas id = "ch1" width = "400px" height = "400px"></canvas></body></html> 点击下方result查看演示:http://jsfiddle.net/eh02450b/2/","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"js实现图片懒加载","date":"2016-11-03T12:05:01.000Z","path":"2016/11/03/js实现图片懒加载/","text":"懒加载的意义 懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数,对服务器缓压。 预加载:提前加载好,缓存到本地,当需要的时候直接读取缓存,对服务器增压 懒加载实现方式 第一种是纯粹的延迟加载,使用setTimeOut或setInterval进行加载延迟 第二种是条件加载,符合某些条件,或触发了某些事件才开始异步下载 第三种是可视区加载,即仅加载用户可以看到的区域,这个主要由监控滚动条来实现,一般会在距用户看到某图片前一定距离遍开始加载,这样能保证用户拉下时正好能看到图片 Web 图片的懒加载就是通过读取img元素,然后获得img元素的data-src(也可以约定为其他属性名)属性的值,并赋予img的src,从而实现动态加载图片的机制 1、懒加载HTML约定我们首先需要给准备实施懒加载的img元素添加指定的class 这里为m-lazyload ,同时将img src赋值给 data-src属性。具体示例为: 1<img class="m-lazyload" data-src="imgUrl"> 2、懒加载JavaScript实现动态加载总共分为以下几个步骤:1、添加页面滚动监听事件 12345678window.addEventListener('scroll', _delay, false); function _delay() { clearTimeout(delay); delay = setTimeout(function () { _loadImage(); }, time);} 2、当触发监听事件时会执行 _loadImage 函数,该函数负责加载图片 12345678910function _loadImage() { for (var i = imgList.length; i--;) { var el = imgList[i]; if (_isShow(el)) { el.src = el.getAttribute('data-src'); el.className = el.className.replace(new RegExp("(\\\\s|^)" + _selector.substring(1, _selector.length) + "(\\\\s|$)"), " "); imgList.splice(i, 1); } }} 3、判断该图片是否在当前窗口的可视区域内 1234function _isShow(el) { var coords = el.getBoundingClientRect(); return ( (coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + parseInt(offset));} 到这一个简单的图片懒加载就写成了 当网页滚动的事件被触发 -> 执行加载图片操作 -> 判断图片是否在可视区域内 -> 在,则动态将data-src的值赋予该图片。","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"HTML5与移动端web学习笔记","date":"2016-10-23T12:05:01.000Z","path":"2016/10/23/HTML5与移动端web学习笔记/","text":"概述HTML5 提供了很多新的功能,主要有: 123456新的 HTML 元素,例如 section, nav, header, footer, article 等用于绘画的 Canvas 元素用于多媒体播放的 video 和 audio 元素用于定位的 Geolocation API本地存储以及离线应用Web Workers、Web WebSocket API 移动前端开发可分为: 手机网页开发。这部分跟web前端开发差别不大,使用的技术都是html+css+js。区别为手机浏览器是webkit的天下,pc端是IE的天下。 app前端开发。使用的技术也是html+css+js,但它需要基于PhoneGap,React Native等开发平台调用手机核心功能接口(包括地理定位,加速器,联系人,声音和振动等)模拟native app,这部分跟web前端开发完全不同。最终代码发布要分别编译成各系统平台的app。 canvascanvas部分请参考:http://segmentfault.com/a/119… drag and drop(拖拽)拖拽元素事件 : 事件对象为被拖拽元素123dragstart : 拖拽前触发 drag :拖拽前、拖拽结束之间,连续触发dragend : 拖拽结束触发 目标元素事件 : 事件对象为目标元素1234dragenter : 进入目标元素触发,相当于mouseoverdragover : 进入目标、离开目标之间,连续触发dragleave : 离开目标元素触发,相当于mouseoutdrop : 在目标元素上释放鼠标触发 事件的执行顺序 :drop不触发的时候1dragstart > drag > dragenter > dragover > dragleave > dragend 事件的执行顺序 :drop触发的时候(dragover的时候阻止默认事件)1dragstart > drag > dragenter > dragover > drop > dragend 解决火狐下的问题火狐浏览器下必须设置dataTransfer对象的setData方法才可以拖拽除图片外的其他标签。 dataTransfer属性和方法1234567891011121314属性 描述dropEffect 设置或获取拖曳操作的类型和要显示的光标类型。effectAllowed 设置光标样式(none, copy, copyLink, copyMove, link, linkMove, move, all 和 uninitialized)setDragImage 三个参数:指定的元素,坐标X,坐标Yfiles 获取外部拖拽的文件,返回一个filesList列表。filesList下有个type属性,返回文件的类型方法 描述clearData 通过 dataTransfer 或 clipboardData 对象从剪贴板删除一种或多种数据格式。setData() : 设置数据 key和value(必须是字符串)getData() : 获取数据,根据key值,获取对应的value 只有加阻止默认事件才可以触发drop 123oDiv.ondragover = function(ev){ //只有加阻止默认事件才可以触发drop ev.preventDefault(); }; drag and drop的浏览器支持情况: HTML5实现拖拽上传预览图片:1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <style type="text/css"> #div1{ margin: 0 auto; width:200px; height:200px; background:#ccc; color: white;} #div1 p{ position: relative; top: 90px; left: 50px; } li{ width:200px; height:200px; margin:5px; float:left; list-style:none;} li img{ width:500px;height: auto} </style> <script type="text/javascript"> window.onload = function(){ var oUl = document.getElementById('ul1'); var oDiv = document.getElementById('div1'); oDiv.ondragenter = function(){ this.innerHTML = '可以释放'; }; oDiv.ondragover = function(ev){ ev.preventDefault(); }; oDiv.ondragleave = function(){ this.innerHTML = '请拖拽到此区域'; }; oDiv.ondrop = function(ev){ ev.preventDefault(); var fs = ev.dataTransfer.files; for(var i=0;i<fs.length;i++){ var fr = new FileReader(); if( fs[i].type.indexOf('image')!=-1 ){ fr.readAsDataURL( fs[i] ); fr.onload = function(){ var oLi = document.createElement('li'); var oImg = document.createElement('img'); oImg.src = this.result; oLi.appendChild( oImg ); oUl.appendChild( oLi ); }; } else{ alert('亲,请拖拽图片格式'); } } }; }; </script></head><body><div id="div1"><p>请拖拽到此区域</p></div><ul id="ul1"></ul></body> FileReader(读取文件信息) 属性名 描述 error 在读取文件时发生的错误. 只读. readyState 表明FileReader对象的当前状态. result 读取到的文件内容。这个属性只在读取操作完成之后才有效 方法名 描述 abort 中止该读取操作.在返回时,readyState属性的值为DONE. readAsArrayBuffer 将File对象F读取为一个 ArrayBuffer 对象。 readAsBinaryString 将File对象F读取为一个二进制字符串。 readAsDataURL 将File对象F读取为编码过的数据URL。 readAsText(File f, [encoding]) 读取 File对象F并赋予一个字符串。 创建一个FileReader对象: 1var reader = new FileReader(); Web Worker和缓存Web Worker的基本原理就是在当前js的主线程中,使用Worker类加载一个js文件来开辟一个新的线程,起到互不阻塞执行的效果,并且提供主线程和新线程之间数据交换的接口:postMessage,onmessage。 主机 worker 和 worker 脚本可以通过 postMessage 发送消息并使用 onmessage 事件侦听响应。消息的内容作为事件的数据属性进行发送。 1234var worker = new Worker('worker.js');worker.onmessage = function(e) { alert(e.data);}; worker主线程:12345671.通过 worker = new Worker( url ) 加载一个JS文件来创建一个worker,同时返回一个worker实例。2.通过worker.postMessage( data ) 方法来向worker发送数据。3.绑定worker.onmessage方法来接收worker发送过来的数据。4.可以使用 worker.terminate() 来终止一个worker的执行。 worker新线程:1231.通过postMessage( data ) 方法来向主线程发送数据。2.绑定onmessage方法来接收主线程发送过来的数据。 例子:计数功能首先创建一个index.html文件 12345678910111213<!doctype html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <script type="text/javascript" src="index.js"></script></head><body><div id="numDiv">0</div><button type="button" id="start">start</button><button type="button" id="stop">stop</button></body></html> 其次,创建一个count.js文件: 12345678var countNum = 0;function count(){ postMessage(countNum); countNum++; setTimeout(count,1000);}count(); 再创建一个index.js文件 1234567891011121314151617181920212223var numDiv;var work = null;window.onload = function () { numDiv = document.getElementById('numDiv'); document.getElementById('start').onclick = startWorker; document.getElementById('stop').onclick = function () { if(work){ work.terminate();//停止,释放掉资源 work = null;//work重新初始化 } };};function startWorker(){ if(work){ return; } work = new Worker('count.js'); work.onmessage = function (e) { numDiv.innerHTML = e.data; };} Web SQL三个核心方法: 123451、openDatabase:这个方法使用现有数据库或创建新数据库创建数据库对象。2、transaction:这个方法允许我们根据情况控制事务提交或回滚。3、executeSql:这个方法用于执行真实的SQL查询。 浏览器的本地数据库占用资源少,处理速度快。openDatabase方法打开一个已经存在的数据库,如果数据库不存在,它还可以创建数据库,创建并打开数据库的语法如下: 1var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024); 参数为:数据库名(mydb)、版本号(1.0)、描述(Test DB)和数据库大小(2*1024*1024)以及创建回调函数 WebSocketsTCP是因特网的基础传输协议,而WebSocket是Web应用程序的传输协议,它提供了双向的,按序到达的数据流。WebSocket连接的是URL,而非因特网上的主机和端口。 12345678910111213141516171819202122 // 创建一个Socket实例var socket = new WebSocket('ws://localhost:8080');// 打开Socketsocket.onopen = function(ev) { // 发送一个初始化消息 socket.send('hello HTML5'); // 监听消息 socket.onmessage = function(ev) { console.log('Client received a message',ev); }; // 监听Socket的关闭 socket.onclose = function(ev) { console.log('Client notified socket has closed',ev); }; // 关闭Socket.... socket.close()}; 同http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,而安全的WebSocket协议使用wss://开头。 HTTP协议通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS。默认HTTP的端口号为80,HTTPS的端口号为443。 getUserMedia APInavigator.getUserMedia可以提示用户需要权限去使用像摄像头或麦克风之类的媒体设备.下面是一个获取用户摄像头并提供拍照功能的例子: 1234567891011121314151617181920212223242526272829303132333435363738394041424344<body><video id="video" width="640" height="480" autoplay></video><button id="snap">Snap Photo</button><canvas id="canvas" width="640" height="480"></canvas><script type="text/javascript"> // 添加事件监听器 window.addEventListener("DOMContentLoaded", function() { // 获取元素,创建设置等等 var canvas = document.getElementById("canvas"), context = canvas.getContext("2d"), video = document.getElementById("video"), videoObj = { "video": true }, errBack = function(error) { console.log("Video capture error: ", error.code); }; // 添加video 监听器 if(navigator.getUserMedia) { // 标准 navigator.getUserMedia(videoObj, function(stream) { video.src = stream; video.play(); }, errBack); } else if(navigator.webkitGetUserMedia) { // WebKit 前缀 navigator.webkitGetUserMedia(videoObj, function(stream){ video.src = window.webkitURL.createObjectURL(stream); video.play(); }, errBack); } else if(navigator.mozGetUserMedia) { // Firefox 前缀 navigator.mozGetUserMedia(videoObj, function(stream){ video.src = window.URL.createObjectURL(stream); video.play(); }, errBack); } document.getElementById("snap").addEventListener("click", function() { context.drawImage(video, 0, 0, 640, 480); }); }, false);</script></body> 下面是浏览器兼容性的写法: 123456<script type = 'text/javascript'> navigator.getMedia = ( navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);</script> 浏览器对象 audio和video下图是audio和video的属性及其浏览器的兼容性: Fullscreen API进入全屏模式1234567891011121314// 找到正确的方法 function launchFullScreen(element) { if(element.requestFullScreen) { element.requestFullScreen(); } else if(element.mozRequestFullScreen) { element.mozRequestFullScreen(); } else if(element.webkitRequestFullScreen) { element.webkitRequestFullScreen(); } } // 启动全屏模式 launchFullScreen(document.documentElement); // 整个页面 launchFullScreen(document.getElementById("videoElement")); // 单独元素 退出全屏模式123456789101112function cancelFullscreen() { if(document.cancelFullScreen) { document.cancelFullScreen(); } else if(document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if(document.webkitCancelFullScreen) { document.webkitCancelFullScreen(); } } // 取消全屏 cancelFullscreen(); 全屏属性和事件123document.fullScreenElement:当前全屏显示的元素。document.fullScreenEnabled:判断浏览器是否支持全屏。fullscreenchange事件:全屏状态改变事件。 History APIHTML5 更新了两个API,无刷新更新地址 history.pushState方法和history.replaceState 方法 Geolocation APIGeolocation API 是通过window.navigator.geolocation 获得对地理定位的访问的。该对象有如下三个方法: 123getCurrentPosition()watchPosition()clearWatch() 表单元素HTML5 新增了很多表单元素让开发者构建更优秀的 Web 应用程序。以下是HTML5新增的表单元素 12345678910111213datalistdatetimeoutputkeygen date month weektimecolornumber range email url html5移动端优化PC端的优化对于移动端同样适用,Android同时支持4个并发请求,iOS 5后可支持6个,所以,应尽量减少http请求数 123456781. PC优化手段在Mobile侧同样适用2. 在Mobile侧我们提出三秒种渲染完成首屏指标3. 基于第二点,首屏加载3秒完成或使用Loading4. 基于联通3G网络平均338KB/s(2.71Mb/s),所以首屏资源不应超过1014KB5. Mobile侧因手机配置原因,除加载外渲染速度也是优化重点6. 基于第五点,要合理处理代码减少渲染损耗7. 基于第二、第五点,所有影响首屏加载和渲染的代码应在处理逻辑中后置8. 加载完成后用户交互使用时也需注意性能 不滥用Float1Float在渲染时计算量比较大,尽量减少使用 不滥用Web字体1Web字体需要下载,解析,重绘当前页面,尽量减少使用 不声明过多的Font-size1过多的Font-size引发CSS树的效率 减少重绘和回流1234a) 避免不必要的Dom操作b) 尽量改变Class而不是Style,使用classList代替classNamec) 避免使用document.writed) 减少drawImage Viewport可以加速页面的渲染,请使用以下代码 1< meta name=”viewport” content=”width=device-width, initial-scale=1″> 动画优化123a) 尽量使用CSS3动画b) 合理使用requestAnimationFrame动画代替setTimeoutc) 适当使用Canvas动画 5个元素以内使用css动画,5个以上使用Canvas动画(iOS8可使用webGL) GPU加速12CSS中以下属性(CSS3 transitions、CSS3 3D transforms、Opacity、Canvas、WebGL、Video)来触发GPU渲染,请合理使用PS:过渡使用会引发手机过耗电增加 资料参考: 如何做到一秒渲染一个移动页面HTML5与CSS3语法提供浏览器兼容性测试及使用建议:http://html5please.com/ meta相关总结HTML5页面窗口自动调整到设备宽度,并禁止用户缩放页面 1<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" /> 忽略将页面中的数字识别为电话号码 1<meta name="format-detection" content="telephone=no" /> 忽略Android平台中对邮箱地址的识别 1<meta name="format-detection" content="email=no" /> 当网站添加到主屏幕快速启动方式,可隐藏地址栏,仅针对ios的safari 12<meta name="apple-mobile-web-app-capable" content="yes" /><!-- ios7.0版本以后,safari上已看不到效果 --> 将网站添加到主屏幕快速启动方式,仅针对ios的safari顶端状态条的样式 12<meta name="apple-mobile-web-app-status-bar-style" content="black" /><!-- 可选default、black、black-translucent --> 移动端touch事件(区分webkit 和 winphone)当用户手指放在移动设备在屏幕上滑动会触发的touch事件 以下支持webkit: 1234touchstart——当手指触碰屏幕时候发生。不管当前有多少只手指touchmove——当手指在屏幕上滑动时连续触发。通常我们再滑屏页面,会调用event的preventDefault()可以阻止默认情况的发生:阻止页面滚动touchend——当手指离开屏幕时触发touchcancel——系统停止跟踪触摸时候会触发。例如在触摸过程中突然页面alert()一个提示框,此时会触发该事件,这个事件比较少用 以下支持windows phone 8: 123MSPointerDown——当手指触碰屏幕时候发生。不管当前有多少只手指MSPointerMove——当手指在屏幕上滑动时连续触发。通常我们再滑屏页面,会调用css的html{-ms-touch-action: none;}可以阻止默认情况的发生:阻止页面滚动MSPointerUp——当手指离开屏幕时触发 手机拍照和上传图片<input type="file">的accept 属性 1234<!-- 选择照片 --><input type=file accept="image/*"><!-- 选择视频 --><input type=file accept="video/*"> 使用总结: 1234ios 有拍照、录像、选取本地图片功能部分android只有选取本地图片功能winphone不支持input控件默认外观丑陋 移动端手势总结主要用户操作 手势的具体操作 触摸屏手势 手势的具体操作","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"jQuery常用方法归纳总结","date":"2016-08-24T12:05:01.000Z","path":"2016/08/24/jQuery常用方法归纳总结/","text":"有必要对jQuery使用常用的方法进行归纳,碎片化时间看看加深印象 $.grep()1$.grep( array, function(elementOfArray, indexInArray) [, invert ] ) 功能:查找满足过滤函数的数组元素: 12345678910<script src="js/jquery1.42.min.js"></script> <script type="text/javascript"> $(function () { var arr = [23,45,5,1,4,67,8,100,-2]; var arrGrep = $.grep(arr, function (element,index) { return (index<5)&&(element != 4);//整体返回一个数组 }) alert(arrGrep);//23,45,5,1 }) </script> $.map()1$.map( array, callback(elementOfArray, indexInArray) ) 功能:将一个数组中的所有元素转换到另一个数组中。 12345678910111213<script src="js/jquery1.42.min.js"></script> <script type="text/javascript"> $(function () { var arr = [5,1,4,67,8,100,-2]; var arrMap = $.map(arr, function (element,index) { // return (index<3)&&(element != 4);这里按布尔值返回 if(index<3 && element< 4){ return element; } }); alert(arrMap);//1 }) </script> mouseover()/mouserout()当鼠标进入/离开某个元素或它的后代元素时触发mouseover/mouseout事件。mouseover事件大多数时候会与 mouseout 事件一起使用。 mouseover/mouserout事件由于冒泡机制,经常在不需要的时候不小心触发,从而导致一些脚本问题。 mouseenter()/mouseleave()mouseenter/mouseleave当且仅当鼠标进入被选元素时才触发,当鼠标穿过任何子元素时不会触发。它不关心目标元素是否有子元素。 focusin()和focusout().focusin():一个元素或它的子元素得到焦点时触发此事件.focusout():一个元素或它的子元素失去焦点时触发此事件 与 focus() 方法不同的是,focusin() 方法在任意子元素获得焦点时也会触发。 123456789<body> <p><input type="text"> <span>focusin fire</span></p> <p><input type="password"> <span>focusin fire</span></p> <script> $( "p" ).focusin(function() { $( this ).find( "span" ).css( "display", "inline" ).fadeOut( 1000 ); }); </script></body> eq()和get().get(): 通过jQuery对象获取一个对应的DOM元素。.eq():从集合的一个元素中构造新的jQuery对象 eq返回的是一个jQuery对象,get返回的是一个DOM对象。举个例子: 12$( "li" ).get( 0 ).css("color", "red"); //错误$( "li" ).eq( 0 ).css("color", "red"); //正确 那么,什么是DOM对象,什么又是jQuery对象呢? DOM对象就是用js获得的对象,而juqery对象是用jQuery类库的选择器获得的对象。 如:var $obj = $("div");//jQuery对象 get方法本质上是把jQuery对象转换成DOM对象,但是css属于jQuery构造器的,DOM是不存在这个方法的,如果需要用jQuery的方法,我们必须这样写: 12var li = $("li").get(0);$(li).css("color","black");//用$包装 filter()1filter()方法:筛选出与指定表达式匹配的元素集合。 这个方法用于缩小匹配的范围。用逗号分隔多个表达式。 filter(expression):(字符串|函数)如果参数是字符串,则制定jQuery选择器,用于从包装集里删除所有与选择器不匹配的元素,最后留下与选择器匹配的元素;如果参数是函数,则用于确定筛选条件。为包装集里的每一个元素各调用一次该函数,函数调用返回值为false的任何元素都会从包装集里删除。 以下代码意为:保留第一个以及带有select类的元素 HTML 代码: 1<p>Hello</p><p>Hello Again</p><p class="selected">And Again</p> jQuery 代码: 1$("p").filter(".selected, :first") 结果: 1<p>Hello</p>, <p class="selected">And Again</p> 再看一个function的例子,一个函数用来作为测试元素的集合。它接受一个参数index,这是元素在jQuery集合的索引。在函数,this指的是当前的DOM元素。 HTML 代码: 1<p><ol><li>Hello</li></ol></p><p>How are you?</p> jQuery 代码: 123$("p").filter(function(index) { return $("ol", this).length == 0;}); 结果: 1<p>How are you?</p> .bind()、.live()和.delegate()方法.bind():绑定事件处理函数的最基本方式是使用.bind()方法。它和live()方法一样,接受两个参数: 1.bind(event type, event handler) 两种绑定事件处理函数的方法: 1234567$(document).ready(function(){ $('.mydiv').bind('click',test); function test(){ alert("Hello World!"); }}); 事件处理函数也可以使用匿名函数,如下所示: 12345$(document).ready(function(){ $("#mydiv").bind("click",function(){ alert("Hello World!"); }) }); .live():live方法和bind方法的唯一区别在于.live()不仅作用于DOM中当前存在的元素,还作用于将来可能存在(动态生成)的元素 123456789$(document).ready(function(){ $('.box').live('click',function(){ $(this).clone().appendTo('.container'); }); }); <div class="container"> <div class="box"></div> </div> 使用live方法绑定事件的缺点在于它无法使用链式调用,那有没有既可以像live方法那样绑定事件,又可以支持链式调用的方法呢?答案就是下面的delegate方法。 delegate()方法:为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。从jQuery 1.7开始,.delegate()已经被.on()方法取代。语法: 1$(selector).delegate(childSelector,event type,function) 参数说明: childSelector 必需。规定要附加事件处理程序的一个或多个子元素。 event 必需。规定附加到元素的一个或多个事件。由空格分隔多个事件值。必须是有效的事件。 function 必需。规定当事件发生时运行的函数。 12345$(document).ready(function(){ $('.container').delegate('.box','click',function(){ $(this).clone().appendTo('.container'); }); }); delegate()会在以下两个情况下使用到: 1、如果你有一个父元素,需要给其下的子元素添加事件,这时你可以使用delegate()了,代码如下: 12345$("ul").delegate("li", "click", function(){$(this).hide();}); 2、当元素在当前页面中不可用时,可以使用delegate() end()方法1end()方法:在jquery命令链内调用,以便退回到前一个包装集。 每次过滤方法都会被压入栈中。当我们需要返回到前一个状态时,我们可以使用end() 进行出栈操作,来返回栈中的前一个状态。 end() 方法结束当前链条中的最近的筛选操作,并将匹配元素集还原为之前的状态。 123456789101112131415<head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title></title> <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script></head><body> <ul class="one"> <li class="two">item 1</li> <li>item 2</li> <li class="three">item 3</li></ul><script type="text/javascript"> $('ul.one').find(".two").css("color","red").find('.three').css("background","blue");</script> 在上面的代码例子中,我们只会看到item 1的字体颜色改变了,而背景颜色没有改变。这是因为第二个find()方法之前的状态返回的是红色字体的class值为two的对象,因此,第二次find()只会查找<ul class="one"> 中的.two,使用end()方法修改该链式操作的代码如下: 123<script type="text/javascript"> $('ul.one').find(".two").css("color","red").end().find('.three').css("background","blue");</script> end()方法在这里是 返回调用 find() 之前的状态,也就是$('ul.one') toggleClass()12 `toggleClass()方法:`如果在元素中指定类名称不存在,则添加指定类名称;如果元素已经拥有指定类名称,则从元素中删除指定类名称。 1css(name,value)方法:设定指定的值到每个已匹配元素的指定的css样式属性 wrap()和wrapInner()12 `wrap()和wrapInner():`前者把所有匹配的元素用其他元素的结构化标记包裹起来;后者将每一个匹配的元素的子内容(包括文本节点)用一个HTML结构包裹起来。 看下面一个wrap()的例子:用原先div的内容作为新div的class,并将每一个元素包裹起来 HTML 代码: 1234<div class="container"> <div class="inner">Hello</div> <div class="inner">Goodbye</div></div> jQuery 代码: 123$('.inner').wrap(function() { return '<div class="' + $(this).text() + '" />';}); 结果: 12345678<div class="container"> <div class="Hello"> <div class="inner">Hello</div> </div> <div class="Goodbye"> <div class="inner">Goodbye</div> </div></div> 接着再看下面一个wrapInner()的例子: 用原先div的内容作为新div的class,并将每一个元素包裹起来 HTML 代码: 1234<div class="container"> <div class="inner">Hello</div> <div class="inner">Goodbye</div></div> jQuery 代码: 123$('.inner').wrapInner(function() { return '<div class="' + $(this).text() + '" />';}); 结果: 12345678<div class="container"> <div class="inner"> <div class="Hello">Hello</div> </div> <div class="inner"> <div class="Goodbye">Goodbye</div> </div></div> detach、empty和remove方法.detach( [selector ] ):从DOM中去掉所有匹配的元素。当需要移走一个元素,不久又将该元素插入DOM时,就需要用到detach方法。 .empty():这个方法不仅移除子元素(和其他后代元素),同样移除元素里的文本。因为,根据说明,元素里任何文本字符串都被看做是该元素的子节点。 .remove( [selector ] ):将元素从DOM中移除,同时移除元素上的事件及 jQuery 数据 empty()的例子: 123456789 <ul class="one"> <li class="two">item 1</li> <li>item 2</li> <li class="three">item 3</li></ul><script type="text/javascript"> $(".two").empty();//item 1 文本节点被移除,li的小圆点还在,证明li没有被移除</script> 看下面一个remove()例子: 描述:从DOM中把所有段落删除 HTML 代码: 1<p>Hello</p> how are <p>you?</p> jQuery 代码: 1$("p").remove(); 结果: 1how are val()方法1val():获得匹配元素的当前值。 描述:获取文本框中的值 jQuery 代码: $("input").val(); jQuery 代码: 1$("input").val("hello world!"); each()和map()12each()和map()方法:each返回的是原来的数组,并不会新创建一个数组。而map方法会返回一个新的数组。如果在没有必要的情况下使用map,则有可能造成内存浪费。 each方法: 定义一个空数组,通过each方法,往数组添加ID值;最后将数组转换成字符串后,alert这个值; 12345678$(function(){ var arr = []; $(":checkbox").each(function(index){ arr.push(this.id); }); var str = arr.join(","); alert(str);}) map方法: 将每个:checkbox执行return this.id;并将这些返回值,自动的保存为jQuery对象,然后用get方法将其转换成原生Javascript数组,再使用join方法转换成字符串,最后alert这个值; 123456$(function(){ var str = $(":checkbox").map(function() { return this.id; }).get().join(); alert(str);}) 当有需一个数组的值的时候,用map方法,很方便。 更加详细的讨论,请点击我的另一篇文章:详解jQuery内置函数map()和each()的使用 $.each()jQuery的$(selector).each()函数可以遍历循环选中的子元素,而jQuery的$.each()函数则可以遍历任何集合,包括对象和数组,它接收要遍历的集合以及一个回调函数,回调函数每次传递一个数组的下标和这个下标所对应的数组的值。 123$.each(array,callback);$.each(object,callback); 数组实例1234$.each( [ "one", "two", "three" ], function( i, l ){ alert( "index #" + i + ": " + l );});callback(索引,索引值) DEMO: 123index 0: oneindex 1: two;index 2: three 对象实例1234$.each({ name: "trigkit4", lang: "JS" }, function( k, v ) { alert( "Key: " + k + ", Value: " + v );});callback(键,值) Demo: 12Key: name, Value: trigkit4Key: lang, Value: JS .trigger()描述: 根据绑定到匹配元素的给定的事件类型执行所有的处理程序和行为。 当相应的事件发生时,任何通过.on()、.bind()或一个快捷方法绑定的事件处理程序将被触发。但是,它们可以用.trigger()方法手动触发 1234567<script type="text/javascript"> $(document).bind('abc',function(){ console.log('hello');}); $(document).trigger('abc'); //Output 'hello';</script> .attr()和.prop().attr():获取匹配的元素集合中的第一个元素的属性的值 或 设置每一个匹配元素的一个或多个属性。 .prop():同上jQuery 1.6之前 ,.attr()方法在取某些 attribute 的值时,会返回 property 的值,这就导致了结果的不一致。从 jQuery 1.6 开始, .prop()方法 方法返回 property 的值,而 .attr() 方法返回 attributes 的值。 例如, selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked, 和 defaultSelected 应使用.prop()方法进行取值或赋值。 他们没有相应的属性(attributes),只有特性(property)。 .after()和.insertAfter()1.after()描述:在所有段落中后插入一个jQuery对象(类似于一个DOM元素数组)。 HTML 代码: 1<b>Hello</b><p>I would like to say: </p> jQuery 代码: 1$("p").after( $("b") ); 结果: 1<p>I would like to say: </p><b>Hello</b> 2.insertAfter()描述:把所有段落插入到一个元素之后。与 $("#foo").after("p")相同 HTML 代码: 1<p>I would like to say: </p><div id="foo">Hello</div> jQuery 代码: 1$("p").insertAfter("#foo"); 结果: 1<div id="foo">Hello</div><p>I would like to say: </p> .before()和.insertBefore()3.before()描述:在所有段落中前插入一个jQuery对象(类似于一个DOM元素数组)。 HTML 代码: 1<p>I would like to say: </p><b>Hello</b> jQuery 代码: 1$("p").before( $("b") ); 结果: 1<b>Hello</b><p>I would like to say: </p> .append()和.appendTo()4.append()描述:向所有段落中追加一些HTML标记。 HTML 代码: 1<p>I would like to say: </p> jQuery 代码: 1$("p").append("<b>Hello</b>"); 结果: 1<p>I would like to say: <b>Hello</b></p> 5.appendTo()描述:新建段落追加div中并加上一个class HTML 代码: 1<div></div><div></div> jQuery 代码: 12345$("<p/>") .appendTo("div") .addClass("test") .end() .addClass("test2"); 结果: 12<div><p class="test test2"></p></div><div><p class="test"></p></div> .prepend()和.prependTo()6.prepend()描述:向所有段落中前置一个jQuery对象(类似于一个DOM元素数组)。 HTML 代码: <p>I would like to say: </p><b>Hello</b> jQuery 代码: 1$("p").prepend( $("b") ); 结果: 1<p><b>Hello</b>I would like to say: </p> 7.prependTo()描述:把所有段落追加到ID值为foo的元素中。 HTML 代码: 1<p>I would like to say: </p><div id="foo"></div> jQuery 代码: 1$("p").prependTo("#foo"); 结果: 1<div id="foo"><p>I would like to say: </p></div> 总结123456789101. .insertAfter()和.after():在现存元素的外部,从后面插入元素 2. .insertBefore()和.before():在现存元素的外部,从前面插入元素 3. .appendTo()和.append():在现存元素的内部,从后面插入元素 4. .prependTo()和.prepend() :在现存元素的内部,从前面插入元素 .data( key, value ).data() 方法允许我们在DOM元素上绑定任意类型的数据, 1$("div").data("test", { first: 16, last: "pizza!" }); .promise( [type ] [, target ] )在 Javascript 中,有外一种异步处理模式被叫做 Promises, CommonJS 标准委员会于是发布了一个规范,就把这个 API 叫做Promises 了。 Promise 背后的概念非常简单,有两部分: 12Deferreds,定义工作单元,Promises,从 Deferreds 返回的数据。 Promise 不同于回调的很重要的一个点是,你可以在 Promise 状态变成执行(resolved)之后追加处理句柄。这就允许你传输数据,而忽略它是否已经被应用获取,然后缓存它,等等之类的操作,因此你可以对数据执行操作,而不管它是否已经或者即将可用。 你可以给一个 promise 追加多个处理(then())。Promise API 好玩的地方在于允许链式处理: 123456<!-- lang: js -->promise .then(doSomething) .then(doSomethingElse) .then(doSomethingMore) .catch(logError);","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"jQuery使用总结","date":"2016-08-12T12:05:01.000Z","path":"2016/08/12/jQuery使用总结/","text":"window.onload 和$(document).ready() 我 window.onload $(document).ready() 执行时机 必须等待网页中所有的内容加载完毕后(包括图片)才能执行 网页中所有DOM结构绘制完毕后就执行,可能DOM元素关联的东西并没有加载完 编写个数 不能同时编写多个,以下代码无法正确执行:window.onload =function({alert(“test1”);}window.onload = function(){alert(“test2”);}结果只会输出”test2” 能同时编写多个 简化写法 无 $(document).ready(function(){});可以简写成$(function(){}); 逐行分析jQuery123456789(function(){ (21,94) 定义了一些变量和函数 jquery = function(){}; (96,283)给JQ对象,添加一些方法和属性 (283,347)extend:JQ的继承方法 (349,817)jQuery.extend():扩展一些工具方法 (887,2859)Sizzle:复杂选择器的实现 (2880,3042)callbacks:回调对象 (8826)window.jQuery = window.$ = jQuery ;})() 像$(“div”)返回的就是一个对象,对象后面就可以添加属性和方法类似$.trim(),$.proxy()这些方法就是工具方法,他的前面不是对象,而是$,$ 就是函数,在函数下面扩展方法就是扩展静态方法,就是工具方法。工具方法即可给jquery使用,也可以给原生的js使用 1.创建DOM元素:可以通过向$()函数传递一个包含HTML标记的字符串动态地创建DOM元素。例如,可以创建一个新的段落元素。如: 1$("<p>Hi</p>") 2.通过索引获取元素因为jQuery允许我们将包装集当成javascript数组,所以我们可以使用简单的数组下标来获取包装序列中的任何元素。比如,从页面上带有alt属性的所有<img>元素的包装集中获取第一个元素,可以使用如下语句: 1var img = $('img[alt]')[0]; 解决双重提交问题 123$("form").submit(function(){ $(":submit",this).attr("disabled","disabled");}); 我们通过:submit选择器获取表单中的所有提交按钮,并且将其disabled属性设置为”disabled”,this指针总是指向触发此事件的页面元素,在这里,this指向表单实例(form) 4.添加多个类名我们可以为每个元素指定任意数量的类名,在HTML中,class属性用来提供以空格分隔,由多个类名组成的字符串。例如: 1<div class = "one two three"></div> 一、选择网页元素 jQuery的基本设计和主要用法,就是”选择某个网页元素,然后对其进行某种操作”。这是它区别于其他函数库的根本特点。 使用jQuery的第一步,往往就是将一个选择表达式,放进构造函数jQuery()(简写为$),然后得到被选中的元素。 选择表达式可以是CSS选择器: 123456789101. $(document)//选择整个文档对象 2. 3. $('#myId')//选择ID为myId的网页元素 4. 5. $('div.myClass')//选择class为myClass的div元素 6. 7. $('input[name=first]')//选择name属性等于first的input元素 也可以是jQuery特有的表达式: 123456789101112131415161. $('a:first')//选择网页中第一个a元素 2. 3. $('tr:odd')//选择表格的奇数行 4. 5. $('#myForm :input')//选择表单中的input元素 6. 7. $('div:visible') //选择可见的div元素 8. 9. $('div:gt(2)')//选择所有的div元素,除了前三个 10. 11. $('div:animated')//选择当前处于动画状态的div元素 改变结果集 如果选中多个元素,jQuery提供过滤器,可以缩小结果集: 12345$('div').has('p'); //选择包含p元素的div元素 $('div').not('.myClass'); //选择class不等于myClass的div元素 $('div').filter('.myClass'); //选择class等于myClass的div元素 $('div').first(); //选择第1个div元素 $('div').eq(5); //选择第6个div元素 有时候,我们需要从结果集出发,移动到附近的相关元素,jQuery也提供了在DOM树上的移动方法: 123456789101112131. $('div').next('p'); //选择div元素后面的第一个p元素 2. $('div').parent(); //选择div元素的父元素 3. $('div').closest('form'); //选择离div最近的那个form父元素 4. $('div').children(); //选择div的所有子元素 5. $('div').siblings(); //选择div的同级元素 链式操作 选中网页元素以后,就可以对它进行某种操作。 jQuery允许将所有操作连接在一起,以链条的形式写出来,比如: 11. $('div').find('h3').eq(2).html('Hello'); 分解开来,就是下面这样: 12345671. $('div’) //找到div元素 2. .find('h3’) //选择其中的h3元素 3. .eq(2) //选择第3个h3元素 4. .html('Hello'); //将它的内容改为Hello 这是jQuery最令人称道、最方便的特点。它的原理在于每一步的jQuery操作,返回的都是一个jQuery对象,所以不同操作可以连在一起。 那么,如何判断是否可以使用jquery链式操作呢? 除了获取某些数据的函数,比如获取属性值”attr(name)“,获取集合大小”size()“,这些函数明显是返回数据的。除了这些函数之外的jquery函数都可以用于链式操作,比如设置属性attr(name.value) jQuery还提供了.end()方法,使得结果集可以后退一步: 12345671. $('div') 2. .find('h3') 3. .eq(2) 4. .html('Hello') 5. .end()//退回到选中所有的h3元素的那一步 6. .eq(0)//选中第一个h3元素 7. .html('World'); //将它的内容改为World .end():回到最近的一个”破坏性”操作之前。如果之前没有破坏性操作,则返回一个空集。所谓的”破坏性”就是指任何改变所匹配的jQuery元素的操作。 示例描述:选取所有的p元素,查找并选取span子元素,然后再回过来选取p元素 HTML 代码: 1<p><span>Hello</span>,how are you?</p> jQuery 代码: 1$("p").find("span").end() 结果: 1<p><span>Hello</span> how are you?</p> 四、元素的操作:取值和赋值 操作网页元素,最常见的需求是取得它们的值,或者对它们进行赋值。 jQuery使用同一个函数,来完成取值(getter)和赋值(setter)。到底是取值还是赋值,由函数的参数决定。 121. $('h1').html(); //html()没有参数,表示取出h1的值 2. $('h1').html('Hello'); //html()有参数Hello,表示对h1进行赋值 常见的取值和赋值函数如下: 1234561. .html() 返回或设置被选元素的内容 (inner HTML) 2. .text() 取出或设置text内容 3. .attr() 取出或设置某个属性的值 4. .width() 取出或设置某个元素的宽度 5. .height() 取出或设置某个元素的高度 6. .val() 取出或设置html内容 取出某个表单元素的值 需要注意的是,如果结果集包含多个元素,那么赋值的时候,将对其中所有的元素赋值;取值的时候,则是只取出第一个元素的值(.text()例外,它取出所有元素的text内容)。 五、元素的操作:移动.insertAfter(),把div元素移动p元素后面: 1$('div').insertAfter('p'); .after(),把p元素加到div元素前面: 1$('p').after('div'); 使用这种模式的操作方法,一共有四对 123456789101. .insertAfter()和.after():在现存元素的外部,从后面插入元素 2. .insertBefore()和.before():在现存元素的外部,从前面插入元素 3. .appendTo()和.append():在现存元素的内部,从后面插入元素 4. .prependTo()和.prepend() :在现存元素的内部,从前面插入元素 相关方法的详细使用请查看我的另一篇文章:jquery常用方法详解 六、元素的操作:复制、删除和创建 复制元素使用.clone() 删除元素使用.remove()和.detach()。两者的区别在于,前者不保留被删除元素的事件,后者保留,有利于重新插入文档时使用。 清空元素内容(但是不删除该元素)使用.empty()。 创建新元素的方法非常简单,只要把新元素直接传入jQuery的构造函数就行了: 123* $('<p>Hello</p>'); * $('<li class="new">new list item</li>'); * $('ul').append('<li>list item</li>'); 七、工具方法 除了对选中的元素进行操作以外,jQuery还提供一些工具方法(utility),不必选中元素,就可以直接使用。 1工具方法即可给jquery使用,也可以给原生的js使用 常用的工具方法有以下几种: 1234567891011121314151617181920212223242526272829303132331. $.trim() 去除字符串两端的空格。2. 3. $.each() 遍历一个数组或对象。 4. 5. $.inArray() 返回一个值在数组中的索引位置。如果该值不在数组中,则返回-1。 6. 7. $.grep() 返回数组中符合某种标准的元素。 8. 9. $.extend() 将多个对象,合并到第一个对象。 10. 11. $.makeArray() 将对象转化为数组。 12. 13. $.type() 判断对象的类别(函数对象、日期对象、数组对象、正则对象等等)。 14. 15. $.isArray() 判断某个参数是否为数组。 16. 17. $.isEmptyObject() 判断某个对象是否为空(不含有任何属性)。 18. 19. $.isFunction() 判断某个参数是否为函数。 20. 21. $.isPlainObject() 判断某个参数是否为用"{}"或"new Object"建立的对象。 22. 23. $.support() 判断浏览器是否支持某个特性。 八、事件操作 jQuery可以对网页元素绑定事件。根据不同的事件,运行相应的函数。 1231. $('p').click(function(){ 2. alert('Hello'); 3. }); 目前,jQuery主要支持以下事件: 1234567891011121314151617181920212223242526271. .blur() 表单元素失去焦点。 2. .change() 表单元素的值发生变化 3. .click() 鼠标单击 4. .dblclick() 鼠标双击 5. .focus() 表单元素获得焦点 6. .focusin() 子元素获得焦点 7. .focusout() 子元素失去焦点 8. .hover() 同时为mouseenter和mouseleave事件指定处理函数 9. .keydown() 按下键盘(长时间按键,只返回一个事件) 10. .keypress() 按下键盘(长时间按键,将返回多个事件) 11. .keyup() 松开键盘 12. .load() 元素加载完毕 13. .mousedown() 按下鼠标 14. .mouseenter() 鼠标进入(进入子元素不触发) 15. .mouseleave() 鼠标离开(离开子元素不触发) 16. .mousemove() 鼠标在元素内部移动 17. .mouseout() 鼠标离开(离开子元素也触发) 18. .mouseover() 鼠标进入(进入子元素也触发) 19. .mouseup() 松开鼠标 20. .ready() DOM加载完成 21. .resize() 浏览器窗口的大小发生改变 22. .scroll() 滚动条的位置发生变化 23. .select() 用户选中文本框中的内容 24. .submit() 用户递交表单 25. .toggle() 根据鼠标点击的次数,依次运行多个函数 26. .unload() 27. 用户离开页面 以上这些事件在jQuery内部,都是.bind()的便捷方式。使用.bind()可以更灵活地控制事件,比如为多个事件绑定同一个函数: 1234561. $('input').bind( 2. 'click change', //同时绑定click和change事件 3. function(){ 4. alert('Hello'); 5. } 6. ); 有时,你只想让事件运行一次,这时可以使用.one()方法。 1231. $("p").one("click", function(){ 2. alert("Hello"); //只运行一次,以后的点击不会运行 3. }); .unbind()用来解除事件绑定。 11. $('p').unbind('click'); 所有的事件处理函数,都可以接受一个事件对象(event object)作为参数,比如下面例子中的e: 1231. $("p").click(function(e){ 2. alert(e.type); //"click" 3. }); 这个事件对象有一些很有用的属性和方法: event.pageX 事件发生时,鼠标距离网页左上角的水平距离 event.pageY 事件发生时,鼠标距离网页左上角的垂直距离event.type 事件的类型(比如click) event.which 按下了哪一个键 event.data在事件对象上绑定数据,然后传入事件处理函数 event.target 事件针对的网页元素 event.preventDefault() 阻止事件的默认行为(比如点击链接,会自动打开新页面)event.stopPropagation() 停止事件向上层元素冒泡 在事件处理函数中,可以用this关键字,返回事件针对的DOM元素: 123456* $('a').click(function(){ * if ($(this).attr('href').match('evil')){//如果确认为有害链接 * e.preventDefault(); //阻止打开 * $(this).addClass('evil'); //加上表示有害的class * } * }); 有两种方法,可以自动触发一个事件。一种是直接使用事件函数,另一种是使用.trigger()或.triggerHandler()。 12$('a').click();$('a').trigger('click'); 九、特殊效果 jQuery允许对象呈现某些特殊效果。 1$('h1').show(); //展现一个h1标题 常用的特殊效果如下: 123456789.fadeIn() 淡入.fadeOut() 淡出.fadeTo() 调整透明度.hide() 隐藏元素.show() 显示元素.slideDown() 向下展开.slideUp() 向上卷起.slideToggle() 依次展开或卷起某个元素.toggle() 依次展示或隐藏某个元素 除了.show()和.hide(),所有其他特效的默认执行时间都是400ms(毫秒),但是你可以改变这个设置。 12* $('h1').fadeIn(300); // 300毫秒内淡入 * $('h1').fadeOut('slow'); //缓慢地淡出 在特效结束后,可以指定执行某个函数。 11. $('p').fadeOut(300, function(){$(this).remove(); }); 更复杂的特效,可以用.animate()自定义。 123456781. $('div').animate( 2. { 3. left : "+=50",//不断右移 4. opacity : 0.25 //指定透明度 5. },6. 300,// 持续时间 7. function(){ alert('done!'); }//回调函数 8. ); .stop()和.delay()用来停止或延缓特效的执行。 $.fx.off如果设置为true,则关闭所有网页特效。 几个常见的筛选选择器filter():筛选出与指定表达式匹配的元素集合。这个方法用于缩小匹配的范围。用逗号分隔多个表达式描述:保留子元素中不含有ol的元素。 HTML 代码: 1<p><ol><li>Hello</li></ol></p><p>How are you?</p> jQuery 代码: 123$("p").filter(function(index) { return $("ol", this).length == 0;}); 结果: 1<p>How are you?</p> silce():选取一个匹配的子集 描述:选择第一个p元素 HTML 代码: 1<p>Hello</p><p>cruel</p><p>World</p> jQuery 代码: 1$("p").slice(0, 1).wrapInner("<b></b>"); 结果: 1<p><b>Hello</b></p> 另附:jquery常用方法详解如何使用JQuery CDN?推荐使用官方的CDN节点,使用代码如下: 121. <script src="//code.jquery.com/jquery-1.11.0.min.js"> </script> 2. <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"> </script> jquery与原生的关系: 12345678910111213141516 <script type="text/javascript"> $(function(){ $('#div1').click(function(){ //alert( $(this).html()); //jq的写法 //alert( this .innerHTML ); //js alert( $(this).innerHTML ); //错误的写法,jq与原生不能混用 alert ( this.html()); //也是错误的 }) }) </script></head><body> <div id="div1">abcd</div></body>","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Ajax封装","date":"2016-07-20T12:05:01.000Z","path":"2016/07/20/Ajax封装/","text":"之前的项目中,因为用到了前后端分离的思路,所以都要通过Ajax来请求数据然后把数据渲染到页面上,一开始想过直接引用Jquery,但感觉就使用Jquery的Ajax函数,有点太浪费,所以就自己撸了一个Ajax函数。本文由浅入深,一步一步带你封装属于自己的Ajax库。 Ajax简介 Asynchronous Javascript And XML (异步的JavaScript和XML) 它并不是一种单一的技术,而是有机利用一系列交互式网页应用相关的技术所形成的结合体 Ajax是一种用于创建快速动态网页的技术。在前台与后台进行数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,实现局部更新。 1、优点 页面无刷新,用户体验好。 异步通信,更加快的响应能力。 减少冗余请求,减轻了服务器负担。 基于标准化的并被广泛支持的技术 2、应用场景 场景 1. 数据验证 场景 2. 按需取数据 场景 3. 自动更新页面 … 说了这么多,接下来来点干货。 创建ajax的步骤 Ajax的原理简单来说通过XMLHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。原生创建ajax可分为以下四步 1、创建XMLHttpRequest对象123456789function createRequest (){ if (window.XMLHttpRequest) { //IE6以上 xhr = new XMLHttpRequest(); } else { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } return xhr;} 2、准备请求1xhr.open(method,url,async); 第一个参数表示请求类型的字符串,其值可以是GET或者POSTGET请求: 1xhr.open("GET",demo.php?name=hzzly&age=21,true); POST请求: 1xhr.open("POST",demo.php,true); 第二个参数是要作为请求发送目标的URL。 第三个参数是true或false,表示请求是以异步还是同步的模式发出。(默认为true,一般不建议为false) 3、发送请求1xhr.send(); GET请求: 12xhr.open("GET",demo.php?name=hzzly&age=21,true);xhr.send(); POST请求 123xhr.open("POST",demo.php,true);xhr.setRequestHeder("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");xhr.send(param) 4、处理响应12345xhr.onreadystatechange = function(){ if(xhr.readyState == 4 && xhr.status == 200){ console.log(xhr.responseText); }} onreadystatechange:当处理过程发生变化的时候执行下面的函数 12> readyState> > :ajax处理过程 0:请求未初始化(还没有调用 open()) 1:请求已经建立,但是还没有发送(还没有调用 send()) 2:请求已发送,正在处理中(通常现在可以从响应中获取内容头) 3:请求在处理中;通常响应中已有部分数据可用了,但是服务器还没有完成响应的生成 4:响应已完成;您可以获取并使用服务器的响应了 12> status> > 属性: 200: “OK” 404: 未找到页面 responseText:获得字符串形式的响应数据,可以用JSON.parse(xhr.responseText)转化为JSON对象 封装例子 1.get请求函数 12345678910111213141516171819202122232425262728293031323334353637383940/** * 一个简单的get请求 * @param {String} url 请求地址,文件名 * @param {Function} fnSucc 请求成功时执行的函数 * @param {Function} fnFaild 请求失败执行的函数 */function Get(url, fnSucc, fnFaild) { //1.创建ajax对象 var xhr = null; /** * 此处必须需要使用window.的方式,表示为window对象的一个属性.不存在时值为undefined. * 进入else若直接使用XMLHttpRequest在不支持的情况下会报错 **/ if (window.XMLHttpRequest) { //IE6以上 xhr = new XMLHttpRequest(); } else { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } //2.连接服务器 //open(方法,url,是否异步) xhr.open("GET", url, true); //3.发送请求 xhr.send(); //4.接收返回 //OnRedayStateChange事件 xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { //alert("成功" + xhr.responseText); fnSucc(xhr.responseText); } else { //alert("服务器响应失败!"); if (fnFaild) { fnFaild(); } } } };} 2.get与post结合的请求函数 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364/** * AJAX函数封装 * @param {string} url 请求地址(必须) * @param {object} options 发送请求的选项参数 * @config {string} [options.type] 请求发送的类型。默认为GET。 * @config {Object} [options.data] 需要发送的数据。 * @config {Function} [options.onsuccess] 请求成功时触发。(必须) * @config {Function} [options.onfail] 请求失败时触发。 */function AJAX(url, options) { //1.创建ajax对象 var xhr = null; /** * 此处必须需要使用window.的方式,表示为window对象的一个属性.不存在时值为undefined,进入else * 若直接使用XMLHttpRequest,在不支持的情况下会报错 **/ if (window.XMLHttpRequest) { //IE6以上 xhr = new XMLHttpRequest(); } else { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } //2.连接服务器 //open(方法,url,是否异步) var param = ""; //请求参数。 //只有data存在,且为对象使才执行 var data = options.data ? options.data : -1; //缓存data if (typeof (data) === "object") { for (var key in data) { //请求参数拼接 if (data.hasOwnProperty(key)) { param += `${key}=${data[key]}&`; } } param.replace(/&$/, ""); } else { param = "timestamp=" + new Date().getTime(); } //3.发送请求 var type = options.type ? options.type.toUpperCase() : "GET"; if (type === "GET") { xhr.open("GET", `${url}?${param}`, true); xhr.send(); } else { xhr.open("POST", url, true); xhr.setRequestHeder("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"); xhr.send(param); } //4.接收返回 //OnRedayStateChange事件 xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { //请求成功。形参为获取到的字符串形式的响应数据 options.onsuccess(xhr.responseText); } else { //先判断是否存在请求失败函数 //存在时,形参为XMLHttpRequest对象,便于进行错误进行处理 if (options.onfail) { options.onfail(xhr); } } } };}","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"分析css中选择器的效率","date":"2016-06-18T12:05:01.000Z","path":"2016/06/18/分析css中选择器的效率/","text":"我们都知道,CSS具有叠加性(同一个元素被多条样式规则指定),继承性(后代元素会继承前辈元素的一些样式和属性)和优先级 (由于CSS的叠加性和继承性,将产生优先级,这指的是哪条样式规则会最终作用于指定的元素,他只遵循一条规则,指定的越具体,优先级越高) 由上可知,选择器指定的越具体,那么他的优先级就越高, 在这里,我们来总结一下css的选择器: 一、基本选择器(标签选择器、通用选择器、类和ID选择器) 选择器 描述 CSS版本 E 标签选择器,匹配所有使用E标签的元素 * 通用元素选择器,匹配任何元素 .info class选择器,匹配所有class属性中包含info的元素 #footer id选择器,匹配所有id属性等于footer的元素 二、多元素的组合选择器(标签选择器[群组选择器]、后代选择器、子元素选择器、相邻选择器) 选择器 描述 CSS版本 E,F 多元素选择器,同时匹配所有E元素或F元素,E和F之间用逗号隔开 E F 包含选择符,匹配所有被E元素包含的F元素 E>F 子元素选择器,匹配所有E元素的儿子元素F E+F 毗邻元素选择器,匹配所有紧随E元素之后的同级元素F E~F 匹配任何E标签之后的同级F标签 三、属性选择器 选择器 描述 CSS版本 E[attribute] 匹配所有具有attribute属性的E元素,不考虑它的值。(注意:E在此处可以省略,比如“[cheacked]”。以下同。) 2.1 E[attribute=value] 匹配所有attribute属性等于“value”的E元素 2.1 E[attribute~=value] 匹配所有attribute属性具有多个空格分隔的值、其中一个值等于“value”的E元素 2.1 E[attribute^=value] 匹配任何E标签之后的同级F标签 2.1 E[attribute$=value] 匹配所有attribute属性值包含有“value”的E元素 3 E[attribute*=value] 匹配所有attribute属性值是以”value”结束的E元素 3 四、伪类选择器 五、伪元素选择器 选择器 描述 CSS版本 E:first-line 匹配所有E标签内的第一行 2.1 E:first-letter 匹配所有E标签内的第一个字母 2.1 E:before 在E标签之前插入生成的内容 2.1 E:after 在E标签之后插入生成的内容 2.1 在这里,我们需要知道的是浏览器是如何读取选择器的。Chris Coyier曾在《Efficiently Rendering CSS》一文中说过“浏览器读取你的选择器,遵循的原则是从选择器的右边到左边读取。换句话说,浏览器读取选择器的顺序是由右到左进行”。 选择器的最后一部分,也就是选择器的最右边(在这个例子中就是a[title]部分)部分被称为“关键选择器”,它将决定你的选择器的效率如何?是高还是低。 那么如何让关键选择器更有效,性能化更高呢?其实很简单,主要把握一点“越具体的关键选择器,其性能越高” 选择器有一个固有的效率,我们来看Steve Souders给排的一个顺序: 123456789id选择器(#myid)类选择器(.myclassname)标签选择器(div,h1,p)相邻选择器(h1+p)子选择器(ul > li)后代选择器(li a)通配符选择器(*)属性选择器(a[rel="external"])伪类选择器(a:hover,li:nth-child) 上面九种选择器的效率是从高到低排下来的,基中ID选择器的效率是最高,而伪类选择器的效率则是最低的。 我们来对比一下这几个实例,看看谁的效率是最高的: 1231. #myId span 2. span #myId 由上面的例子,我们可以知道,下面的效率要比上面的高。因为最右边的关键选择器是最具体的,也符合上述的选择器优先级顺序。","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"css知识归纳三","date":"2016-05-10T12:05:01.000Z","path":"2016/05/10/css知识归纳三/","text":"为文档添加样式的三种方法行内样式行内样式是写在HTML标签的style属性里的,比如: 1<p style="font-size: 12px;font-weight: 200;color: #333333">Hello Everyone!</p> 行内样式会覆盖嵌入样式和链接样式。 嵌入样式嵌入的css样式是放在HTML文档的head元素中的,这点想必大家都知道,这里就不赘述了。 链接样式12345<head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="style.css" type="text/css"/></head> 链接样式的作用范围可以是整个网站。只要使用标签把样式表链接到每个页面,相应的页面就可以使用其中的样式,除了link方法外,还可以使用@import指令 1@import url(css/style.css); @import指令必须出现在样式表中其他样式之前,否则该链接的文件不会被加载 不要乱用类不要像使用ID一样,为每个类都指定一个不同的类名,然后再为每个类编写规则。如果你有这种随意使用类的习惯的话,那么,你还不了解继承和上下文选择符的作用。继承和上下文选择符(后代选择器)能让不同的标签共享样式,从而降低你需要编写和维护的css量。 使用继承方式降低你的css代码量: 1234567891011所有元素可继承:visibility和cursor内联元素和块元素可继承:letter-spacing、word-spacing、white-space、line-height、color、font、 font-family、font-size、font-style、font-variant、font-weight、text- decoration、text-transform、direction块状元素可继承:text-indent和text-align列表元素可继承:list-style、list-style-type、list-style-position、list-style-image表格元素可继承:border-collapse不可继承的:display、margin、border、padding、background、height、min-height、max- height、width、min-width、max-width、overflow、position、left、right、top、 bottom、z-index、float、clear、table-layout、vertical-align 盒子边框每一个元素都会在页面上生成一个盒子,因此,HTML页面实际上就上由一堆盒子组成的。默认情况下,每个盒子的边框是不可见的,背景也是透明的。 边框(border)有如下3个相关属性: 1231. 宽度(border-width):可以使用`thin、medium`和`thick`等文本值,也可以使用除百分比和负值之外的任何绝对值2. 样式(border-style):有none、hidden、dotted、dashed、double、groove、ridge、inset和outset等3. 颜色(border-color):可以使用任意颜色值,包括RGB、HSL、十六进制颜色值和颜色关键字 叠加外边距垂直方向上的外边距会叠加,假设有3个段落,前后相接,而且都应用以下规则: 12345678910<style type="text/css"> p{ color: black; background: #ccc; margin-top: 50px; margin-bottom: 30px; height: 50px; border: 1px solid red; }</style> 第一段的下外边距与第二段的上外边距相邻,你可能认为它们之间的外边距是80px,但实际的间距却是50px。像这样的上下外边距相遇时,它们就会相互重叠,直至一个外边距碰到另一个元素的边框。因此,在这里,第二段较宽的上外边距就会碰到第一段的边框。也就是说,较宽的外边距决定两个元素最终离多远。这个过程就是外边距叠加。 盒子有多大设定width属性的盒子12盒模型结论一: 为设定了宽度的盒子添加边框、内间距和外边距,会导致盒子扩展得更宽。实际上,盒子的width属性设定的只是内容区的宽度,而非盒子要占据的水平宽度 没有设定width属性的盒子从现在开始,“元素”和“盒子”从现在起代表了同一个意思。如果我们不设置块级元素的width属性,那么这个属性的默认值是auto,结果会让元素的宽度扩展到与父元素等宽。 12盒模型结论二: 没有设定width属性的元素始终会扩展到填满其父元素的宽度为止。添加水平边框、内边距和外边距,会导致内容宽度减少,减少的量 等于 水平边框、内边框和外边距的和 看实例的话大家也比较烦,就拿着这个结论自己去验证下吧。 布局的基本概念多栏布局有三种基本的实现方案:固定宽度、流动、弹性。 123- 固定宽度布局的大小不会随着用户调整浏览器窗口大小而变化,一般是900到1350px像素宽。其中960像素最常见,因为这个宽度适合所有现代显示器,而且能被16,12,10,8,6,5,4和3整除,容易计算等宽分栏。- 流动布局的大小会随用户调整浏览器窗口大小而变化。这种布局能更好地适应大屏幕,但同时也意味着放弃会页面某些方面的控制,比如随着页面宽度变化,文本行的长度和页面元素之间的位置关系都可能变化。- 弹性布局是在浏览器窗口变宽时,不仅布局变宽,而且所有内容元素的大小也会变化,不过这种布局太过复杂,不好实现。 行内(inline)元素的一些属性并不是所有的属性对行内元素都能够生效 1234567891011行内元素不会应用width属性,其长度是由内容撑开的行内元素不会应用height属性,其高度也是由内容撑开的,但是高度可以通过line-height调节行内元素的padding属性只用padding-left和padding-right生效,padding-top和padding-bottom会改变元素范围,但不会对其它元素造成影响行内元素的margin属性只有margin-left和margin-right有效,margin-top和margin-bottom无效行内元素的overflow属性无效行内元素的vertical-align属性无效(height属性无效) 使用CSS spritesCSS sprites是指把网页中很多小图片(很多图标文件)做成按规律排列的一张大图上,在显示的时候通过background-image、background-position显示图片特定部分达到和分散的一张张小图片一样的效果。 使用CSS sprites,会将所有的小图片整合到一张图片中,网页加载只需要对一张图片进行请求,CSS再通过坐标的形式定位每一个小图片显示出来。这样做的好处是,大大减少http请求数,提高网页加载速度。 css sprites工具推荐:http://cn.spritegen.website-performance.org/ 隐藏文本隐藏网页元素的方法有很多,比如设置display:none,或是使用全透明(opacity)。在设置文本的时候,有时并不希望文本丢失,而通常是把文字转移到屏幕外面,浏览器是可以检测到的。有如下两种隐藏文本的方式: 121. 使用text-indent隐藏:图片替换文本、搜索引擎优化2. 使用position进行定位隐藏:利于屏幕讲述工具的阅读 使用text-indent在h1上设置logo为背景并设置居中来做SEO: 12345h1{ text-indent: -9999px;/*缩进*/ margin: 0 auto;width: 100px;height: 100px;/*居中*/ background: url("img/sf.jpg") no-repeat;} 使用定位12345p{ position: absolute; top: -9999px; left: -9999px; } rgba和opacityrgba()和opacity都能实现透明效果,但最大的不同是opacity作用于元素,以及元素内的所有内容的透明度, 而rgba()只作用于元素的颜色或其背景色。(设置rgba透明的元素的子元素不会继承透明效果!) ou和ul的列表缩进IE使用margin-left来缩进列表,而Safari和Firefox使用padding-left。 1ol, ul { padding-left:40px; } 而IE的默认样式是: 1ol, ul { margin-left:30px; } 去除li的左边距,比如: 1ol, ul { padding-left:0px; } 或者也可以只针对IE进行修复: 1ol, ul { _padding-left:0; } css选择符思维导图 css工具推荐不写具体介绍啦 截个图给你们吧 说再多都比不上一张图呢 EnjoyCSS 能创建活跃,超棒的实例,EnjoyCSS 生成器大大简化了自定义类声明。EnjoyCSS 是众多 CSS 工具中非常有用的,也是开发者和设计师工具箱必备的利器之一。它能加快工作流,简单易用,不需要编码就能整合丰富的图形样式到简单的UI。 css3生成器 css3 maker hands On css3 http://css3.mikeplate.com/ HTML5/css3 box 浏览器hacks技巧 前端在线工具–开源中国 在线 css–实时预览 HTML5/css3浏览器支持表 OverAPI–齐全的API文档","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"css知识归纳二","date":"2016-05-08T12:05:01.000Z","path":"2016/05/08/css知识归纳二/","text":"标签与元素<p>标签和p元素有什么区别呢?大多数时候他们表示的是同一样东西,但仍有细微的区别。<p>、<div>等指的是HTML分隔符,而元素则是由一对开始结束标签构成的,用来包含某一些内容 子选择器和后代选择器的区别: 12后代选择器的写法就是把外层的标记写在前面,内层的标记写在后面,之间用空格分隔。子选择器只对直接后代有影响的选择器,而对“孙子后代”以及多层后代不产生作用。 注意:在IE6中,只支持后代选择器,不支持子选择器 链接伪类1234a:link {color: black} /* 未访问的链接 */a:visited {color: blue} /* 已访问的链接 */a:hover {color: red} /* 当有鼠标悬停在链接上 */a:active {color: purple} /* 被选择的链接 */ 为了产生预期的效果,在 CSS 定义中,a:hover 必须位于 a:link 和 a:visited 之后!a:active 必须位于 a:hover 之后!! :after和:before伪元素“伪元素”,顾名思义。它创建了一个虚假的元素,并插入到目标元素内容之前或之后。伪元素如果没有设置“content”属性,伪元素是无用的。 插入的元素默认情况下是内联元素,如果你要为其设置宽高等属性,你需要将他定义为块级元素 123456#element:before{ content : ""; display : 'block' height : 1000px; width : 1000px;} 注入的内容将是有关联的目标元素的子元素,但它会被置于这个元素的任何内容的“前”或“后”。 web标准的构成1231.结构:用来对网页中的信息进行整理与分类,常用的技术有:HTML,XHTML,XML2.表现:用于对已经被结构化的信息进行显示上的修饰,主要技术就是CSS3.行为:是指对整个文档内部的一个模型进行定义及交互行为的编写;主要技术有:Javascript 那么如何让关键选择器更有效,性能化更高呢?其实很简单,主要把握一点“越具体的关键选择器,其性能越高” cellpadding与cellspacing12cellpadding(表格填充) -- 代表单元格外面的一个距离,用于隔开单元格与单元格空间cellspacing(表格间距) -- 代表表格边框与单元格补白的距离,也是单元格补白之间的距离 css的三性1234CSS叠加性:同一个元素被多条样式规则指定。CSS继承性:后代元素会继承前辈元素的一些样式和属性。CSS优先级:由于CSS的叠加性和继承性,将产生优先级,这指的是哪条样式规则会最终作用于指定的元素,他只遵循一条规则,指定的越具体,优先级越高 浏览器读取你的选择器,遵循的原则是从选择器的右边到左边读取。换句话说,浏览器读取选择器的顺序是由右到左进行 并非所有css属性都具有继承性,那么,哪些属性具有继承性呢? 1231.文本相关属性是继承的:font-family,font-size,line-height,font-weight,font-style,text-transform2.列表相关属性是继承的:list-style,list-style-image,list-style-position3.颜色相关属性是继承的:color 无继承的属性:11.所有背景属性,盒子属性,布局属性 我们在ul下设置color属性,并不会使ul>li>a下的a的字体发生样式的改变,但会使li下的字体样式发生改变 background属性1234567891011background:background-color ||background-image || background-repeat || background-attachment || background-position||background-sizebackground-image:url("图片的网址"); 背景图 background: url(" 图片的网址 "); 背景 background-color:#色码; 背景色彩 background-position:默认值:0% 0%,可能值:top left ,center left等background-repeat:默认值:repeatscroll 拉动卷轴时,背景图片会跟着移动(缺省值) fixed 拉动卷轴时,背景图片不会跟着移动 repeat 背景图片并排 background-size:是css3规定的属性,50%为缩放图片;100px 50px:把图片调整到100像素宽,50像素高;cover:拉大图片,使其完全填满背景区;container:缩放图片,使其恰好适合背景区 background-position:X坐标 Y坐标 各浏览器默认的css样式地址:http://www.iecss.com/ 伪类与伪元素选择符伪类选择符 伪元素选择符 常用css hack技巧地址:http://www.css88.com/book/css/hack/index.htm IE条件注释法:01.只在IE下生效 123<!-- [if IE]><link type="text/css" href="text.css" rel="stylesheet" /><![endif] --> 02.只在IE6下生效 123<!-- [if IE 6]><link type="text/css" href="text.css" rel="stylesheet" /><![endif] --> css整理与优化工具地址:http://www.css88.com/tool/csstidy/ css的缩写font缩写12345678910111213141516缩写前element{ font-style:italic //设置或检索对象中的字体样式 font-variant:normal //设置或检索对象中的文本是否为小型的大写字母 //前2项如果没有特殊设置,可以不写,用默认值即可 font-weight:bold; font-size:12px; line-height:20px; font-family:"宋体"; }缩写后element{ font:bold 12px/20px "宋体"; //属性依次为:字体的粗细 - 字体大小/行高 - 文本的字体 } background的缩写12345678910111213缩写前element{ background-color:#ccc; background-image:url(sample.gif); background-repeat:repeat-x; background-attachment:scroll;//scroll是背景图像随对象内容滚动为默认值,可以不写 background-position:top right;}缩写后element{ background:#ccc url(sample.gif) repeat-x top right; //属性依次为:颜色-背景图-X轴平铺-背景图像位置(背景图片路径不需要加引号)} css超出 自动换行只针对单行文本有效; 1234567891011121314151617181901.针对块状元素ul li{ width: 180px; text-overflow: ellipsis;/*超出部分显示省略号*/ white-space: nowrap;/*禁止自动换行*/ overflow: hidden;}02.针对tabletable{ table-layout:fixed;}table td{ word-break:keep-all;/* 不换行 */ white-space:nowrap;/* 不换行 */ overflow:hidden;/* 内容超出宽度时隐藏超出部分的内容 */ text-overflow:ellipsis;/* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/} css-常用reset12345678910111213141516171.body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,tr,td,var {margin:0;padding:0; font-size:12px;} 2.table {border-collapse:collapse;border-spacing:0;} 3.fieldset,img {border:none} 4.address,caption,cite,code,dfn,em,strong,th {font-style:normal;font-weight:normal} 5.ol,ul {list-style:none} 6.caption,th,td{text-align:center} 7.h1,h2,h3,h4,h5,h6 {font-size:100%;font-weight:normal} 8.q:before,q:after {content:''} 9.abbr,acronym { border:0} 注: 123456code - 计算机代码(在引用源码的时候需要)dfn - 定义字段acronym - 首字abbr - 缩写u - 下划线var - 定义变量 浮动与清除浮动 clear对内联元素设置float和absolute属性,可以让元素脱离文档流,并且可以设置其宽高。 float: left的元素会尽量靠近父元素的左上角 float: right的元素会尽量靠近父元素的右上角 123456789101112131415161718192021/*======万能Float闭合======*/.clear:after { content: "."; display: block; height: 0; clear: both; visibility: hidden;}.clear {display: inline-block;} /* for IE/Mac */.clear { zoom: 1; /* triggers hasLayout */ display: block; /* resets display for IE/Win */} /*======万能Float闭合3======*/.clear{ height:0px; clear:both; font-size:0px; line-height:0px; zoom: 1;} 浮动框可以左右移动,直到它的外边缘碰到包含框或另一个浮动框的边缘。因为浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。 编写更好的 css避免过度约束作为一般规则,不添加不必要的约束。 1234567// 糟糕ul#someid {..}.menu#otherid{..}// 好的#someid {..}#otherid {..} 后代选择符最烂不仅性能低下而且代码很脆弱,html代码和css代码严重耦合,html代码结构发生变化时,CSS也得修改,这是多么糟糕,特别是在大公司里,写html和css的往往不是同一个人。 12// 烂透了html div tr td {..} 尽可能使用复合语法1234567891011121314151617// 糟糕.someclass {padding-top: 20px;padding-bottom: 20px;padding-left: 10px;padding-right: 10px;background: #000;background-image: url(../imgs/carrot.png);background-position: bottom;background-repeat: repeat-x;}// 好的.someclass {padding: 20px 10px 20px 10px;background: #000 url(../imgs/carrot.png) repeat-x bottom;} 避免不必要的重复12345678910111213141516171819// 糟糕.someclass {color: red;background: blue;font-size: 15px;}.otherclass {color: red;background: blue;font-size: 15px;}// 好的.someclass, .otherclass {color: red;background: blue;font-size: 15px;} 组织好的代码格式代码的易读性和易维护性成正比。下面是我遵循的格式化方法。 12345678910111213141516171819202122// 糟糕.someclass-a, .someclass-b, .someclass-c, .someclass-d {...}// 好的.someclass-a,.someclass-b,.someclass-c,.someclass-d {...}// 好的做法.someclass { background-image: linear-gradient(#000, #ccc), linear-gradient(#ccc, #ddd); box-shadow: 2px 2px 2px #000, 1px 4px 1px 1px #ddd inset;} div>ul>li>a 结构结构为:div>div>ul>li>a div与div默认是重合在一起的,为了作区分,第二个div弄了个margin :5px 的间距 在谷歌和火狐浏览器下,div与ul的默认顶底部间距为20px,ul始终包裹着li,ul的高度由li撑起,块级元素的宽度默认为浏览器宽度。li距离ul左边有一小段间距,用来存放无序列表的小圆点(这里设置了 list-style :none )。 定义一张图片也要为其设置宽高属性,否则无法进行定位设置,同理,很多元素必须设置其宽高属性才能进行定位 块级元素盒子会扩展到与父元素同宽,所有块级元素的父元素都是body,而它的宽度默认与浏览器窗口一样宽(当然有少量边距)。因为块级元素始终与浏览器窗口同宽。这样一来,一个块级元素旁边也就没有空间容纳另一个块级元素了。 如何居中一个浮动元素方法一设置容器的浮动方式为绝对定位然后确定容器的宽高 比如宽500 高 300 的层然后设置层的外边距 123456789 div{ width:500px; height:300px; margin:-150px 0 0 -250px; position:absolute; left:50%; top:50%; background-color:#000;} 方法二父元素和子元素同时左浮动,然后父元素相对左移动50%,再然后子元素相对右移动50%,或者子元素相对左移动-50%也就可以了。 1234567891011121314151617181920<!DOCTYPE html><html><head> <title>Demo</title> <meta charset="utf-8"/> <style type="text/css"> .p{ position:relative; left:50%; float:left; } .c{ position:relative; float:left; right:50%; } </style></head><body> <div class="p"> <h1 class="c">Test Float Element Center</h1> </div></body></html>","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"css知识归纳一","date":"2016-04-28T12:05:01.000Z","path":"2016/04/28/css知识归纳一/","text":"选择器的分组CSS选择器分为 123456789101112131415161718191.群组选择器 如:p, body, img, div{}2.兄弟选择器 如:p + p { color:#f00; }3.属性选择器 如: p[title] { color:#f00; }4.包含(后代)选择器 如:body ul li{}5.子元素选择器 如:div > p{}6.ID选择器 如:#myDiv{}7.类选择器 如:.class1{}8.伪元素选择器 如:E:first-line,E:before9.伪类选择器 如:E:first-child ,E:visited,E:focus,E:enabled10.标签选择器 如:p { font-size:1em; } 子选择器和后代选择器的区别: 12后代选择器的写法就是把外层的标记写在前面,内层的标记写在后面,之间用空格分隔。子选择器只对直接后代有影响的选择器,而对“孙子后代”以及多层后代不产生作用。 注意:在IE6中,只支持后代选择器,不支持子选择器 盒子模型css框模型介绍: 给ul下的li设置宽度,那么他们将平均掉它们所占容器的宽度。div >ul> li> a标签所占宽度和高度: 当你为body元素指定div时,每个div默认的宽为浏览器的100%,高度在每个浏览器的解析都是不一样的,比如在火狐下是131px,在chrome下则是142px,具体机制不明 css字体速记规则当用css定义字体样式的时候,你也许会这样做: 123456font-weight: bold;font-style: italic;font-variant: small-caps;font-size: 1em;line-height: 1.5em;font-family: verdana,sans-serif 没有必要这么做,因为你可以使用css速记属性: 1font: bold italic small-caps 1em/1.5em verdana,sans-serif 值得注意的是:css速记版本只会在你同时指定 font-size和font-family 属性时才会生效。如果你没有指定font-weight, font-style,或者 font-variant,那么这些值将会自动默认为 normal 避免多余选择器有时候你会有如下的写法: 12345ul li { ... }ol li { ... } table tr td { ... } 但实际上这是没必要的写法,因为<li>会且只会与<ul>或<ol>连用,就像<td>只能存在于<tr>和<table>中一样,这儿真没有把它们重复一次的必要。 !Important所有被!important 标记的样式,即使它后来被重写,浏览器也只会采用被标记的那条。 1234 #content{ height:960px !important; height:900px;} !important: IE7/IE8/IE9/FireFox可以识别上面附加!important的语句,看到附加!important的语句后,就不会再去执行 第二句,尽管他们也“认识”第二句,但是附加“!important”的语句拥有绝对优先级,只要有它存在,第二句就不允许执行。 IE6会执行!important的语句后,再去执行第二句“height:900px”,用后面的样式覆盖了前面的样式,所以在IE6下,最终的height值是900px。 @import and<link>在决定使用使用哪种方法去包含你的样式表之前,你应该明白这两种方法被用来干嘛? 链接式:link就是把外部CSS与网页连接起来,将其加在<head>头部标签中,具体形式如下: 1<link href="styles.css" type="text/css" /> 导入样式:通过两个或以上的css文件共同部分,在css页面引入css文件,通过@import url(” “) 123@import url("global.css");@import url(global.css);@import "global.css"; 以上三种方式都有效, 区别:12341)link属于XHTML标签,而@import是CSS提供的; 2)页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载; 3)@import只在IE5以上才能识别,而link是XHTML标签,无兼容问题; 4)link方式的样式的权重 高于@import的权重. 行内元素、块元素和空元素行内元素特点123451、和其他元素都在一行上;2、元素的高度、宽度、行高及顶部和底部边距不可设置;3、元素的宽度就是它包含的文字或图片的宽度,不可改变。 行内元素在设置 水平方向的padding-left、padding-right、margin-left、margin-right都产生边距效果,但竖直方向的padding-top、padding-bottom、margin-top、margin-bottom却不会产生边距效果。 块级元素特点123451、每个块级元素都从新的一行开始,并且其后的元素也另起一行。(真霸道,一个块级元素独占一行)2、元素的高度、宽度、行高以及顶和底边距都可设置。3、元素宽度在不设置的情况下,是它本身父容器的100%(和父元素的宽度一致),除非设定一个宽度。 在html中,<span>、<a>、<label>、<input>、 <img>、 <strong> 和<em>就是典型的行内元素(inline)元素。 块级元素是可以设置宽高的,但是它的实际宽高是本身宽高+padding。block元素要单独占一行。内联元素不单独占一行,给他设置宽高是没有用的。 块级元素和行内元素列表: 空元素知名的空元素: <br> <hr> <img> <input> <link> <meta>鲜为人知的是: <area> <base> <col> <command> <embed> <keygen> <param> <source> <track> <wbr> 长度单位emem为相对长度单位,相对于当前对象内文本的字体尺寸(font-size)。比如:Web页面中body的文字大小在用户浏览器下默认渲染是16px,所以,此时的1em = 16px; in英寸(Inches)。绝对长度单位。 11in = 2.54cm = 25.4 mm = 72pt = 6pc = 96px pt点(Points)。绝对长度单位。 11in = 2.54cm = 25.4 mm = 72pt = 6pc = 96px small<small> 标签呈现小号字体效果。 <strong>,<em>和<b>,<i>标签1234`<strong>` 标签和 `<em>` 标签一样,用于强调文本,但它强调的程度更强一些。`em` 是 斜体强调标签,更强烈强调,表示内容的强调点。相当于html元素中的 `<i>...</i>`;`< b > < i >` 是视觉要素,分别表示无意义的加粗,无意义的斜体。em 和 strong 是表达要素(phrase elements)。 b标签和i标签的区别12345b 元素现在描述为在普通文章中仅从文体上突出的不包含任何额外的重要性的一段文本。 例如:文档概要中的关键字,评论中的产品名。或者代表强调的排版方式。i 元素现在描述为在普通文章中突出不同意见或语气或其他的一段文本, 例如:一个分类名称,一个技术术语,一个外语中的谚语,一个想法等。或者代表斜体的排版方式。 角度单位deg度(Degress)。一个圆共360度 190deg = 100grad = 0.25turn grag梯度(Gradians)。一个圆共400梯度 190deg = 100grad = 0.25turn turn转、圈(Turns)。一个圆共1圈 190deg = 100grad = 0.25turn rad弧度(Radians)。一个圆共2π弧度 190deg = 100grad = 0.25turn CSS 多类选择器一个 class 值中可能包含一个词列表,各个词之间用空格分隔。例如,如果希望将一个特定的元素同时标记为重要(important)和警告(warning),就可以写作: 123<p class="important warning">This paragraph is a very important warning.</p> 对于ID来说,就不能这样写了 所有浏览器下的CSS透明度元素透明度时常是个恼人的问题,下面这种方式可以实现所有浏览器下的透明度设置: 12345.transparent { zoom: 1; filter: alpha(opacity=50); opacity: 0.5;} Zoom属性是IE浏览器的专有属性,Firefox等浏览器不支持。它可以设置或检索对象的缩放比例。除此之外,它还有其他一些小作用,比如触发IE的hasLayout属性,清除浮动、清除margin的重叠等。 当一个元素的 hasLayout属性值为true时,我们说这个元素有一个布局(layout) css float属性定义和用法 float 属性定义元素在哪个方向浮动。以往这个属性总应用于图像,使文本围绕在图像周围,不过在 CSS 中,任何元素都可以浮动。浮动元素会生成一个块级框,而不论它本身是何种元素。 如果浮动非替换元素,则要指定一个明确的宽度;否则,它们会尽可能地窄。 注释:假如在一行之上只有极少的空间可供浮动元素,那么这个元素会跳至下一行,这个过程会持续到某一行拥有足够的空间为止。 伟大的塌陷使用浮动(float)的一个比较疑惑的事情是他们怎么影响包含他们的父元素的。如果父元素只包含浮动元素,那么它的高度就会塌缩为零。如果父元素不包含任何的可见背景,这个问题会很难被注意到 塌陷的直观对立面更不好,看看下面的情况: 清除浮动如果你很明确的知道接下来的元素会是什么,可以使用 clear:both; 来清除浮动。这个方法很不错,它不需要 hack,不添加额外的元素也使得它有良好的语义性。 使用css 伪选择符(:after)来清除浮动: 1234567.clearfix:after { content: "."; visibility: hidden; display: block; height: 0; clear: both; } 渐进增强与优雅降级概念优雅降级和渐进增强印象中是随着css3流出来的一个概念。由于低级浏览器不支持css3,但css3的效果又太优秀不忍放弃,所以在高级浏览中使用 css3而低级浏览器只保证最基本的功能。咋一看两个概念差不多,都是在关注不同浏览器下的不同体验,关键的区别是他们所侧重的内容,以及这种不同造成的 工作流程的差异。 渐进增强 progressive enhancement:针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。 优雅降级 graceful degradation:一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。 区别优雅降级是从复杂的现状开始,并试图减少用户体验的供给,而渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。 visibility:hidden和display:none1234display:none 隐藏对应的元素,在文档布局中不再给它分配空间,它各边的元素会合拢,就当他从来不存在。visibility:hidden 隐藏对应的元素,但是在文档布局中仍保留原来的空间。 使用CSS display:none属性后,HTML元素(对象)的宽度、高度等各种属性值都将“丢失”;而使用visibility:hidden属性后,HTML元素(对象)仅仅是在视觉上看不见(完全透明),而它所占据的空间位置仍然存在。 text 文本属性text-indenttext-indent 属性规定文本块中首行文本的缩进。 注释:允许使用负值。如果使用负值,那么首行会被缩进到左边。使用一个较大的负值进行缩进的话,文字将被隐藏,如-9999em letter-spacing与word-spacingletter-spacing 属性与 word-spacing 的区别在于,前者是修改字母的间隔,后者是修改单词或单个文字的间隔 text-transformtext-transform 属性处理文本的大小写。这个属性有 4 个值: 1234noneuppercase:所有的单词都大写lowercase:所有的单词都小写capitalize:只对每个单词的首字母大写 text-decorationtext-decoration 有 5 个值: 12345noneunderline:下划线overline:上划线line-through:在文本中间画一个贯穿线blink:让文本闪烁 white-space12345pre-line 合并空白符序列,但保留换行符 normal nowrap 防止元素中的文本换行pre 空白符不会被忽略pre-wrap 保留空白符序列","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Javascript基础总结九(事件处理)","date":"2016-04-18T12:05:01.000Z","path":"2016/04/18/Javascript基础总结九(事件处理)/","text":"事件处理程序在DOM中定义了一些事件, 而响应某个事件的函数就叫事件处理程序(或事件侦听器)。事件处理程序的名字一般以“on”开头,例如:onclick等 事件冒泡与捕获事件流指的是页面中接收事件的顺序,IE,火狐和chrome浏览器都是事件冒泡,所谓是事件冒泡指的是事件最开始由最具体的元素接收,然后逐级向上传播到不具体的节点。而事件捕获则正好相反,事件捕获是由Netscape提出的,事件冒泡和捕获具体如下图所示: 虽然事件捕获是Netscape唯一支持的事件流模型,但目前IE9,火狐和谷歌也都支持这种事件流模型。 事件冒泡的好处因为事件具有冒泡机制,因此我们可以利用冒泡的原理,把事件加到父级上,触发执行效果。这样做的好处当然就是提高性能了, 1234567891011121314151617181920212223242526272829<head lang="en"> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> window.onload = function () { var aUl = document.getElementsById("bubble"); var aLi = aUl.getElementsByTagName("li"); for(var i = 0;i<aLi.length;i++){ aLi[i].onmouseover = function () { this.style.backgroundColor = "blue"; }; ali[i].onmouseout = function () { this.style.backgroundColor = ""; } } }; </script></head><body><div> <ul id = "bubble"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul></div></body> 这样我们就可以做到li上面添加鼠标事件。但是如果说我们可能有很多个li用for循环的话就比较影响性能。下面我们可以用事件委托的方式来实现这样的效果。html不变: 1234567891011121314151617181920212223242526<script type="text/javascript"> window.onload = function () { var aUl = document.getElementsById("bubble"); var aLi = aUl.getElementsByTagName("li"); //不管在哪个事件中,只要你操作的那个元素就是事件源。 // ie:window.event.srcElement // 标准下:event.target aUl.onmouseover = function (ev) { var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == "li"){ target.style.background = "blue"; } }; aUl.onmouseout = function (ev) { var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() = "li"){ target.style.background = ""; } } };</script> 那么,如何阻止事件的冒泡呢,看下面一个例子: 1234567891011121314151617181920<div onclick="showMsg(this,event)" id="outSide" style="width:100px; height:100px; background:#000; padding:50px"><div onclick="showMsg(this,event)" id="inSide" style="width:100px; height:100px; background:#CCC"></div></div><script type="text/javascript">//阻止事件冒泡后,你点击灰色盒子,整个过程只弹一次对话框了(注意与默认情况对比)function showMsg(obj,e){ alert(obj.id); stopBubble(e)}//阻止事件冒泡函数function stopBubble(e){ if (e && e.stopPropagation) e.stopPropagation() else window.event.cancelBubble=true}</script> 点击黑色外围的效果图: DOM 0级事件处理程序通过js指定事件处理程序通常是将回调函数赋给这个事件处理程序的属性。每个元素都有自己的事件处理程序属性(属性小写,例如:onclick) 123btn.onclick = function(){ console.log('hello');}; 使用DOM 0级指定的事件处理程序被认为是元素的方法。因此,this指向当前元素: 123456var btn = document.getElementById('myDiv');//DOM上触发的事件会产生一个事件对象eventbtn.onclick = function (event) { alert(this.id);//myDiv }; DOM level 1DOM level 1 专注于 HTML 和 XML 文档模型。它含有文档导航和处理功能。 DOM level 1 于 1998 年 10 月 1 日成为 W3C 推荐标准。 第二版的工作草案在 2000 年 9 月 29 日。 值得一提的是:DOM level 0 并不是 W3C 规范。而仅仅是对在 Netscape Navigator 3.0 和 IE 3.0 中的等价功能性的一种定义。 DOM 2级事件处理程序DOM 2级定义了两个方法,用于指定和删除事件处理程序的操作:addEventListener()和removeEventListener(),他们都接受三个参数: 1231.事件名。比如上面的click2.作为事件处理程序的函数。3.布尔值(true表示捕获阶段调用事件处理程序,false表示冒泡阶段) 通过Element对象的addEventListener方法,也可以定义事件的回调函数。 123456//element.addEventListener(event, function, useCapture) var btn = document.getElementById('myDiv');btn.addEventListener('click', function () { console.log(this.id);},false); IE中的事件处理程序IE9之前的IE浏览器不支持addEventListener()和removeEventListener()。与其他浏览器不同的是,IE使用的是attachEvent()和detachEvent()方法来为DOM添加事件处理程序,由于IE8及更早版本只支持事件冒泡,所以他们只接受两个参数: 121、事件处理程序名称(前面要加on)2、事件处理程序函数 使用attachEvent()添加的事件处理程序如下: 1234var btn = document.getElementById('myDiv');btn.attachEvent('onclick', function () { console.log(this.id);}); 值得注意的是,使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,所以,此时this等于window 事件对象在触发DOM上的某个事件时,会产生一个事件对象event,这个对象包含着所有与事件相关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。event对象会被作为第一个参数传递给事件监听的回调函数。我们可以通过这个event对象来获取到大量当前事件相关的信息: 12345678type (String) — 事件的名称target (node) — 事件起源的DOM节点currentTarget?(node) — 当前回调函数被触发的DOM节点(后面会做比较详细的介绍)bubbles (boolean) — 指明这个事件是否是一个冒泡事件(接下来会做解释)preventDefault(function) — 这个方法将阻止浏览器中用户代理对当前事件的相关默认行为被触发。比如阻止<a>元素的click事件加载一个新的页面cancelable (boolean) — 这个变量指明这个事件的默认行为是否可以通过调用event.preventDefault来阻止。stopPropagation (function) — 取消事件的进一步捕获或冒泡,bubbles为true使用这个方法eventPhase:返回一个数字,表示事件目前所处的阶段,0为事件开始从DOM表层向目标元素传播,1为捕获阶段,2为事件到达目标元素,3为冒泡阶段。 此外,事件对象还可能拥有很多其他的属性,但是他们都是针对特定的event的。比如,鼠标事件包含clientX和clientY属性来表明鼠标在当前视窗的位置。 另外,stopPropagation()方法用于立即停止事件在DOM中的传播,即取消进一步的事件冒泡或捕获。 12345678910var btn = document.getElementById('myDiv');btn.onclick = function (event) { alert("clicked"); event.stopPropagation();};//避免触发在document.body上的事件处理程序document.body.onclick = function (event) { alert("Body clicked"); }; 只有在事件处理程序执行期间,event对象才会存在,一旦事件处理程序执行完毕,event对象就会自动销毁。 IE中的事件对象在DOM 0级中添加事件处理程序时,event对象是作为window对象的一个属性存在的: 12345var btn = document.getElementById('myDiv');btn.onclick = function (event) { var event = window.event; alert(event.type);//click}; IE 的event对象同样也包含与创建它的事件相关的属性和方法。 1234cancleBubble 布尔 默认值时false,但可以被设置成true来取消事件冒泡,与dom中的 stopPropagation()方法相同。returnValue 布尔 默认值是true,当设置成false时用以取消事件的默认行为 与dom中的preventDefault()相同。srcElement 元素 事件的目标,与dom中的target属性相同。type 字符串 被触发的事件类型。 click事件当用户点击以后,event对象会包含以下属性。 123pageX,pageY:点击位置相对于html元素的坐标,单位为像素。clientX,clientY:点击位置相对于视口(viewport)的坐标,单位为像素。screenX,screenY:点击位置相对于设备显示屏幕的坐标,单位为设备硬件的像素 clientX,clientY图示:clientX和clientY,他们的值表示事件发生时鼠标指针在视口中的水平和垂直坐标(不包含滚动条区域) 偏移量 123456789通过以下4个属性可以取得元素的偏移量。(1)offsetHeight:元素在垂直方向上占用的空间大小,以像素计。包括元素的高度、(可见的)水平滚动条的高度、上边框高度和下边框高度。(2)offsetWidth:元素在水平方向上占用的空间大小,以像素计。包括元素的宽度、(可见的)垂直滚动条的宽度、左边框宽度和右边框宽度。(3)offsetLeft:元素的左外边框至包含元素的左内边框之间的像素距离。(4)offsetTop:元素的上外边框至包含元素的上内边框之间的像素距离。 pageX,pageY这两个属性表示鼠标光标在页面中的位置,在页面没有滚动的情况下,pageX,pageY的值与clientX,clientY的值相等 滚动大小 滚动大小,指的是包含滚动内容的元素的大小。 123456789以下是4个与滚动大小相关的属性。(1)scrollHeight:在没有滚动条的情况下,元素内容的总高度。(2)scrollWidth:在没有滚动条的情况下,元素内容的总宽度。(3)scrollLeft:被隐藏在内容区域左侧的像素数。通过设置这个属性可以改变元素的滚动位置。(4)scrollTop:被隐藏在内容区域上方的像素数。通过设置这个属性可以改变元素的滚动位置。 焦点事件焦点事件会在页面元素获得或失去焦点时触发,有以下4个焦点事件: 12341. blur:元素失去焦点时触发,该事件不冒泡2. focus:元素获得焦点时触发。不冒泡3. focusin:元素获得焦点时触发,冒泡4. focusout:元素失去焦点时触发,冒泡 鼠标事件DOM 3级定义了9个鼠标事件: 12345678910111213141516171819click:当用户点击鼠标主键通常是指鼠标左键或按回车键时触发。dbclick:用户双击鼠标时触发mousedown:当用户按下鼠标任意一个键都会触发,这个事件是不能够通过键盘触发的。mousemove:当鼠标在某元素周围移动时重复触发,该事件不能通过键盘事件触发。mouseout:当鼠标离开元素时触发,这个事件不能通过键盘触发。mouseover:当鼠标进入元素时触发,这个事件不能够通过键盘触发。 mouseenter:类似“mouseover”,但不冒泡,而且当光标移到后代元素上不会触发。 mouseleave:类似“mouseout”,但不冒泡。在元素上方是不触发。mouseup:当用户释放鼠标按键时触发,不能够通过键盘触发。传递给鼠标事件处理程序的事件对象有clientX和clientY属性,它们指定了鼠标指针相对于包含窗口的坐标。加入窗口的滚动偏移量,就可以把鼠标位置转换成文档坐标。 页面上的所有元素都支持鼠标事件。除了mouseenter和mouseleave外,所有的事件都冒泡,并且他们的默认行为是可以被取消掉的。但取消鼠标事件的默认行为可能会影响到其他事件,因为有些鼠标事件是相互依赖的。 mouseenter和mouseover的不同:http://www.w3school.com.cn/ti… 拖拉事件(1)drag事件 1drag事件在源对象被拖拉过程中触发。 (2)dragstart,dragend事件 1dragstart事件在用户开始用鼠标拖拉某个对象时触发,dragend事件在结束拖拉时触发。 (3)dragenter,dragleave事件 1dragenter事件在源对象拖拉进目标对象后,在目标对象上触发。dragleave事件在源对象离开目标对象后,在目标对象上触发。 (4)dragover事件 1dragover事件在源对象拖拉过另一个对象上方时,在后者上触发。 (5)drop事件 1当源对象被拖拉到目标对象上方,用户松开鼠标时,在目标对象上触发drop事件。","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Javascript基础总结八(正则表达式)","date":"2016-04-08T12:05:01.000Z","path":"2016/04/08/Javascript基础总结八(正则表达式)/","text":"这篇文章本来很早就要写的,拖了挺久的,现在整理下,供大家学习交流哈! 基本概念正则表达式是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”)。模式描述在搜索文本时要匹配的一个或多个字符串。 首先推荐几个正则表达式编辑器Debuggex :https://www.debuggex.com/PyRegex:http://www.pyregex.com/Regexper:http://www.regexper.com/ 正则表达式是一种查找以及字符串替换操作。正则表达式在文本编辑器中广泛使用,比如正则表达式被用于: 1234检查文本中是否含有指定的特征词找出文中匹配特征词的位置从文本中提取信息,比如:字符串的子串修改文本 说明:正则表达式通常用于两种任务:1.验证,2.搜索/替换。用于验证时,通常需要在前后分别加上^和$,以匹配整个待验证字符串;搜索/替换时是否加上此限定则根据搜索的要求而定,此外,也有可能要在前后加上\\b而不是^和$。此表所列的常用正则表达式,除个别外均未在前后加上任何限定,请根据需要,自行处理。 优先权顺序在构造正则表达式之后,就可以象数学表达式一样来求值,也就是说,可以从左至右并按照一个优先权顺序来求值。 下表从最高优先级到最低优先级列出各种正则表达式操作符的优先权顺序: 操作符 描述 \\ 转义符 (), (?:), (?=), [] 圆括号和方括号 *, +, ?, {n}, {n,}, {n,m} 限定符 ^, $, \\anymetacharacter 位置和顺序 字符类匹配 字符 匹配 […] 方括号内的任意字符 1 不在方括号内的任意字符 . 除了换行符和其他Unicode行终止符之外的任意字符 \\w 任何ASCII字符组成的单词,等价于[a-zA-Z0-9] \\W 任何不是ASCII字符组成的单词,等价于2 \\s 任何Unicode空白符 \\S 任何非Unicode空白符的字符 \\d 任何ASCII数字,介于[0-9] \\D 除了ASCII数字之外的任何字符,等价于3 \\b 退格直接量 重复字符匹配 字符 匹配 {n,m} 匹配前一项至少n次,但不能超过m次 {n,} 匹配前一项n次或更多次 {n} 匹配前一项n次 ? 匹配前一项0次或者1次,也就是说前一项是可选的,等价于{0,1} + 匹配前一项1次或多次,等价于{1,} * 匹配前一项0次或多次,等价于{0,} 字符类:锚字符 匹配 元字符/元符号 匹配 $ 匹配字符串的结尾,在多行检索中,匹配一行的结尾 ^ 匹配字符串的开头,在多行检索中,匹配一行的开头 \\A 只有匹配字符串开始处 \\b 匹配单词边界,词在 []内时无效 \\B 匹配非单词边界 \\G 匹配当前搜索的开始位置 \\Z 匹配字符串结束处或行尾 \\z 只匹配字符串结束处 字符类:记录字符 匹配 元字符/元符号 匹配情况 (string) 用于反向引用的分组 \\1 或$1 匹配第一个分组中的内容 \\2 或$2 匹配第二个分组中的内容 \\3 或$3 匹配第三个分组中的内容 正则表达式修饰符1234字符 含义i 执行不区分大小写的匹配g 执行一个全局匹配,即找到所有匹配而非一次匹配m 多行匹配模式,^匹配一行的开头和字符串开头,$匹配行的结束和字符串的结尾 RegExp的方法RegExp 对象有 3 个方法:test()、exec() 以及 compile()。 1234test():检索字符串中的指定值。返回值是布尔值。exec():返回一个数组,数组中的第一个条目是第一个匹配,其他的是反向引用compile() 既可以改变检索模式,也可以添加或删除第二个参数。 String 对象中的正则表达式方法 方法 含义 match(pattern) 返回 pattern 中的子串或 null replace(pattern, replacement) 用 replacement 替换 pattern search(pattern) 返回字符串中 pattern 开始位置 split(pattern) 返回字符串按指定 pattern 拆分的数组 建立正则表达式构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与操作符将小的表达式结合在一起来创建更大的表达式。可以通过在一对分隔符之间放入表达式模式的各种组件来构造一个正则表达式。 对 js 而言,分隔符为一对正斜杠 (/) 字符。例如: 1/expression/ 对 VBScript 而言,则采用一对引号 (“”) 来确定正则表达式的边界。例如: 1"expression" 看个例子1//匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线 123456var re =new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,19}$"); `if(re.test(aaaa)){ alert("格式正确"); }else{ alert("格式错误");} 正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。 match 方法12345/*使用 match 方法获取获取匹配数组*/ var pattern = /box/ig;//全局搜索 var str = 'This is a Box!,That is a Box too'; alert(str.match(pattern)); //匹配到两个 Box,Boxconsole.log(str.match(pattern).length);//获取数组的长度 search方法1234/*使用 search 来查找匹配数据*/var pattern = /box/ig;var str = 'This is a Box!,That is a Box too'; console.log(str.search(pattern));//查找到返回位置,否则返回 -1 PS:因为 search 方法查找到即返回,也就是说无需 g 全局 replace方法1234/*使用 replace 替换匹配到的数据*/var pattern = /box/ig;var str = 'This is a Box!,That is a Box too'; console.log(str.replace(pattern, 'Cat'));//将 Box 替换成了 Cat split方法12345/*使用 split 拆分成字符串数组*/ var pattern = / /ig; var str = 'This is a Box!,That is a Box too'; console.log(str.split(pattern));//将空格拆开分组成数组 exec方法123456789/* 统计子字符串出现的所有位置*/function count(str){ var b,r=/def/g; while(b = r.exec(str)){ console.log(b); }}count('abcdefabcdefabcdefabcdef'); 输出: 1234[ 'def', index: 3, input: 'abcdefabcdefabcdefabcdef' ][ 'def', index: 9, input: 'abcdefabcdefabcdefabcdef' ][ 'def', index: 15, input: 'abcdefabcdefabcdefabcdef' ][ 'def', index: 21, input: 'abcdefabcdefabcdefabcdef' ] 正则表达式选择一个正则表达式选择包含1个或多个正则表达式序列。这些序列被竖线(|)字符分隔。如果这些序列中的任何一项符合匹配条件,那么这个选择就被匹配。他会按顺序依次匹配 1"into".match(/in | int/); 以上将在into中匹配in。但他不会匹配int,因为in已经匹配成功了。 正则表达式转义1\\ / [ ] () { } ? + * | . ^ $ 如果希望按字面去匹配上面的字符,那么必须用一个\\前缀来进行转义。\\前缀不能使字母或数字字面化。 12345678910\\f : 换页符\\n : 换行符\\r : 回车符\\t : 制表(tab)符\\^ 匹配 ^ 符号本身\\$ 匹配 $ 符号本身\\. 匹配小数点(.)本身 实例123String.prototype.trim = function () { return this.replace(/(^\\s*)|(\\s*$)/g,'');}; ^表示字符串必须以后面的规则开头,而(^\\s*) 表示的就是以0个空格或者多个空格开头,后面的(\\s*$) 的意思就是, 以0个空格或者多个空格结尾。 匹配特定字符串12345^[A-Za-z]+$ //匹配由26个英文字母组成的字符串^[A-Z]+$ //匹配由26个英文字母的大写组成的字符串^[a-z]+$ //匹配由26个英文字母的小写组成的字符串^[A-Za-z0-9]+$ //匹配由数字和26个英文字母组成的字符串^\\w+$ //匹配由数字、26个英文字母或者下划线组成的字符串 评注:最基本也是最常用的一些表达式 思维导图","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Javascript基础总结七(Ajax+http)","date":"2016-03-20T12:05:01.000Z","path":"2016/03/20/Javascript基础总结七(Ajax+http)/","text":"Ajax及其工作原理AJAX 是一种与服务器交换数据无需刷新网页的技术,最早由Google公司在谷歌地图里使用,并迅速风靡。 AJAX是不能跨域的,如需跨域,可以使用document.domain='a.com';或者使用服务器代理,代理XMLHttpRequest文件 AJAX是基于现有的Internet标准,并且联合使用它们: 1234XMLHttpRequest 对象 (异步的与服务器交换数据)JavaScript/DOM (信息显示/交互)CSS (给数据定义样式)XML (作为转换数据的格式) 创建 XMLHttpRequest 对象所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。 创建Ajax对象: 12345//IE6以上var oAjax = new XMLHttpRequest();//IE6var oAjax =new ActiveXObject("Microsoft.XMLHTTP") 连接服务器1oAjax.open(方法,url,是否异步) 我们都知道,Ajax即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。所以,Ajax天生就是工作在异步模式的(异步为true,同步false) 同步和异步同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。(简单点说:同步就是只能一件一件事的来做,而异步就是可以多件事同时进行) 发送请求send()12345678910111213141516171819202122<script type="text/javascript">function getDoc(){ var xmlhttp; if(window.xmlhttpRequest){ xmlhttp=new XMLHttpRequest(); } else{ xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");//for IE6 } xmlhttp.onreadystatechange = function(){ if(xmlhttp.readyState==4&&xmlhttp.status==200){ document.getElementById("myId").innerHTML=xmlhttp.responseText; } } xmlhttp.open("GET", index.php,true); xmlhttp.send();}</script></head><body> <button type="button" onclick="getDoc()">请求数据</button></body> GET 还是 POST? 与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。 然而,在以下情况中,请使用 POST 请求: 123无法使用缓存文件(更新服务器上的文件或数据库)向服务器发送大量数据(POST 没有数据量限制)发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠 接收返回信息12345oAjax.onreadystatechange = function(){ //当请求状态改变时要调用的事件处理器 alert(oAjax.readystate); } 只要readyState属性的值发生变化时,便会触发一次readyStatechange事件。可以利用这个事件来检测每次状态变化后readyState的值。通常,我们只对readyState值为4的阶段感兴趣,因为这时所有数据都已经就绪,不过,必须在调用open()之前指定onreadystatechange事件处理程序才能确保跨浏览器兼容性。下面来看一个例子: 123456789101112var xhr = createXHR();xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { alert(xhr.statusText); } else { alert("Request was unsuccessful: " + xhr.status); } }};xhr.open("get", "example.txt", true);xhr.send(null); XHR对象XMLHttpRequest这个对象的属性: 它的属性有: 12345678onreadystatechange 每次状态改变所触发事件的事件处理程序。responseText 从服务器进程返回数据的字符串形式。responseXML 从服务器进程返回的DOM兼容的文档数据对象。status 从服务器返回的数字代码,比如常见的404(未找到)和200(已就绪)status Text 伴随状态码的字符串信息 当XHR对象把一个HTTP请求发送到服务器的过程中会经历几个状态,直到请求被处理,然后才接收一个回应。readyState就是XHR请求的状态属性,它本身有5个属性值: 123450(未初始化)还没有调用open()方法1(载入)已调用send()方法,正在发送请求2(载入完成)send()方法完成,已收到全部响应内容3(解析)正在解析响应内容4(完成)响应内容解析完成,可以再客户端使用了 http状态码1字头:消息。这一类型的状态码,代表请求已被接受,需要继续处理。2字头:成功。这一类型的状态码,代表请求已成功被服务器接收、理解、并接受。3字头:重定向。这类状态码代表需要客户端采取进一步的操作才能完成请求。4字头:客户端错误。这类状态码代表了客户端看起来可能发生错误,妨碍了服务器的处理。5字头:服务器错误。这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生 另附:http状态码详解w3cschool HTTP 状态消息:http://www.w3school.com.cn/ta… status和statusText statusText是响应返回的文本信息,仅当readyState值为3或4的时候才能使用。当readyState为其它值时视图存取statusText属性将引发异常。 XHR的方法 方法 描述 abort() 导致当前正在执行的请求被取消 getAllResponseHeaders() 返回包含所有响应头的名称和值的单个字符 getResponseHeader(name) 返回响应头中指定的名称和值 open(method,url,async,username,pwd) 设置HTTP方法(get或post)等 send(content) 发出带有指定主体内容的请求 setRequestHeader(name,value) 使用指定的名称和值设置请求头 12345678910111213141516<script type="text/javascript"> var oAjax =oAjax(); alert(oAjax.readyState);//弹出"0" oAjax.open("get","index.html",true); alert(oAjax.readyState);//弹出"1" oAjax.send(null); alert(oAjax.readyState);//IE下弹出4,而firefox是2 //可以通过readystatechange事件监听 oAjax = XHR(); oAjax.onreadystatechange = function () { alert(oAjax.readyState);//Firefox下依次是1,2,3,4但最后还会再来个1 //IE下则是1,1,3,4 }; oAjax.open("get","index.txt",true); oAjax.send(null);</script> jQuery中的Ajax.load()方法是局部方法,因为他需要一个包含元素的jQuery对象作为前缀,而$.get()和$.post()是全局方法,无需指定某个元素,对于用途而言,.load()适合做静态文件的异步获取,而对于需要传递参数到服务器页面的,$.get()和$.post()更加合适。 GET和POST传入的data是一个键值对 对象,不同的是GET传入的data是通过地址栏传输的,而POST是通过表单提交的, 1234567$(function () { $("input").click(function () { $.get('test.php?url=baidu.com', function (response,status,xhr) { $('#box').html(response); }) })}); POST提交不能使用url传参。post提交可以使用字符串形式的键值对形式传参,自动转换为http消息实体传参 1234567$(function () { $("input").click(function () { $.post('test.php','url=baidu.com', function (response,status,xhr) { $('#box').html(response); }) })}); 1234567891011//post提交可以使用对象键值对$(function () { $("input").click(function () { $.post('test.php',{ url:'baidu.com'//post提交可以使用对象键值对 }, function (response,status,xhr) { $('#box').html(response); }) })}); $.get()方法有四个参数,前面三个参数和.load()一样,多了一个第四参数type,即服务器返回的内容格式,包括xml,json,script,html,text等,第一个参数为必选参数,后面三个为可选参数 $.ajax()是所有Ajax方法中最底层的方法,所有其他方法都是基于$.ajax()方法的封装,这个方法只有一个参数,传递一个各个功能键值对的对象。 $.ajax()方法对象参数列表 参数 类型 说明 url string 发送请求的地址 type string 请求方法,默认GET timeout Number 设置请求超时的时间 data Object或String 发送到服务器的对象,键值对字符串或对象 datatype String 返回的数据类型,比如html,XML,json等 success Function 请求成功后调用的回调函数 complete Function 请求完成后调用的回调函数 error Function 请求失败后调用的回调函数 1234567891011121314$(function () { $("input").click(function () { $.ajax({ type : "POST", url: 'test.php', data:{ url: 'baidu.com' }, success : function(response,status,xhr){ $('#box').html(response); } }) })}); 表单序列化Ajax用的最多的地方莫过于表单操作,而传统的表单操作是通过submit提交将数据传输到服务器,如果使用Ajax异步处理的话,我们需要将每个表单元素获取才能提交,这样工作效率就大大降低 12345678910111213141516171819202122232425<body><form action=""> 用户名: <input type="text" name="user" /> 邮件: <input type="text" name="email" /> <input type="button" value="提交"/></form><div id="box"></div><script type="text/javascript"> $(function () { $("form input[type=button]").click(function () { $.ajax({ type: 'POST', url: 'test.php', data: { user: $('form input[name=user]').val(), email: $("form input[name=email]").val(), }, success: function(response){ $("#box").html(response); } }) }) });</script></body> 表单元素特别多的情况下应采用表单序列化,即data:$(“form”).serialize();//得到的是字符串键值对,并且对url进行编码 serialize()方法不但可以序列化表单内的元素,还可以直接获取单选框,复选框和下拉列表框等内容 123456789101112131415161718<body><form action=""> 用户名: <input type="text" name="user" /> 邮件: <input type="text" name="email" /> <input type="button" value="提交"/> <input type="radio" name="sex" value="男"/>男 <input type="radio" name="sex" value="女"/>女 <input type="button" value="submit"/></form><div id="box"></div><script> $(function () { $("form input[name=sex]").click(function () { $('#box').html(decodeURIComponent($(this).serialize())); }) })</script></body> 传统Ajax问题传统的ajax有如下的问题: 12345678910111、可以无刷新改变页面内容,但无法改变页面URL2、为了更好的可访问性,内容发生改变后,通常改变URL的hash3、hash的方式不能很好的处理浏览器的前进、后退等问题4、进而浏览器引入了onhashchange的接口,不支持的浏览器只能定时去判断hash是否改变5、但这种方式对搜索引擎很不友好6、twitter和google约定了使用#!xxx(即hash第一个字符为!),搜索引擎进行支持。","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Javascript基础总结六(数据类型和Json)","date":"2016-03-18T12:05:01.000Z","path":"2016/03/18/Javascript基础总结六(数据类型和Json)/","text":"什么是JSONJSON:JavaScript 对象表示法(JavaScript Object Notation)。 JSON的形式是用大括号“{}”包围起来的项目列表,每一个项目间用逗号(,)分隔,而项目就是用冒号(:)分隔的属性名和属性值。这是典型的字典表示形式,也再次表明javascript里的对象就是字典结构。不管多么复杂的对象,都可以用一句JSON代码来创建并赋值。在JSON中,名称/值对 包括字段名称(在双引号中),后面写一个冒号,然后是值 JSON 结构JSON有两种结构 json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构 1、对象:对象在js中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,...}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种。 2、数组:数组在js中是中括号“[]”括起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。经过对象、数组2种结构就可以组合成复杂的数据结构了。 JSON 语法规则JSON 语法是 JavaScript 对象表示法语法的子集。 1234数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组 JSON 值可以是: 123456数字(整数或浮点数)字符串(在双引号中)逻辑值(true 或 false)数组(在方括号中)对象(在花括号中)null 除以上6种外,再无其他,没有像js一样的undefined、NAN 12345671) 并列的数据之间用逗号(", ")分隔。2) 映射用冒号(": ")表示。3) 并列数据的集合(数组)用方括号("[]")表示。4) 映射的集合(对象)用大括号("{}")表示。 对象是一套无序的名/值对,一个对象以左边分支开始,以右边分支结束 一个值可以是用双引号括起来的字符串,或者是一个数值,一个true or false ,一个数组或者一个对象 JSON与对象字面量在编程语言中,字面量是一种表示值的记法。JSON规定键-值对中的键必须用双引号! 引号。例如: 1{"first name" : "Mike"}; 在JSON字符串中,不能使用函数或者正则表达式字面量 数据类型:从结构上看,所有的数据(data)最终都可以分解成三种类型: 12345第一种类型是标量(scalar),也就是一个单独的字符串(string)或数字(numbers),比如"北京"这个单独的词。第二种类型是序列(sequence),也就是若干个相关的数据按照一定顺序并列在一起,又叫做数组(array)或列表(List),比如"北京,上海"。第三种类型是映射(mapping),也就是一个名/值对(Name/value),即数据有一个名称,还有一个与之相对应的值,这又称作散列(hash)或字典(dictionary),比如"首都:北京"。 在编程语言中,只要有了数组(array)和对象(object)就能够储存一切数据了。 数组和对象的另一个区别是,数组的数据没有”名称”(name),对象的数据有”名称”(name)。 JavaScript中有5种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number和String。还有1种复杂数据类型——Object,Object本质上是由一组无序的名值对组成的。 对一个值使用typeof操作符可能返回下列某个字符串: 1234567891011"undefined"——如果这个值未定义;"boolean"——如果这个值是布尔值;"string"——如果这个值是字符串;"number"——如果这个值是数值;"object"——如果这个值是对象或null;"function"——如果这个值是函数; Undefined类型:12 `Undefined`类型只有一个值,在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined Null类型 Null类型是第二个只有一个值的数据类型,这个特殊的值是null。从逻辑角度来看,null值表示一个空对象指针,而这也正是使用typeof操作符检测null时会返回”object”的原因,例如: 12var car = null;alert(typeof car); // "object" Number类型 这种类型用来表示整数和浮点数值,还有一种特殊的数值,即NaN(非数值 Not a Number)。这个数值用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)。 String类型 String类型用于表示由零或多个16位Unicode字符组成的字符序列,即字符串。字符串可以由单引号(‘)或双引号(“)表示。 数值、布尔值、对象和字符串值都有toString()方法。但null和undefined值没有这个方法。 多数情况下,调用toString()方法不必传递参数。但是,在调用数值的toString()方法时,可以传递一个参数:输出数值的基数。 123456var num = 10;alert(num.toString()); //"10"alert(num.toString(2)); //"1010"alert(num.toString(8)); //"12"alert(num.toString(10)); //"10"alert(num.toString(16)); //"a" 在不知道要转换的值是不是null或undefined的情况下,还可以使用转型函数String(),这个函数能够将任何类型的值转换为字符串。String()函数遵循下列转换规则: ● 如果值有toString()方法,则调用该方法(没有参数)并返回相应的结果 ● 如果值是null,则返回”null“ ● 如果值是undefined,则返回”undefined“ Object类型 对象其实就是一组数据和功能的集合。对象可以通过执行new操作符后跟要创建的对象类型的名称来创建。而创建Object类型的实例并为其添加属性和(或)方法,就可以创建自定义对象。 1var o = new Object(); typeof 操作符1234567891011121314151617<script type="text/javascript"> var s = "Nicholas"; var b =true; var c = 21; var u; var n = null; var o = {}; var obj = new Object;//最好写出new object()形式 alert(typeof s);//string alert(typeof b);//boolean alert(typeof c);//number alert(typeof u);//undefined alert(typeof n);//object alert(typeof o);//object alert(typeof obj);//object</script>","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Javascript基础总结五(原型和原型链)","date":"2016-03-15T12:05:01.000Z","path":"2016/03/15/Javascript基础总结五(原型和原型链)/","text":"私有变量和函数在函数内部定义的变量和函数,如果不对外提供接口,外部是无法访问到的,也就是该函数的私有的变量和函数。 123456789<script type="text/javascript"> function Box(){ var color = "blue";//私有变量 var fn = function() //私有函数 { } }</script> 这样在函数对象Box外部无法访问变量color和fn,他们就变成私有的了: 123var obj = new Box(); alert(obj.color);//弹出 undefined alert(obj.fn);//同上 静态变量和函数当定义一个函数后通过点号 “.”为其添加的属性和函数,通过对象本身仍然可以访问得到,但是其实例却访问不到,这样的变量和函数分别被称为静态变量和静态函数。 12345678910111213141516<script type="text/javascript"> function Obj(){}; Obj.num = 72;//静态变量 Obj.fn = function() //静态函数 { } alert(Obj.num);//72 alert(typeof Obj.fn)//function var t = new Obj(); alert(t.name);//undefined alert(typeof t.fn);//undefined</script> 实例变量和函数在面向对象编程中除了一些库函数我们还是希望在对象定义的时候同时定义一些属性和方法,实例化后可以访问,js也能做到这样 123456789101112131415<script type="text/javascript"> function Box(){ this.a=[]; //实例变量 this.fn=function(){ //实例方法 } } console.log(typeof Box.a); //undefined console.log(typeof Box.fn); //undefined var box=new Box(); console.log(typeof box.a); //object console.log(typeof box.fn); //function</script> 为实例变量和方法添加新的方法和属性 123456789101112131415161718<script type="text/javascript">function Box(){ this.a=[]; //实例变量 this.fn=function(){ //实例方法 } } var box1=new Box(); box1.a.push(1); box1.fn={}; console.log(box1.a); //[1] console.log(typeof box1.fn); //object var box2=new Box(); console.log(box2.a); //[] console.log(typeof box2.fn); //function</script> 在box1中修改了a和fn,而在box2中没有改变,由于数组和函数都是对象,是引用类型,这就说明box1中的属性和方法与box2中的属性与方法虽然同名但却不是一个引用,而是对Box对象定义的属性和方法的一个复制。 这个对属性来说没有什么问题,但是对于方法来说问题就很大了,因为方法都是在做完全一样的功能,但是却又两份复制,如果一个函数对象有上千和实例方法,那么它的每个实例都要保持一份上千个方法的复制,这显然是不科学的,这可肿么办呢,prototype应运而生。 基本概念我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。那么,prototype就是通过调用构造函数而创建的那个对象实例的原型对象。 使用原型的好处是可以让对象实例共享它所包含的属性和方法。也就是说,不必在构造函数中添加定义对象信息,而是可以直接将这些信息添加到原型中。使用构造函数的主要问题就是每个方法都要在每个实例中创建一遍。 在JavaScript中,一共有两种类型的值,原始值和对象值。每个对象都有一个内部属性 prototype ,我们通常称之为原型。原型的值可以是一个对象,也可以是null。如果它的值是一个对象,则这个对象也一定有自己的原型。这样就形成了一条线性的链,我们称之为原型链。 含义函数可以用来作为构造函数来使用。另外只有函数才有prototype属性并且可以访问到,但是对象实例不具有该属性,只有一个内部的不可访问的__proto__属性。__proto__是对象中一个指向相关原型的神秘链接。按照标准,__proto__是不对外公开的,也就是说是个私有属性,但是Firefox的引擎将他暴露了出来成为了一个共有的属性,我们可以对外访问和设置。 123456789<script type="text/javascript"> var Browser = function(){}; Browser.prototype.run = function(){ alert("I'm Gecko,a kernel of firefox"); } var Bro = new Browser(); Bro.run();</script> 当我们调用Bro.run()方法时,由于Bro中没有这个方法,所以,他就会去他的__proto__中去找,也就是Browser.prototype,所以最终执行了该run()方法。(在这里,函数首字母大写的都代表构造函数,以用来区分普通函数) 当调用构造函数创建一个实例的时候,实例内部将包含一个内部指针(__proto__)指向构造函数的prototype,这个连接存在于实例和构造函数的prototype之间,而不是实例与构造函数之间。 12345678910111213141516<script type="text/javascript">function Person(name){ //构造函数 this.name=name; } Person.prototype.printName=function() //原型对象 { alert(this.name); } var person1=new Person('Byron');//实例化对象 console.log(person1.__proto__);//Person console.log(person1.constructor);//自己试试看会是什么吧 console.log(Person.prototype);//指向原型对象Person var person2=new Person('Frank');</script> Person的实例person1中包含了name属性,同时自动生成一个__proto__属性,该属性指向Person的prototype,可以访问到prototype内定义的printName方法,大概就是这个样子的: 每个JavaScript函数都有prototype属性,这个属性引用了一个对象,这个对象就是原型对象。原型对象初始化的时候是空的,我们可以在里面自定义任何属性和方法,这些方法和属性都将被该构造函数所创建的对象继承。 那么,现在问题来了。构造函数、实例和原型对象三者之间有什么关系呢? 构造函数、实例和原型对象的区别实例就是通过构造函数创建的。实例一创造出来就具有constructor属性(指向构造函数)和__proto__属性(指向原型对象), 构造函数中有一个prototype属性,这个属性是一个指针,指向它的原型对象。 原型对象内部也有一个指针(constructor属性)指向构造函数:Person.prototype.constructor = Person; 实例可以访问原型对象上定义的属性和方法。 在这里person1和person2就是实例,prototype是他们的原型对象。 再举个栗子: 12345678910111213141516171819<script type="text/javascript"> function Animal(name) //积累构造函数 { this.name = name;//设置对象属性 } Animal.prototype.behavior = function() //给基类构造函数的prototype添加behavior方法 { alert("this is a "+this.name); } var Dog = new Animal("dog");//创建Dog对象 var Cat = new Animal("cat");//创建Cat对象 Dog.behavior();//通过Dog对象直接调用behavior方法 Cat.behavior();//output "this is a cat" alert(Dog.behavior==Cat.behavior);//output true;</script> 可以从程序运行结果看出,构造函数的prototype上定义的方法确实可以通过对象直接调用到,而且代码是共享的。(可以试一下将Animal.prototype.behavior 中的prototype属性去掉,看看还能不能运行。)在这里,prototype属性指向Animal对象。 数组对象实例再看个数组对象的实例。当我们创建出array1这个对象的时候,array1实际在Javascript引擎中的对象模型如下: 1var array1 = [1,2,3]; array1对象具有一个length属性值为3,但是我们可以通过如下的方法来为array1增加元素: 1array1.push(4); push这个方法来自于array1的__proto__成员指向对象的一个方法(Array.prototye.push())。正是因为所有的数组对象(通过[]来创建的)都包含有一个指向同一个具有push,reverse等方法对象(Array.prototype)的__proto__成员,才使得这些数组对象可以使用push,reverse等方法。 函数对象实例123function Base() { this.id = "base" } 1var obj = new Base(); 这样代码的结果是什么,我们在Javascript引擎中看到的对象模型是: new操作符具体干了什么呢?其实很简单,就干了三件事情。 123var obj = {}; obj.__proto__ = Base.prototype; Base.call(obj); 原型链原型链:当从一个对象那里调取属性或方法时,如果该对象自身不存在这样的属性或方法,就会去自己关联的prototype对象那里寻找,如果prototype没有,就会去prototype关联的前辈prototype那里寻找,如果再没有则继续查找Prototype.Prototype引用的对象,依次类推,直到Prototype.….Prototype为undefined(Object的Prototype就是undefined)从而形成了所谓的“原型链”。 12345678910111213141516171819202122<script type="text/javascript"> function Shape(){ this.name = "shape"; this.toString = function(){ return this.name; } } function TwoShape(){ this.name = "2 shape"; } function Triangle(side,height){ this.name = "Triangle"; this.side = side; this.height = height; this.getArea = function(){ return this.side*this.height/2; } } TwoShape.prototype = new Shape(); Triangle.prototype = new TwoShape();</script> 这里,用构造器Shape()新建了一个实体,然后用它去覆盖该对象的原型。 123456789101112131415161718192021222324252627282930<script type="text/javascript"> function Shape(){ this.name = "shape"; this.toString = function(){ return this.name; } } function TwoShape(){ this.name = "2 shape"; } function Triangle(side,height){ this.name = "Triangle"; this.side = side; this.height = height; this.getArea = function(){ return this.side*this.height/2; } } TwoShape.prototype = new Shape(); Triangle.prototype = new TwoShape(); TwoShape.prototype.constructor = TwoShape; Triangle.prototype.constructor = Triangle; var my = new Triangle(5,10); my.getArea(); my.toString();//Triangle my.constructor;//Triangle(side,height)</script> 原型继承原型继承:在原型链的末端,就是Object构造函数prototype属性指向的那个原型对象。这个原型对象是所有对象的祖先,这个老祖宗实现了诸如toString等所有对象天生就该具有的方法。其他内置构造函数,如Function,Boolean,String,Date和RegExp等的prototype都是从这个老祖宗传承下来的,但他们各自又定义了自身的属性和方法,从而他们的子孙就表现出各自宗族的那些特征。 ECMAScript中,实现继承的方法就是依靠原型链实现的。 12345678910111213141516<script type="text/javascript"> function Father(){ //被继承的函数叫做超类型(父类,基类) this.name = "Jack";}function Son(){ //继承的函数叫做子类型(子类,派生类) this.age = 10;}//通过原型链继承,赋值给子类型的原型属性//new Father()会将father构造里的信息和原型里的信息都交给SonSon.prototype = new Father();//Son继承了Father,通过原型,形成链条var son = new Son();alert(son.name);//弹出 Jack</script> 原型链的问题:原型链虽然很强大,可以用它来实现继承,但它也存在一些问题。其中最主要的问题来自包含引用类型的值原型。包含引用类型的原型属性会被所有实例共享;而这也正是为什么要在构造函数中,而不是在原型对象中定义属性的原因。在通过原型来实现继承时,原型实际上回变成另一个类型的实例。于是,原先的实例属性也就变成了原型的属性。 在创建子类型的实例时,不能向超类型的构造函数中传递参数。实际上,应该说是没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数。再加上刚刚讨论的由于原型中包含引用类型值所带来的问题,实践中很少会单独使用原型链。 再举个栗子: 123456789101112131415161718192021222324<script type="text/javascript"> function Person(name) { this.name = name;//设置对象属性 }; Person.prototype.company = "Microsoft";//设置原型的属性 Person.prototype.SayHello = function() //原型的方法 { alert("Hello,I'm "+ this.name+ " of " + this.company); }; var BillGates = new Person("BillGates");//创建person对象 BillGates.SayHello();//继承了原型的内容,输出"Hello,I'm BillGates of Microsoft" var Jobs = new Person("Jobs"); Jobs.company = "Apple";//设置自己的company属性,掩盖了原型的company属性 Jobs.SayHello = function() { alert("Hi,"+this.name + " like " + this.company); }; Jobs.SayHello();//自己覆盖的属性和方法,输出"Hi,Jobs like Apple" BillGates.SayHello();//Jobs的覆盖没有影响原型,BillGates还是照样输出</script> __ptoto__属性__ptoto__属性(IE浏览器不支持)是实例指向原型对象的一个指针,它的作用就是指向构造函数的原型属性constructor,通过这两个属性,就可以访问原型里的属性和方法了。 Javascript中的对象实例本质上是由一系列的属性组成的,在这些属性中,有一个内部的不可见的特殊属性——__proto__,该属性的值指向该对象实例的原型,一个对象实例只拥有一个唯一的原型。 123456789101112131415<script type="text/javascript"> function Box(){ //大写,代表构造函数 Box.prototype.name = "trigkit4";//原型属性 Box.prototype.age = "21"; Box.prototype.run = function()//原型方法 { return this.name + this.age + 'studying'; } } var box1 = new Box(); var box2 = new Box(); alert(box1.constructor);//构造属性,可以获取构造函数本身, //作用是被原型指针定位,然后得到构造函数本身</script> __proto__属性和prototype属性的区别prototype是function对象中专有的属性。__proto__是普通对象的隐式属性,在new的时候,会指向prototype所指的对象;__ptoto__实际上是某个实体对象的属性,而prototype则是属于构造函数的属性。__ptoto__只能在学习或调试的环境下使用。 原型模式的执行流程1.先查找构造函数实例里的属性或方法,如果有,就立即返回。2.如果构造函数的实例没有,就去它的原型对象里找,如果有,就立即返回 原型对象的123456789101112131415161718<script type="text/javascript"> function Box(){ //大写,代表构造函数 Box.prototype.name = "trigkit4";//原型属性 Box.prototype.age = "21"; Box.prototype.run = function()//原型方法 { return this.name + this.age + 'studying'; } } var box1 = new Box(); alert(box1.name);//trigkit4,原型里的值 box1.name = "Lee"; alert(box1.name);//Lee,就进原则 var box2 = new Box(); alert(box2.name);//trigkit4,原型的值,没有被box1修改</script> 构造函数的1234567891011121314151617<script type="text/javascript"> function Box(){ this.name = "Bill"; } Box.prototype.name = "trigkit4";//原型属性 Box.prototype.age = "21"; Box.prototype.run = function()//原型方法 { return this.name + this.age + 'studying'; } var box1 = new Box(); alert(box1.name);//Bill,原型里的值 box1.name = "Lee"; alert(box1.name);//Lee,就进原则</script> 综上,整理一下: 123456789101112131415161718<script type="text/javascript"> function Person(){}; Person.prototype.name = "trigkit4"; Person.prototype.say = function(){ alert("Hi"); } var p1 = new Person();//prototype是p1和p2的原型对象 var p2 = new Person();//p2为实例化对象,其内部有一个__proto__属性,指向Person的prototype console.log(p1.prototype);//undefined,这个属性是一个对象,访问不到 console.log(Person.prototype);//Person console.log(Person.prototype.constructor);//原型对象内部也有一个指针(constructor属性)指向构造函数 console.log(p1.__proto__);//这个属性是一个指针指向prototype原型对象 p1.say();//实例可以访问到在原型对象上定义的属性和方法 </script> 123构造函数.prototype = 原型对象原型对象.constructor = 构造函数(模板)原型对象.isPrototypeof(实例对象) 判断实例对象的原型 是不是当前对象 工厂模式123456 function createObject(name,age){ var obj = new Object(); obj.name = name; obj.age = age; return obj;} 工厂模式解决了实例化对象大量重复的问题,但还有一个问题,那就是根本无法搞清楚他们到底是哪个对象的实例。使用构造函数的方法,既解决了重复实例化的问题,又解决了对象识别的问题。 使用构造函数的方法和工厂模式的不同之处在于: 1231.构造函数方法没有显示的创建对象(new Object());2.直接将属性和方法赋值给this对象3.没有return 语句 当使用了构造函数,并且new 构造函数(),那么就在后台执行了new Object();函数体内的this代表了new Object()出来的对象 1234561.判断属性是在构造函数的实例里,还是在原型里,可以使用`hasOwnProperty()`函数2.字面量创建的方式使用constructor属性不会指向实例,而会指向Object,构造函数创建的方式则相反为什么指向Object?因为Box.prototype = {};这种写法其实就是创建了一个新对象。而每创建一个函数,就会同时创建它的prototype,这个对象也会自动获取constructor属性3.如果是实例方法,不同的实例化,他们的方法地址是不一样的,是唯一的4.如果是原型方法,那么他们的地址的共享的","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Javascript基础总结四(function)","date":"2016-03-10T12:05:01.000Z","path":"2016/03/10/Javascript基础总结四(function)/","text":"概念 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。 js 支持两种函数:一类是语言内部的函数(如eval() ),另一类是自己创建的。 在 JavaScript 函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它。(该变量的作用域是局部的)。 您可以在不同的函数中使用名称相同的局部变量,因为只有声明过该变量的函数才能识别出该变量。 函数调用有如下四种调用js函数的方式: 作为函数 作为方法 作为构造函数 通过call()和apply() 返回函数的函数1231. 当函数无明确返回值时,返回的值就是`undefined`。2. 当函数有返回值时,返回值是什么就返回什么。 我们可以通过使用 return 语句实现将函数返回调用它的地方。 在使用 return 语句时,函数会停止执行,并返回指定的值。 函数通常会返回一个唯一值,那么这个值也可能是另一个函数: 1234567891011<script type="text/javascript"> //函数表达式 var box = function(){ var a=1; return function(){ alert(a++) } alert(a);//永远不会执行 } alert(box());//弹出"function(){alert(a++)}"</script> 在这里,我们只需将返回值赋值给某个变量,然后就可以像使用一般函数那样调用它了: 12345678910<script type="text/javascript"> var box = function(){ var a=1; return function(){ alert(++a) } } var newFunc = box(); newFunc();//2</script> 如果想让返回的函数立即执行,亦可以使用box()()来执行这段代码。 ECMAScript所有函数的参数都是按值传递的,言下之意就是参数不会按引用传递。 PS:如果存在按引用传递的话,那么函数里的那个变量将会是全局变量,在外部也可以访问。 12(1)值类型:数值、布尔值、null、undefined。(2)引用类型:对象、数组、函数。 引用类型值:指的是那些保存在堆内存中的对象,意思是,变量中保存的实际上只是一个指针,这个指针执行内存中的另一个位置,由该位置保存对象; 创建匿名函数123function(){ return ‘hi’; //单独的匿名函数是无法运行的,就算能运行也无法调用,因为没有名字} 这种匿名函数的用法在JQuery中非常多。直接声明一个匿名函数,立即使用。用匿名函数的好处就是省得定义一个用一次就不用的函数,而且免了命名冲突的问题,js中没有命名空间的概念,因此很容易函数名字冲突,一旦命名冲突以最后声明的为准。 在javascript语言里任何匿名函数都是属于window对象。在定义匿名函数时候它会返回自己的内存地址,如果此时有个变量接收了这个内存地址,那么匿名函数就能在程序里被使用了,因为匿名函数也是在全局执行环境构造时候定义和赋值,所以匿名函数的this指向也是window对象 123(function(){ console.log(this === window);//true})(); 通过自我执行来执行匿名函数: 1234567//通过自我执行来执行匿名函数<script type="text/javascript"> (function (){ // (匿名函数)();第一圆括号放匿名函数,第二个圆括号执行 alert('Lee'); })();</script> 把匿名函数自我执行的返回值赋给变量: 12345678910111213//把匿名函数自我执行的返回值赋给变量<script type="text/javascript"> var box = (function (){ alert('Lee'); })(); //弹出”Lee”; alert(box); //弹出 undefined</script>var box= (function () { return 'hi';})();console.log(box);//hi 自我执行匿名函数的传参: 1234567//自我执行匿名函数的传参<script type="text/javascript"> (function (age){ alert(age); })(100); //弹出100</script> 自执行函数的三种写法123var result = function (){ alert(2);}(); 另一种语法也可得到同样结果: 123var result = (function () { console.log(2);})(); 将函数返回值分配给变量: 123var result = (function () { return 2;}()); js创建动态函数: js支持创建动态函数,动态函数必须用Function对象来定义(Function是js中的一个对象,是固定不变的,规定Function对象的”F”必须大写,当是function的时候,我们知道是定义函数的时候所使用的一个关键字:function funName(x,y),当是Function的时候(F大写的时候),我们知道是js中的对象) 创建动态函数的基本格式:var 变量名 = new Function("参数1","参数2","参数n","执行语句"); 看下面的一段代码: 1234<script type="text/javascript"> var square = new Function ("x","y","var sum ; sum = x+y;return sum;"); alert("square(2,3)的结果是:"+square(2,3)); //square(2,3)的结果是:5</script> square是动态创建的函数,在Function对象后面的括号里的每一部分内容都必须是字符串形式的,也就是说都必须用引号(””或者是’’)括起来 这段代码: 1var square = new Function ("x","y","var sum ; sum = x+y;return sum;"); 和下面这段代码: 123456//函数声明function square (x,y){ var sum; sum = x+y; return sum; } 是一摸一样的,只不过一个是动态函数,一个是静态函数。我们为什么要把代码分成一小段一小段的代码呢?,把一个字符串分成了若干个独立的字符串的优点就在于我们可以通过修改其中的某些字符串来随时改变函数的作用。 回调函数回调就是一个函数的调用过程。那么就从理解这个调用过程开始吧。函数a有一个参数,这个参数是个函数b,当函数a执行完以后执行函数b。那么这个过程就叫回调。 其实中文也很好理解:回调,回调,就是回头调用的意思。函数a的事先干完,回头再调用函数b。 这里必须清楚一点:函数b是你以参数形式传给函数a的,那么函数b就叫回调函数。 在jquery里的绝大多数效果函数都涉及到callback函数。jquery效果函数例如: 12345<script type="text/javascript"> $("div").show(1000,function(){ //callback function });</script> 这里的callback function换成实例可以是: 12345<script type="text/javascript"> $("div").show(1000,function(){ console.log("hello world") });</script> Callback实际上是,当一个函数执行完后,现执行的那个函数就是所谓的callback函数。怎么样?很好理解吧…… 方法和函数的区别1234567891011var arr = [1,2,3,4,5]var a =12; // 变量:自由的arr.a= 5; //属性:属于一个对象function show() //函数:自由的{ alert(‘a’);}arr.fn = function() //方法:属于一个对象{ alert(‘b’);} 其实方法就是函数,只不过方法是有所属的对象。 我们所熟知的,将函数绑定到 click 事件语法: 1$(selector).click(function) 参数 描述 function 可选。规定当发生 click 事件时运行的函数. 这种形式在jquery中经常见到。它是将function当做该方法的参数,向该方法添加一个事件处理函数。 js全局函数全局函数与内置对象的属性或方法不是一个概念。全局函数它不属于任何一个内置对象。JavaScript 中包含以下 7 个全局函数,用于完成一些常用的功能: 12escape( )、eval( )、isFinite( )、isNaN( )、parseFloat( )、parseInt( )、unescape( )。 函数的几个作用作为一个类构造器使用123function Class(){}Class.prototype={};var item=new Class(); 作为闭包使用123(function(){ //独立作用域})(); 作为构造函数调用所谓构造函数,就是通过这个函数生成一个新对象(object)。 12345678<script type="text/javascript"> function Test(){//大写,以区分普通函数 this.x = 10; } var obj = new Test(); alert(obj.x); //弹出 10; </script> 可以使用 new 运算符结合像 Object()、Date() 和 Function() 这样的预定义的构造函数来创建对象并对其初始化。面向对象的编程其强有力的特征是定义自定义构造函数以创建脚本中使用的自定义对象的能力。创建了自定义的构造函数,这样就可以创建具有已定义属性的对象。下面是自定义函数的示例(注意 this 关键字的使用)。 12345function Circle (xPoint, yPoint, radius) { this.x = xPoint; // 圆心的 x 坐标。 this.y = yPoint; // 圆心的 y 坐标。 this.r = radius; // 圆的半径。} 调用 Circle 构造函数时,给出圆心点的值和圆的半径(所有这些元素是完全定义一个独特的圆对象所必需的)。结束时 Circle 对象包含三个属性。下面是如何例示 Circle 对象。 1var aCircle = new Circle(5, 11, 99); 使用构造器函数的优点是,它可以根据参数来构造不同的对象。 缺点是构造时每个实例对象都会生成重复调用对象的方法,造成了内存的浪费。 1234567891011121314<script type="text/javascript"> function Test(name){ this.occupation = "coder"; this.name = name; this.whoAreYou = function(){ return "I'm " + this.name + "and I'm a " + this.occupation; } } var obj = new Test('trigkit4');//利用同一个构造器创建不同的对象 var obj2 = new Test('student'); obj.whoAreYou();//"I'm trigkit4 and I'm a corder" obj2.whoAreYou();//"I'm student and I'm a corder" </script> 依照惯例,我们应该将构造器函数的首字母大写,以便显著地区别于一般的函数。 以下两种形式的定义函数方式是等价的。 123456<script type="text/javascript"> var test = function(){ alert("Hello World"); } alert(typeof(test));//output function</script> 这里明确定义了一个变量test,他的初始值被赋予了一个function实体 123456<script type="text/javascript"> function test(){ alert("Hello World"); } alert(typeof(test));//output function</script> 看看下面这种定义式函数形式: 1234567891011<script type="text/javascript"> function test(){ alert("Hello World"); }; test();//居然输出Hello,很奇怪不是吗? function test(){ alert("Hello"); }; test();//正常滴输出了Hello</script> 很显然,第一个函数并没有起到作用,很奇怪不是吗?我们知道,javascript解析引擎并不是一行一行地执行代码,而是一段一段地执行代码。在同一段程序的分析执行中,定义式的函数语句会被优先执行,所以第一个定义的代码逻辑已经被第二个覆盖了,所以两次调用相同函数,只会执行第二个。 作为值的函数函数在js中不仅是一种语法,也是一个值。也就是说可以将函数赋值给变量,存储在对象的属性或数组的元素中,作为参数传入另一个函数中。函数的名字实际是看不见的,它仅仅是变量的名字,这个变量指代函数对象 12345678<script type="text/javascript"> function square(x,y){ return x*y; } var s = square; //s和square指代同一个函数 square(2,3);//6 s(2,4);//8</script> 除了可以将函数赋值给变量,同样可以将函数赋值给对象的属性,当函数作为对象的属性调用时,函数就称为方法 123456<script type="text/javascript"> var obj = {square:function(x,y){ //对象直接量 return x*y; }}; var ect = obj.square(2,3);</script> prototype属性每一个函数都包含prototype属性,这个属性指向一个对象的引用,这个对象称为原型对象。详见:javascript学习总结(五)原型和原型链 call()和apply()apply()函数有两个参数:第一个参数是上下文,第二个参数是参数组成的数组。如果上下文是null,则使用全局对象代替。例如: 1function.apply(this,[1,2,3]) call()的第一个参数是上下文,后续是实例传入的参数序列,例如: 1function.call(this,1,2,3); 高阶函数这里的高阶函数可不是高数里的那个高阶函数,所谓高阶函数就是操作函数的函数,它接收一个或多个函数作为参数,并返回新函数 参数arguments当函数被调用时,会得到一个免费奉送的参数数组,那就是arguments数组。通过它,函数可以访问所有它被调用时传递给他的参数列表。这使得编写一个无需指定参数个数的函数成为可能。 12345678910<script type="text/javascript"> var sum = function(){ var i ,sum =0; for(i = 0;i<arguments.length;i+=1){ sum+=arguments[i]; } return sum; }; document.writeln(sum(4,5,23,13,35,46,-10));//116</script> 在ECMAScript中的参数在内部是用一个数组来表示的,函数接收到的始终都是这个数组,而不关心数组中包含哪些参数 1234567function add(num1,num2){ num = num1 + num2; return num;}var result = 12,count = 20;alert(add(result,count));//32;命名的参数只提供便利,解析器不会验证命名参数 实际上,arguments并不是一个真正的数组,它只是一个类数组的对象,它拥有一个length属性,但他缺少所有数组的方法。另外,arguments对象的长度是由传入的参数个数决定的,而不是由定义函数时的命名参数的个数决定的 函数在定义或者声明的时候,所有的参数都是形参,因此,我们可以根据实际情况来命名参数,函数也只有在被调用时才会传入实参。而每个函数在被调用时都会自动取得两个特殊变量:this 和 arguments 函数的递归函数的递归,即一个函数在通过名字调用自身的情况下构成的: 通过使用argument.callee代替函数名: 12345678910//arguments.callee是一个指向正在执行的函数的指针<script> function factorial(num){ if(num<=1){ return 1; }else{ return num*arguments.callee(num-1); } }</script> 思维导图最后附上一张前辈总结的思维导图:","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Javascript基础总结三(BOM+DOM)","date":"2016-03-08T12:05:01.000Z","path":"2016/03/08/Javascript基础总结三(BOM+DOM)/","text":"DOM介绍D(文档)可以理解为整个Web加载的网页文档,O(对象)可以理解为类似window对象只来的东西,可以调用属性和方法,这里我们说的是document对象,M(模型)可以理解为网页文档的树形结构,DOM树由节点构成 1节点种类:元素节点、文本节点和属性节点 DOM(文档对象模型)是 HTML 和 XML 的应用程序接口(API)。DOM代表着被加载到浏览器窗口里的当前网页:浏览器向我们提供了当前网页的地图(或者说模型),而我们可以通过js去读取这张地图。 BOM 主要处理浏览器窗口和框架,不过通常浏览器特定的 JavaScript 扩展都被看做 BOM 的一部分。这些扩展包括: 123456弹出新的浏览器窗口移动、关闭浏览器窗口以及调整窗口大小提供 Web 浏览器详细信息的定位对象提供用户屏幕分辨率详细信息的屏幕对象对 cookie 的支持IE 扩展了 BOM,加入了 ActiveXObject 类,可以通过 JavaScript 实例化 ActiveX 对象 window对象对应着浏览器窗口本身,这个对象的属性和方法通常被称为BOM DOM包含:window 123Window对象包含属性:document、location、navigator、screen、history、framesDocument根节点包含子节点:forms、location、anchors、images、links 从window.document已然可以看出,DOM的最根本的对象是BOM的window对象的子对象。 区别:DOM描述了处理网页内容的方法和接口,BOM描述了与浏览器进行交互的方法和接口。 根据W3C DOM规范,DOM是HTML与XML的应用编程接口(API),DOM将整个页面映射为一个由层次节点组成的文件。有1级、2级、3级共3个级别。 先来看看下面代码: 1234567891011121314151617 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>DOM</title> </head> <body> <h2><a href="http://www.baidu.com">javascript DOM</a></h2> <p>对HTML元素进行操作,可添加、改变或移除css样式等</p> <ul> <li>Javascript</li> <li>DOM</li> <li>CSS</li> </ul> </body> </html> 将HTML代码分解为DOM节点层次图: 1234 **HTML文档可以说由节点构成的集合,DOM节点有:**1. 元素节点:上图中<html>、<body>、<p>等都是元素节点,即标签。2. 文本节点:向用户展示的内容,如<li>...</li>中的JavaScript、DOM、CSS等文本。3. 属性节点:元素属性,如<a>标签的链接属性href="http://www.baidu.com"。 查找元素W3C提供了比较方便的定位节点的方法和属性,如下所示:| 方法 | 说明 || ————- |:————-:|| getElementById() | 获取特定ID元素的节点 || getElementsByTagName() | 获取相同元素的节点列表 || getElementsByName | 获取相同名称的节点列表 || getAttribute() | 获取特定元素节点属性的值 || setAttribute() | 设置特定元素节点属性的值 || removeAttribute() | 移除特定元素节点属性 | 元素节点属性 节点属性 nodeName 返回一个字符串,其内容是节点的名字 nodeType 返回一个整数,这个数值代表给定节点的类型 nodeValue 返回给定节点的当前值 属性 说明 tagName 获取原酸节点的标签名 innerHTML 获取元素节点的内容 遍历节点树 遍历节点树 childNodes 返回一个数组,这个数组由给定元素的子节点构成 firstChild 返回第一个子节点 lastChild 返回最后一个子节点 parentNode 返回一个给定节点的父节点 nextSibling 返回给定节点的下一个子节点 previousSibling 返回给定节点的上一个子节点 DOM操作 DOM操作 creatElement(element) 创建一个新的元素节点 creatTextNode() 创建一个包含给定文本的新文本节点 appendChild() 指定节点的最后一个节点列表后添加一个新的子节 insertBefore() 将一个给定节点插入到一个给定元素节点的给定子节点的前面 removeChild() 从一个给定元素中删除子节点 replaceChild() 把一个给定父元素里的一个子节点替换为另外一个节点 DOM通过创建树来表示文档,描述了处理网页内容的方法和接口,从而使开发者对文档的内容和结构具有空前的控制力,用DOM API可以轻松地删除、添加和替换节点。 1. 访问节点12345`var oHtml = document.documentElement;` //返回存在于 XML 以及 HTML 文档中的文档根节点,oHtml包含了一个表示<html />的HTMLElement对象`document.body` //是对 HTML 页面的特殊扩展,提供了对 <body> 标签的直接访问</span><span></span></span>`document.getElementById("ID")` //通过指定的 ID 来返回元素,getElementById() 无法工作在 XML 中,IE6还会返回name为指定ID的元素`document.getElementByName("name")`//获取所有name特性等于指定值的元素,不过在IE6和Opera7.5上还会返回id为给定名称的元素且仅检查<input/>和<img/>`var x=document.getElementsByTagName("p");` //使用指定的标签名返回所有的元素列表NodeList,索引号从0开始。当参数是一个星号的时候,IE6并不返回所有的元素,必须用document.all来替代 2. Node节点的特性和方法1234567891011firstChild //Node,指向在childNodes列表中的第一个节点 lastChild //Node,指向在childNodes列表中的最后一个节点 parentNode //Node,指向父节ownerDocument //Document,指向这个节点所属的文档 firstChild //Node,指向在childNodes列表中的第一个节点 lastChild //Node,指向在childNodes列表中的最后一个节点 parentNode //Node,指向父节点 childNodes //NodeList,所有子节点的列表 previousSibling /Node,/指向前一个兄弟节点:如果这个节点就是第一个节点,那么该值为 null `nextSibling` //Node,指向后一个兄弟节点:如果这个节点就是最后一个节点,那么该值为null `hasChildNodes()` //Boolean,当childNodes包含一个或多个节点时,返回真值 3.DOM事件12345678910DOM同时两种事件模型:冒泡型事件和捕获型事件 冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标的顺序触发 <body onclick="handleClick()"> <div onclick="handleClick()">Click Me</div> </body> 触发的顺序是:div、body、html(IE 6.0和Mozilla 1.0)、document、window(Mozilla 1.0) 捕获型事件:与冒泡事件相反的过程,事件从最不精确的对象开始触发,然后到最精确 上面例子触发的顺序是:document、div DOM事件模型最独特的性质是,文本节点也触发事件(在IE中不会)。 4.事件处理函数/监听函数123456789 **事件处理函数/监听函数** 在JavaScript中: var oDiv = document.getElementById("div1"); oDiv.onclick = function(){ //onclick只能用小写,默认为冒泡型事件 alert("Clicked!"); } 在HTML中: <div onclick="javascript: alert("Clicked!")"></div> //onclick大小写任意 IE事件处理程序attachEvent()和detachEvent()在IE中,每个元素和window对象都有两个方法:attachEvent()和detachEvent(),这两个方法接受两个相同的参数,事件处理程序名称和事件处理程序函数,如: 12345678[object].attachEvent("name_of_event_handler","function_to_attach") [object].detachEvent("name_of_event_handler","function_to_remove") var fnClick = function(){ alert("Clicked!"); } oDiv.attachEvent("onclick", fnClick); //添加事件处理函数 oDiv.attachEvent("onclick", fnClickAnother); // 可以添加多个事件处理函数 oDiv.detachEvent("onclick", fnClick); //移除事件处理函数 在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此this等于window。 跨浏览器的事件处理程序1addHandler()和removeHandler() addHandler()方法属于一个叫EventUntil()的对象,这两个方法均接受三个相同的参数,要操作的元素,事件名称和事件处理程序函数。 事件类型12345**事件类型** 鼠标事件:click、dbclick、mousedown、mouseup、mouseover、mouseout、mousemove 键盘事件:keydown、keypress、keyup HTML事件:load、unload、abort、error、select、change、submit、reset、resize、scroll、focus、blur 事件处理器执行JavaScript 代码的程序在事件发生时会对事件做出响应。为了响应一个特定事件而被执行的代码称为事件处理器。 在HTML标签中使用事件处理器的语法是: 1<HTML标签 事件处理器="JavaScript代码''> 事件处理程序事件就是用户或浏览器自身执行的某种动作。比如click,mouseup,keydown,mouseover等都是事件的名字。而响应某个事件的函数就叫事件处理程序(事件监听器),事件处理程序以on开头,因此click的事件处理程序就是onclick DOM 0级事件处理程序DOM 0级事件处理程序:把一个函数赋值给一个事件的处理程序属性 12345678<input type="button" value="按钮2" id="ben2"/> var btn2=document.getElementById('btn2');获得btn2按钮对象 btn2.onclick //给btn2添加onclick属性,属性又触发了一个事件处理程序btn2.onclick=function(){} //添加匿名函数btn2.onclick=null //删除onclick属性 如何阻止冒泡?阻止冒泡有以下方法: 123e.cancelBubble=true;e.stopPropagation();return false; innerText、innerHTML、outerHTML、outerText123456innerText、innerHTML、outerHTML、outerTextinnerText: 表示起始标签和结束标签之间的文本 innerHTML: 表示元素的所有元素和文本的HTML代码 如:<div><b>Hello</b> world</div>的innerText为Hello world,innerHTML为Hello world outerText: 与前者的区别是替换的是整个目标节点,问题返回和innerText一样的内容 outerHTML: 与前者的区别是替换的是整个目标节点,返回元素完整的HTML代码,包括元素本身 DOM 2级事件处理程序DOM 2级事件定义了两个方法,用于指定和删除事件处理程序的操作。addEventListener()和removeEventListener() addEventListener()和removeEventListener()123456789101112131415161718192021222324在DOM中,addEventListener()和removeEventListener()用来分配和移除事件处理函数,与IE不同的是,这些方法需要三个参数:事件名称,要分配的函数和处理函数是用于冒泡阶段(false)还是捕获阶段(true),默认为冒泡阶段false [object].addEventListener("name_of_event",fnhander,bcapture) [object].removeEventListener("name_of_event",fnhander,bcapture) var fnClick = function(){ alert("Clicked!"); } oDiv.addEventListener("onclick", fnClick, false); //添加事件处理函数 oDiv.addEventListener("onclick", fnClickAnother, false); // 与IE一样,可以添加多个事件处理函数 oDiv.removeEventListener("onclick", fnClick, false); //移除事件处理函数 如果使用addEventListener()将事件处理函数加入到捕获阶段,则必须在removeEventListener()中指明是捕获阶段,才能正确地将这个事件处理函数删除 oDiv.onclick = fnClick; oDiv.onclick = fnClickAnother; //使用直接赋值,后续的事件处理函数会覆盖前面的处理函数 oDiv.onclick = fnClick; oDiv.addEventListener("onclick", fnClickAnother, false); //会按顺序进行调用,不会覆盖 一张图了解OUTHTML和innerText、innerHTML: DOM基本操作思维导图 更详细的XML DOM - Element 对象的属性和方法请访问w3cshool BOM 部分BOM的核心是window,而window对象又具有双重角色,它既是通过js访问浏览器窗口的一个接口,又是一个Global(全局)对象。这意味着在网页中定义的任何对象,变量和函数,都以window作为其global对象。 123456789101112131415161718192021222324252627window.close(); //关闭窗口 window.alert("message"); //弹出一个具有OK按钮的系统消息框,显示指定的文本 window.confirm("Are you sure?"); //弹出一个具有OK和Cancel按钮的询问对话框,返回一个布尔值 window.prompt("What's your name?", "Default"); //提示用户输入信息,接受两个参数,即要显示给用户的文本和文本框中的默认值,将文本框中的值作为函数值返回 window.status //可以使状态栏的文本暂时改变 window.defaultStatus //默认的状态栏信息,可在用户离开当前页面前一直改变文本 window.setTimeout("alert('xxx')", 1000); //设置在指定的毫秒数后执行指定的代码,接受2个参数,要执行的代码和等待的毫秒数 window.clearTimeout("ID"); //取消还未执行的暂停,将暂停ID传递给它 window.setInterval(function, 1000); //无限次地每隔指定的时间段重复一次指定的代码,参数同setTimeout()一样 window.clearInterval("ID"); //取消时间间隔,将间隔ID传递给它 window.history.go(-1); //访问浏览器窗口的历史,负数为后退,正数为前进 window.history.back(); //同上 window.history.forward(); //同上 window.history.length //可以查看历史中的页面数 document对象1234567891011121314151617181920212223document对象:实际上是window对象的属性,document == window.document为true,是唯一一个既属于BOM又属于DOM的对象 document.lastModified //获取最后一次修改页面的日期的字符串表示 document.referrer //用于跟踪用户从哪里链接过来的 document.title //获取当前页面的标题,可读写 document.URL //获取当前页面的URL,可读写 document.anchors[0]或document.anchors["anchName"] //访问页面中所有的锚 document.forms[0]或document.forms["formName"] //访问页面中所有的表单 document.images[0]或document.images["imgName"] // 访问页面中所有的图像 document.links [0]或document.links["linkName"] //访问页面中所有的链接 document.applets [0]或document.applets["appletName"] //访问页面中所有的Applet document.embeds [0]或document.embeds["embedName"] //访问页面中所有的嵌入式对象 document.write(); 或document.writeln(); //将字符串插入到调用它们的位置 location对象1234567891011121314151617181920212223location对象:表示载入窗口的URL,也可用window.location引用它 location.href //当前载入页面的完整URL,如http://www.somewhere.com/pictures/index.htm location.portocol //URL中使用的协议,即双斜杠之前的部分,如http location.host //服务器的名字,如www.wrox.com location.hostname //通常等于host,有时会省略前面的www location.port //URL声明的请求的端口,默认情况下,大多数URL没有端口信息,如8080 location.pathname //URL中主机名后的部分,如/pictures/index.htm location.search //执行GET请求的URL中的问号后的部分,又称查询字符串,如?param=xxxx location.hash //如果URL包含#,返回该符号之后的内容,如#anchor1 location.assign("http:www.baidu.com"); //同location.href,新地址都会被加到浏览器的历史栈中 location.replace("http:www.baidu.com"); //同assign(),但新地址不会被加到浏览器的历史栈中,不能通过back和forward访问 location.reload(true | false); //重新载入当前页面,为false时从浏览器缓存中重载,为true时从服务器端重载,默认为false navigator对象12345678910111213141516171819 `navigator`对象:包含大量有关Web浏览器的信息,在检测浏览器及操作系统上非常有用,也可用window.navigator引用它 `navigator.appCodeName` //浏览器代码名的字符串表示 navigator.appName //官方浏览器名的字符串表示 navigator.appVersion //浏览器版本信息的字符串表示 navigator.cookieEnabled //如果启用cookie返回true,否则返回false navigator.javaEnabled //如果启用java返回true,否则返回false navigator.platform //浏览器所在计算机平台的字符串表示 navigator.plugins //安装在浏览器中的插件数组 navigator.taintEnabled //如果启用了数据污点返回true,否则返回false navigator.userAgent //用户代理头的字符串表示 screen对象1234567891011screen对象:用于获取某些关于用户屏幕的信息,也可用window.screen引用它 screen.width/height //屏幕的宽度与高度,以像素计 screen.availWidth/availHeight //窗口可以使用的屏幕的宽度和高度,以像素计 screen.colorDepth //用户表示颜色的位数,大多数系统采用32位 window.moveTo(0, 0); window.resizeTo(screen.availWidth, screen.availHeight); //填充用户的屏幕 window对象方法 BOM和DOM的结构关系示意图 window对象思维导图","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Javascript基础总结二(对象+数组)","date":"2016-03-06T12:05:01.000Z","path":"2016/03/06/Javascript基础总结二(对象+数组)/","text":"对象部分Object类型Object 是一个无序的集合,可以存放任意类型对象,所有其他对象都继承自这个对象。创建Object类型有两种,一种是使用new运算符,一种是字面量表示法。 1.使用new运算符创建Object 1var obj = new Object();//注意大写,也可以直接写成Object() 注意,通过new Object() 的写法生成新对象,与字面量的写法 obj = {} 是等价的。 2. 使用字面量方式创建: 1234var obj = { name : 'trigkit4', age : 21};//分号最好加上 在使用字面量声明Object对象时,不会调用Object()构造函数(FF除外) Object.prototype对象所有构造函数都有一个prototype属性,指向一个原型对象。 12345Object.prototype.print = function(){ console.log(this)};var obj = new Object();obj.print() // Object 实例obj直接继承了Object.prototype的属性和方法 12345671.对象只是一种特殊的数据。对象拥有属性和方法。 JavaScript 是面向对象的语言,但 JavaScript 不使用类。 JavaScript 基于 [prototype][1],而不是基于类的。2.属性:是隶属于某个特定对象的变量。方法:是只有某个特定对象才能调用的函数。3.js对象是属性和方法的集合。一个方法就是一个函数,是对象的成员。属性是一个值或一组值(以数组或对象的形式),是对象的成员。4.js对象是基于构造器函数的,使用构造器函数创建一个新对象时,就可以说是实例化了一个新对象。属性是构造器函数内部的变量。 使用构造器函数实例化的对象: 1cat = new Animal(); Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类)。 1234567<script type="text/javascript"> //对象是名/值对的集合 var browser = { //对象是由花括号括起来的 name:"Firefox", kernel:"Gecko" };</script> 123//通过点号(.)或“[]”来访问对象的属性 browser.name //"Firefox" browser["kernel"] //"Gecko" 对象(objct)是属性(property)的集合,每个属性都由“名/值对”构成,js同样定义了一个特殊的对象——数组,它是带有编号的值的有序集合。 js还定义了一个特殊的对象——函数,函数是具有与他相关联的可执行代码的对象,通过调用函数来执行代码,并返回运算结果。 JS中没有[类]3,但是它取了一个新的名字叫“原型对象”,因此”类==原型对象”,详情见:JavaScript类的写法(一) 二:类(原型对象)和对象(实例)的区别与联系1231.类(原型对象)是抽象,是概念的,代表一类事物。2.对象是具体的,实际的,代表一个具体的事物。3.类(原型对象)是对象实例的模板,对象实例是类的一个个体。 一个常见的误解是数字的字面值(literal)不是对象。这是因为 JavaScript 解析器的一个错误,它试图将点操作符解析为浮点数字面值的一部分。 有很多变通方法可以让数字的字面值看起来像对象。 1232..toString(); // 第二个点号可以正常解析2 .toString(); // 注意点号前面的空格(2).toString(); // 2先被计算 删除属性删除属性的唯一方法是使用 delete 操作符;设置属性为 undefined 或者 null 并不能真正的删除属性,而仅仅是移除了属性和值的关联。 JavaScript面向对象三大特征123封装:不考虑内部实现,只考虑功能使用继承:从已有对象上,继承出新的对象多态:所谓多态,就是指一个引用在不同情况下的多种状态, 1.封装封装就是要把属于同一类事物的共性(包括属性与行为)归到一个类中,以方便使用.比如人这个东东,可用下面的方式封装: 人{ 1234567年龄(属性一)身高(属性二)性别(属性三)做事(行为之一)走路(行为之二)说话(行为之三) } 封装的好处: 1234封装保护了内部数据的完整性;封装使对象的重构更轻松;弱化模块间的耦合,提高对象的可重用性;有助于避免命名空间冲突; 看下面一个例子: 123456789<script type="text/javascript"> var boy = {}; //创建一个空对象 boy.name = "小明";//按照原型对象的属性赋值 boy.age = 12; var girl = {}; girl.name = "小红"; girl.age = 10; </script> 这就是最简单的封装了,把两个属性封装在一个对象里面。但是,这样的写法有两个缺点,一是如果多生成几个实例,写起来就非常麻烦;二是实例与原型之间,没有任何办法,可以看出有什么联系。 构造函数模式为了解决从原型对象生成实例的问题,Javascript提供了一个构造函数(Constructor)模式。 所谓”构造函数“,其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。 比如boy和girl的原型对象现在就可以这样写: 123456<script type="text/javascript"> function Person(name,age){ this.name = name; this.age = age; }</script> 我们现在就可以生成实例对象了。 1234567<script type="text/javascript"> var boy = new Person("小明",12); var girl = new Person("小红",10); alert(boy.name); //小明 alert(boy.age); //12</script> 这时boy和girl会自动含有一个constructor属性,指向它们的构造函数。 123alert(boy.constructor == Person); //truealert(girl.constructor); //输出整串构造函数代码,自己试试吧 Prototype模式 Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。 这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。 123456789101112<script type="text/javascript">function Person(name,age){ this.name = name; this.age = age;}Person.protype.type = "人类";Person.protype.eat = function(){ alert("吃米饭");}</script> 然后,生成实例: 1234567<script type="text/javascript">var boy = new Person("小明","12");var girl = new Person("小红","10");alert(boy.type);//人类boy.eat();//吃饭</script> 这时所有实例的type属性和eat()方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。 1alert(boy.eat == girl.eat); //true 原型属性是一个内置属性,它指定了对象所扩展的构造器函数。下面的代码为Animal构造器函数添加一个新的属性size,这个新属性是cat对象的原型属性。通过使用原型属性,所有扩展Animal构造器函数的对象就可以访问size属性 12cat = new Animal("feline","meow", "walk/run");cat.prototype.size = "fat"; 在这种情况下,所有的Animal对象的size属性都是“fat”。原型默认为Object的新实例, 由于仍是对象, 故可以给该对象添加新的属性。就好像style是javascript的一个对象一样,也可以往style后继续添加属性。 123456789101112131415 <script type="text/javascript"> /*定义一个Person类*/ function Person(_name,_age,_salary){ //Person类的公开属性,类的公开属性的定义方式是:”this.属性名“ this.Name=_name; //Person类的私有属性,类的私有属性的定义方式是:”var 属性名“ var Age=_age; var Salary=_salary; //定义Person类的公开方法(特权方法),类的公开方法的定义方式是:”this.functionName=function(){.....}“ this.Show=function(){ alert("Age="+Age+"\\t"+"Salary="+Salary);//在公开方法里面访问类的私有属性是允许的 }</script> 对象在查找某个属性的时候,会首先遍历自身的属性,如果没有则会继续查找[[Prototype]]引用的对象,如果再没有则继续查找[[Prototype]].[[Prototype]]引用的对象,依次类推,直到[[Prototype]].….[[Prototype]]为undefined(Object的[[Prototype]]就是undefined) 简单说就是通过对象的[[Prototype]]保存对另一个对象的引用,通过这个引用往上进行属性的查找,这就是原型链。 null 对象js给变量赋null值的作用在于:赋值一个空指针,容易让人理解这个变量是准备用来存放对象的。也方便调错 全局的window对象JavaScript中的任何一个全局函数或变量都是window的属性。self对象与window对象完全相同,self通常用于确认就是在当前的窗体内。 window的主对象主要有如下几个: 123456JavaScript document 对象JavaScript frames 对象JavaScript history 对象JavaScript location 对象JavaScript navigator 对象JavaScript screen 对象 几个常用方法123456789valueof()方法:返回指定对象的原始值split() 方法将字符串分割为字符串数组,并返回此数组。indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。 substring() 方法用于提取字符串中介于两个指定下标之间的字符。substr() 方法从字符串中提取从 startPos位置开始的指定数目的字符串。 join()方法用于把数组中的所有元素放入一个字符串。arrayObject.join(分隔符)reverse() 方法用于颠倒数组中元素的顺序。 slice() 方法可从已有的数组中返回选定的元素。 对象字面量对象字面量是用于创建包含大量属性的过程,如下所示: 12345678<script type="text/javascript"> var company = { name : "Microsoft", ages : 39, employees : 99000, CEO : "Nadella" }; </script> 这里需要注意的是属性和属性值以冒号(:)隔开;多个属性用逗号(,)隔开。对象字面量亦可以定义方法,只需在这个对象的属性上写上function就行,这是一个匿名函数,调用它只需要写上他的方法名()即可。 12345678910<script type="text/javascript">var dog = { name:"husky", age:2, run:function(){ return "123";}}alert(dog.run());//如果输入dog.run,那么会弹出它后面的function部分的代码</script> 基本值类型包装器js有五种基本的值类型:number、string、Boolean、null和undefined。除了null和undefined外,其他三个都具有所谓的基本包装对象。可以使用内置构造函数Number()、String()和Boolean()创建包装对象。 12var num = new Number(10);console.log(typeof num);//object Object()方法1234567891011Object() // 返回一个空对象Object(undefined) // 返回一个空对象Object(null) // 返回一个空对象Object(1) // 等同于 new Number(1)Object('foo') // 等同于 new String('foo')Object(true) // 等同于 new Boolean(true)Object([]) // 返回原数组Object({}) // 返回原对象Object(function(){}) // 返回原函数 数组部分1.Array 对象Array 对象:提供对创建任何数据类型的数组的支持。 123arrayObj = new Array()arrayObj = new Array([size])arrayObj = new Array([element0[, element1[, ...[, elementN]]]]) 定义:var arr = [2,3,45,6]; var arr = new Array(2,4,5,7)两者是定义没有任何差别,[]的性能高,因为代码短。 使用数组和对象字面量:var aTest = [];创建数组时,使用数组字面量是个好选择;类似的,对象字面量也可用于节省空间。以下两行是相等的,但是使用对象字面量的更加简短: 12var oTest = new Object; //尽量不用var oTest = { }; //最好的选择,或者var 0Test = [ ]; 遍历为了达到遍历数组的最佳性能,推荐使用经典的 for 循环。 1234var list = [1, 2, 3, 4, 5, ...... 100000000];for(var i = 0, l = list.length; i < l; i++) { console.log(list[i]);} 上面代码有一个处理,就是通过 l = list.length 来缓存数组的长度。 Array 构造函数由于 Array 的构造函数在如何处理参数时有点模棱两可,因此总是推荐使用数组的字面语法 - [] - 来创建数组。 因此下面的代码将会使人很迷惑: 12new Array(3, 4, 5); // 结果: [3, 4, 5] new Array(3) // 结果: [],此数组长度为 3 应该尽量避免使用数组构造函数创建新数组。推荐使用数组的字面语法。它们更加短小和简洁,因此增加了代码的可读性。 Array数组的属性Array数组的3个属性:length属性、prototype属性、constructor属性 1.length属性Length属性表示数组的长度,即其中元素的个数。因为数组的索引总是由0开始,所以一个数组的上下限分别是:0和length-1。和其他大多数语言不同的是,JavaScript数组的length属性是可变的,这一点需要特别注意。 2.prototype属性返回对象类型原型的引用。prototype属性是object共有的。 对于Array数组对象,以以下例子说明prototype属性的用途。给数组对象添加返回数组中最大元素值的方法。要完成这一点,声明一个函数,将它加入Array.prototype,并使用它。 1234567891011121314function array_max() { var i,max=this[0]; for(i=1;i<this.length;i++) { if(max<this[i]) max=this[i]; } return max; } Array.prototype.max=array_max; var x=new Array(1,2,3,4,5,6); var y=x.max(); 该代码执行后,y保存数组x中的最大值,或说6。 3.constructor属性表示创建对象的函数。说明:constructor属性是所有具有prototype的对象的成员。它们包括除Global和Math对象以外的所有JScript固有对象。constructor属性保存了对构造特定对象实例的函数的引用。 例如: 123456789x = new String("Hi"); if(x.constructor==String) //进行处理(条件为真)。 //或 function MyFunc{ //函数体。 } y=new MyFunc; if(y.constructor==MyFunc)//进行处理(条件为真)。 对于数组来说: 1y = new Array(); Array 对象方法 方法 描述 concat() 连接两个或更多的数组,并返回结果。 join() 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。 pop() 删除并返回数组的最后一个元素 push() 向数组的末尾添加一个或更多元素,并返回新的长度。 reverse() 颠倒数组中元素的顺序。 shift() 删除并返回数组的第一个元素 slice() 从某个已有的数组返回选定的元素 sort() 对数组的元素进行排序 splice() 删除元素,并向数组添加新元素。 toSource() 返回该对象的源代码。 toString() 把数组转换为字符串,并返回结果。 toLocaleString() 把数组转换为本地数组,并返回结果。 unshift() 向数组的开头添加一个或更多元素,并返回新的长度。 valueOf() 返回数组对象的原始值 sort()方法语法 1arrayObject.sort(sortby) sortby可选。规定排序顺序。必须是函数。 12var arr = [11,2,28,4,5,1];console.log(arr.sort());//return [1, 11, 2, 28, 4, 5] 为毛这里的11、28没有按照顺序来排列呢?这是因为不带参数的sort是按照字符编码的顺序进行排序的。那么,如果要让数组元素按照从小到大排序呢?看下面代码: 1234var arr = [11,2,28,4,5,1]; console.log(arr.sort(function(a,b){ return a-b;//return [1, 2, 4, 5, 11, 28] })); 如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下: 123若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。若 a 等于 b,则返回 0。若 a 大于 b,则返回一个大于 0 的值。 附上一张数组的思维导图:","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]},{"title":"Javascript基础总结一(基本概念)","date":"2016-03-02T12:05:01.000Z","path":"2016/03/02/Javascript基础总结一(基本概念)/","text":"##基本概念javascript是一门解释型的语言,浏览器充当解释器。js执行时,在同一个作用域内是先解释再执行。解释的时候会编译function和var这两个关键词定义的变量,编译完成后从上往下执行并向变量赋值。 ###区分大小写ECMASCript中的一切(包括变量,函数名和操作符)都区分大小写。 ##1.变量变量在第一次用到时就设置于内存中,便于后来在脚本中引用。使用变量之前先进行声明。可以使用 var 关键字来进行变量声明。1var count, amount, level; // 用单个 var 关键字声明的多个声明。 ###变量命名变量名包括全局变量,局部变量,类变量,函数参数等等,他们都属于这一类。 变量命名都以类型前缀+有意义的单词组成,用驼峰式命名法增加变量和函式的可读性。例如:sUserName,nCount。 前缀规范:每个局部变量都需要有一个类型前缀,按照类型可以分为: 123456789> s:表示字符串。例如:sName,sHtml;> n:表示数字。例如:nPage,nTotal;> b:表示逻辑。例如:bChecked,bHasLogin;> a:表示数组。例如:aList,aGroup;> r:表示正则表达式。例如:rDomain,rEmail;> f:表示函数。例如:fGetHtml,fInit;> o:表示以上未涉及到的其他对象,例如:oButton,oDate;> g:表示全局变量,例如:gUserName,gLoginTime;> JScript 是一种区分大小写的语言。创建合法的变量名称应遵循如下规则: 1.注意第一个字符不能是数字。 2.后面可以跟任意字母或数字以及下划线,但不能是空格变量名称一定不能是 保留字。 javascript是一种弱类型语言,JavaScript 会忽略多余的空格。您可以向脚本添加空格,来提高其可读性。 var是javascript的保留字,表明接下来是变量说明,变量名是用户自定义的标识符,变量之间用逗号分开。 如果声明了一个变量但没有对其赋值,该变量存在,其值为Jscript 值 undefined。 ###强制类型转换在 Jscript 中,可以对不同类型的值执行运算,不必担心 JScript 解释器产生异常。相反,JScript 解释器自动将数据类型之一改变(强制转换)为另一种数据类型,然后执行运算。例如: 运算 结果 数值与字符串相加 将数值强制转换为字符串。布尔值与字符串相加 将布尔值强制转换为字符串。数值与布尔值相加 将布尔值强制转换为数值。 要想显式地将字符串转换为整数,使用 parseInt 方法。要想显式地将字符串转换为数字,使用 parseFloat 方法。 JavaScript 变量的生存期:当您在函数内声明了一个变量后,就只能在该函数中访问该变量。当退出该函数后,这个变量会被撤销。这种变量称为本地变量。您可以在不同的函数中使用名称相同的本地变量,这是因为只有声明过变量的函数能够识别其中的每个变量。如果您在函数之外声明了一个变量,则页面上的所有函数都可以访问该变量。这些变量的生存期从声明它们之后开始,在页面关闭时结束。 ###js变量思维导图 ##2.js的数据类型jscript 有三种->主要数据类型、两种->复合数据类型和两种->特殊数据类型。 主要(基本)数据类型:字符串、数值、布尔 复合(引用)数据类型:对象、数组 特殊数据类型: null 、undefined 字符串数据类型:字符串数据类型用来表示 JScript 中的文本。在js中,虽然双引号(””)和单引号(‘’)均可表示字符串,而且它们几乎没有任何区别。但只使用双引号(“”)来表示字符串被认为是最佳的。一个字符串值是排在一起的一串零或零以上的 Unicode 字符(字母、数字和标点符号)。 ###什么是Unicode?Unicode为每个字符都提供了唯一的数值,不管是什么平台、什么程序或什么语言。开发unicode是为了给处理世界上存在的所有字符提供统一的编码。 ###数值数据类型我们需要明白一点,JScript 内部将所有的数值表示为浮点值,因此,在 Jscript 中整数和浮点值没有差别。 ###Boolean数据类型布尔(逻辑)只能有两个值:true 或 false。 ###引用数据类型 javascript引用数据类型是保存在堆内存中的对象,JavaScript不允许直接访问堆内存空间中的位置和操作堆内存空间,只能通过操作对象在栈内存中的引用地址。所以引用类型的数据,在栈内存中保存的实际上是对象在堆内存中的引用地址。通过这个引用地址可以快速查找到保存在堆内存中的对象。下面我们来演示这个引用数据类型赋值过程: 基本类型值指的是那些保存在栈内存中的简单数据段,即这种值完全保存在内存中的一个位置。而引用类型值则是指那些保存在堆内存中的对象,即变量中保存的实际上只是一个指针,这个指针指向内存中的另一个位置,该位置保存对象。简而言之,堆内存存放引用值,栈内存存放固定类型值。 在 ECMAScript 中,变量可以存在两种类型的值,即原始值和引用值。原始值存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。引用值存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。 123456<script type="text/javascript”>var box = new Object(); //创建一个引用类型var box = "lee"; //基本类型值是字符串box.age = 23; //基本类型值添加属性很怪异,因为只有对象才可以添加属性。alert(box.age); //不是引用类型,无法输出;</script> 3.JScript 的运算符优先级:指运算符的运算顺序,通俗的说就是先计算哪一部分。结合性:同一优先级运算符的计算顺序,通俗的说就是从哪个方向算起,是左到右还是右到左。 数据类型转换和基本包装类型String() 转换为字符串类型Number() 转换为数字类型Boolean() 转换为布尔类型 parseInt:将字符串转换为整数。从字符串的开头开始解析,在第一个非整数的位置停止解析,并返回前面读到所有的整数。如果字符串不是以整数开头的,将返回NaN。如:parseInt(“150 hi”)返回的值是:150,parseInt(“hi”)返回的值是:NaN。parseFloat:将字符串转换为浮点数。 从字符串的开头开始解析,在第一个非整数的位置停止解析,并返回前面读到所有的整数。如果字符串不是以整数开头的,将返回NaN。如:parseFloat("15.5 hi") 返回的值是:15.5,parseFloat("hi 15.5")返回的值是:NaN。 1eval:将字符串作为javascript表达式进行计算,并返回执行结果,如果没有结果则返回undefined。 基本包装类型每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而能调用一些方法来操作这些数据。基本包装类型包括Boolean、Number和String 123456789101112var box = 'trigkit4'; //字面量box.name = 'mike'; //无效属性box.age = function () { //无效方法 return 22;}; //new运算符写法var box = new String('trigkit4');//new 运算符box.name = 'mike'; //有效属性box.age = function () { //有效方法 return 22;}; String类型包含了三个属性和大量的可用内置方法 1234属性 描述length :返回字符串的字符长度Constructor : 返回创建String对象的函数prototype : 通过添加属性和方法扩展字符串定义 4.js流程控制对于js流程控制语句,这里只讲几个比较难懂的。其他不赘述。等下附上一张思维导图。1.for…in 语句对应于一个对象的每个,或一个数组的每个元素,执行一个或多个语句。 12for (variable in [object | array])statements 参数: variable:必选项。一个变量,它可以是 object 的任一属性或 array 的任一元素。object, array:可选项。要在其上遍历的对象或数组。statement:可选项。相对于 object 的每个属性或 array 的每个元素,都要被执行的一个或多个语句。可以是复合语句。 虽然条件控制语句(如if语句)只在执行多条语句的情况下才要求使用代码块(左花括号”{“开头,右花括号”}”结尾),但最佳实践是始终使用代码块。 123456if(args) alert(args);//容易出错 if(args){ alert(args);//推荐使用} js流程控制语句思维导图 5.js函数函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。 Jscript 支持两种函数:一类是语言内部的函数,另一类是自己创建的。JavaScript 函数允许没有参数(但包含参数的小括号不能省略),也可以向函数传递参数供函数使用。 更多关于函数的知识请访问我的另一篇文章:javascript学习大总结(四)function函数部分 对象的组成12方法——函数:过程、动态的属性——变量:状态、静态的 最后,再附上一张前辈总结的思维导图:","comments":true,"tags":[{"name":"技术","slug":"技术","permalink":"https://guohui8.github.io/tags/技术/"}]}]