学习札记
一.JS正则test()方法
每个正则表达式都有一个 lastIndex 属性,用于记录上一次匹配结束的位置,包括exec方法。
var re = /^[1-9]d{4,10}$/gi; var str = "123456"; alert(re.test(str)); //返回true str = "1234567"; alert(re.test(str)); //返回false
解决方法:
var re = /^[1-9]d{4,10}$/gi; var str = "123456"; alert(re.test(str)); //返回true
// 执行上面的 test 之后 可以弹出
alert(re.lastIndex); // 弹出6
即表示上一次在第6个字符之后结束.那么下一次再调用 test 的时候, 就会从第6个字符之后继续搜索.解决办法,将正则表达式的 lastIndex 属性设置为0 .具体代码如下:
var re = /^[1-9]d{4,10}$/gi; var str = "123456"; alert(re.test(str)); //返回true str = "1234567"; re.lastIndex=0; alert(re.test(str)); //返回true
或:正则模式去掉全局模式。把g去掉就行了,g就是继续往下的意思,不是必要别加g.改成:
var re = /^[1-9]d{4,10}$/i; var str = "123456"; alert(re.test(str)); //返回true str = "1234567"; alert(re.test(str)); //返回true
二.获取图片的大小
var img = new Image(); img.src = 'https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png'; img.onload = function(){ alert(this.width + '*' + this.height); }
三.使用border-box
box-sizing: border-box; 这里的宽度就是元素所占总宽度。使用时最好带上浏览器前缀,ie8以上。
四.onload与ready
load是一个事件,会在页面包含文件资源加载完成后触发。支持该事件的HTML标签:body、frame、frameset、iframe、img、link、script。
那么 document ready到底是什么ready了? 按资料说明,这个事件指的是文档结构(DOM)加载完成触发的。 jq(document).ready(function(jq) { //todo }
五.regular性能优化指引
Regular使用了被诟病无数次的脏检查机制,但是它提供了非常多的方案来帮助我们解决性能问题,这个章节将会不断更新。
请尽量使用一次绑定
' '
使用list的track by功能
使用isolate
使用if else代替 display:none
使用throttle或until(tid = setTimeout)的方式来避免频繁更新
六.ng-bind与ng-model
ng-bind是相当于{{object.xxx}},是用于展示数据的。 而ng-model是控制数据的。 AngularJS 表达式写在双大括号内:{{ expression }}。 AngularJS 表达式把数据绑定到 HTML,这与 ng-bind 指令有异曲同工之妙。
七.加时间戳防止缓存
八.画三角形
九.解析Js的面向对象代码片段
以下是prototype.js的一块代码片段
var Class = { create: function() { return function() { this.initialize.apply(this , arguments); } } }
Class使用方法如下
var A = Class.create(); A. prototype={ initialize:function(v){ this .value=v; } showValue:function(){ alert(this.value); } } var a = new A(‘helloWord!'); a. showValue();//弹出对话框helloWord!
1.initialize是什么?
initialize是个变量,代表一个方法,用途是类的构造函数。
JS中的所有function都是一样的,但是用途可能是不同的,有的用作构造对象抑,有的是执行一个过程。
var Class = { create: function() { return function() { this.initialize.apply(this , arguments); } } } var A = Class.create();
这段代码是构造个一个function复制给A,这个function是:
function() { this.initialize.apply(this , arguments); }
并且后面这个方法是用来做构造函数的。当使用这个构造函数来构造对象的时候,会让构造出来的这个对象的initialize变量执行apply()方法。这样在初始化对象的时候会联系到initialize。
A.prototype={ initialize:function(v){ this .value=v; } showValue:function(){ alert(this.value); } }
Prototype是“原型”的意思。A是一个function(),那么A. prototype,就是function中的一个变量,其实是个对象。这个对象拥有什么方法,那么function产生的对象就拥有什么方法,故
var a = new A(‘helloWord!'); a. showValue();//弹出对话框helloWord!
所以a对象也会有initialize方法,不只如此,每一个有A构造出来的对象都会有一个initialize方法,而在前面说过,构造的时候会调用构造函数,构造函数里面会让initialize去调用apply方法,于是在new A(‘helloWord!')的时候initialize回去调用apply方法。这也就是调用了一个初始化的方法。
2.apply方法是干什么的?
功能基本一样,function().call(object,{},{}……)或者function().apply (object,[……])的功能就是对象object调用这里的funciton(),不同之处是call参数从第二个开始都是传递给funciton的,可以依次罗列用“,”隔开。而apply只有两个参数,第二个是一个数组,其中存储了所有传递给function的参数。
this.initialize.apply(this , arguments);
这里的第一个this,是指用new调用构造函数之后生成的对象,也就是前面的a,那么第二个this也当然应该是指同一个对象。那这句话就是this(也就是a)调用initialize方法,参数是arguments对象(参数的数组对象),所以在构造函数执行的时候,对象a就会去执行initialize方法来初始化,这样就和单词“initialize”的意思对上了。 那么执行initialize方法的参数怎么传递进去的呢?
3.arguments变量呢?
Arguments对象
function test(){ alert(typeof arguments); for(var i=0; i
执行后alert(typeof arguments);会显示object,说明arguments是对象。然后会依次打出1、2、3。说明arguments就是调用函数的实参数组。
var Class = { create: function() { return function() { this.initialize.apply(this , arguments); } } }
arguments 就是create返回的构造函数的实参数组,那么在
var a = new A(‘helloWord!');
的时候‘helloWord!'就是实参数组(虽然只有一个字符串),传递给方法apply,然后在调用initialize 的时候作为参数传递给初始化函数initialize。
十.高性能Javascript知识
1.数据存储
在JavaScript中,数据存储的位置会对代码性能产生重大影响。
– 能使用{}创建对象就不要使用new Object,能使用[]创建数组就不要使用new Array。JS中字面量的访问速度要高于对象。
– 变量在作用域链中的位置越深,访问所需实践越长。对于这种变量,可以通过缓存使用局部变量保存起来,减少对作用域链访问次数。
– 使用点表示法(object.name)和操作符(object[name])操作并没有太多区别,只有Safari会有区别,点始终更快。
2.循环
在JS中常见的循环有下面几种:
for(var i = 0,len=arr.length ; i < len; i++) { // do something} for(var prop in object) { // for loop object} [1,2].forEach(function(value, index, array) { // 基于函数的循环})
毋庸质疑,第一种方式是原生的,性能消耗最低的,速度也最快,注意把数组的长度用len缓存下来。第二种方式for-in每次迭代都回产生更多的开销(局部变量),它的速度只有第一种 的1/7 第三种方式明显提供了更便利的循环方式,但是他的速度只有普通循环的1/8。所以可以根据自己项目情况,选择合适的循环方式。
3.事件委托
当页面中存在大量元素都需要绑定同一个事件处理的时候,这种情况可能会影响性能。每绑定一个事件都加重了页面或者是运行期间的负担。对于一个富前端的应 用,交互重的页面上,过多的绑定会占用过多内存。 一个简单优雅的方式就是事件委托。它是基于事件的工作流:逐层捕获,到达目标,逐层冒泡。既然事件存在冒泡机制,那么我们可以通过给外层绑定事件,来处理 所有的子元素出发的事件。
document.getElementById('content').onclick = function(e) { e = e || window.event; var target = e.target || e.srcElement; //如果不是 A标签,我就退出 if(target.nodeNmae !=== 'A') { return } //打印A的链接地址 console.log(target.href) }
4.重绘与重排
浏览器下载完HTMl,CSS,JS后会生成两棵树:DOM树和渲染树。 当Dom的几何属性发生变化时,比如Dom的宽高,或者颜色,position,浏览器需要重新计算元素的几何属性,并且重新构建渲染树,这个过程称之为重绘重排。
bodystyle = document.body.style; bodystyle.color = red; bodystyle.height = 1000px; bodystyke.width = 100%;
上述方式修改三个属性,浏览器会进行三次重排重绘,在某些情况下,减少这种重排可以提高浏览器渲染性能。 推荐方式如下,只进行一次操作,完成三个步骤:
bodystyle = document.body.style; bodystyle.cssText 'color:red;height:1000px;100%';
十一.null是什么数据类型,在内存中如何存储的?
栈:原始数据类型(Undefined,Null,Boolean,Number、String)堆:引用数据类型(对象、数组和函数)
两种类型的区别是:存储位置不同;原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体
当我们为一个引用变量初始化=null例如:
String str=null;
JVM会让这个引用变量指向一个不确定类型的空对象内存(即null内存,),null表示不确定类型的静态内存区域(假定虚拟机为程序分配了个永久固定的null静态内存),并且,假如这时候你输出system.out.println(str);相当于输出了null,而null是一个固定的不确定类型的内存,即可以看做是什么类型也不是,也没有继承Object,当然没有toString()方法,所以这句代码不会默认调用str的toString()方法,所以会报错NullPointerException(空指针异常)。
这时候str其实是指向一个内存的(null),当我们再次为str初始化(new一个新对象时),就是让str由指向null变成指向了new出来的新对象,这时候str才是真正的被初始化。
我们有可能会发现了有很多时候如果我们不为某些引用类型变量初始化null,后面再为其new 对象时会报错的(未初始化该类型),为什么呢??
比如输入以下代码:
Connection conn; String catalog = conn.getCatalog();
系统会提示conn未初始化,当我们改成:
Connection conn=null; String catalog = conn.getCatalog();
这时,系统编译会通过。但运行时又会报错空指针异常
这就是因为Connection conn;只是声明了一个变量,告诉虚拟机我过会有可能要用这个变量,但内存中并不存在这个变量,不能执行conn.getCatalog();,因此编译不会通过。
当我们为conn初始化null,虚拟机检测到conn指向一个内存,即null,因此编译会通过。
但是注意:当你让一个非null的引用类型变量长期指向null。这样这个对象不再被任何对象应用,JVM垃圾回收机制去会去回收它。
var s = "string"; var s2 = new String("string"); console.log(typeof(s)); //输出的是 string console.log(typeof(s2)); //输出的 object s.substring(s.indexOf(" ")+1,s.length);
通过new,它返回一个新创建的 String 对象,存放的是字符串 s2 或 s2 的字符串表示
当不用 new 时,它只把 s 转换成原始的字符串,并返回转换后的值。
字符串既然不是对象,为什么它会有属性?只要应用了字符串s的属性,js就会将字符串值通过new String(s)的方式转换成对象,这个对象继承了字符串的方法,并被用来处理属性的引用。一旦引用结束,这个新创建的对象就会被销毁。同字符串一样,数字和布尔值也具有各自的方法。
存取字符串、数字或布尔值的属性时创建的临时对象称作包装对象,它只是偶尔用来区分字符串值和字符串对象、数字和数值对象以及布尔值和布尔对象。
“==”等于运算符将原始值和其包装对象视为相等,但“===”全等运算符将它们视为不等。
十二.app数据缓存问题的解决
问题描述:
当循环根据参数获取数据,对数据进行显示到不同的结点中(如将数据拼接成字符串模版),当跳出本页面,按返回后各个结点的显示都是第一条的数据。
原因:
app有缓存机制,当不同数据拥有相同的变量名时,有一些app只会缓存第一条数据,把后面的当成缓存,所以会造成所有结点显示同样的数据问题。
解决:
把循环请求回来的数据赋给不同的变量,app不会认为是缓存数据。代码如下:
renderHtml = function (data, index) { var courseInfo = {}; courseInfo[index] = data; courseInfo[index].forEach(function (courseObj, index2) { //todo } }
十三.HTTP中GET与POST的区别
常见的区别:
GET在浏览器回退时是无害的,而POST会再次提交请求。
GET产生的URL地址可以被Bookmark,而POST不可以。
GET请求会被浏览器主动cache,而POST不会,除非手动设置。
GET请求只能进行url编码,而POST支持多种编码方式。
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
GET请求在URL中传送的参数是有长度限制的,而POST么有。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
GET参数通过URL传递,POST放在Request body中。
本质区别:
GET和POST是什么?HTTP协议中的两种发送请求的方法。HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议。
HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。
在万维网世界中,TCP就像汽车,我们用TCP来运输数据,它很可靠,从来不会发生丢件少件的现象。但是如果路上跑的全是看起来一模一样的汽车,那这个世界看起来是一团混乱,送急件的汽车可能被前面满载货物的汽车拦堵在路上,整个交通系统一定会瘫痪。为了避免这种情况发生,交通规则HTTP诞生了。HTTP给汽车运输设定了好几个服务类别,有GET, POST, PUT, DELETE等等,HTTP规定,当执行GET请求的时候,要给汽车贴上GET的标签(设置method为GET),而且要求把传送的数据放在车顶上(url中)以方便记录。如果是POST请求,就要在车上贴上POST的标签,并把货物放在车厢里。当然,你也可以在GET的时候往车厢内偷偷藏点货物,但是这是很不光彩;也可以在POST的时候在车顶上也放一些数据,让人觉得傻乎乎的。HTTP只是个行为准则,而TCP才是GET和POST怎么实现的基本。
但是,我们只看到HTTP对GET和POST参数的传送渠道(url还是requrest body)提出了要求。关于参数大小的限制又是从哪来的呢?
在万维网世界中,还有另一个重要的角色:运输公司。不同的浏览器(发起http请求)和服务器(接受http请求)就是不同的运输公司。 虽然理论上,你可以在车顶上无限的堆货物(url中无限加参数)。但是运输公司可不傻,装货和卸货也是有很大成本的,他们会限制单次运输量来控制风险,数据量太大对浏览器和服务器都是很大负担。业界不成文的规定是,(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。超过的部分,恕不处理。如果你用GET服务,在request body偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略,所以,虽然GET可以带request body,也不能保证一定能被接收到哦。
好了,现在你知道,GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
GET和POST还有一个重大区别:
GET产生一个TCP数据包;POST产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。
十四.自定义浏览器滚动条的样式
自定义IE浏览器滚动条样式
经过不断的测试发现,以下是Win 8下面的滚动条样式,并写出了和CSS支持的情况:
以上所写的几个四个CSS属性,足以控制Win 8系统下,IE浏览器的滚动条样式了。但经过测试,发现,其它的四个属性仍然支持(主要是在以上几个属性空缺时,就会体现其作用)。具体如下:
1).关于scrollbar-track-color,scrollbar-face-color与scrollbar-base-color。scroll-base-color是一个备用颜色,只要前两者未设置时,它就开始起作用了。但是你得注意,当scrollbar-base-color用来作scrollbar-track-color功能来用时,你会发现,实际颜色与设定的颜色要淡一点。不信你可以这样试试:只设置一下scrollbar-base-color看看滚动条的效果。
2)关于scrollbar-dark-shadow-color属性,通过测试发现Win 8下IE10,IE11滚动条并没有改变。可能是win 8的滚动条重新定义了,导致没有了隐影了.
3)通过观察发现,Win 8下的滚动条中,上箭头和下箭头后面的背景颜色都已经从scroll-face-color中脱离出来了,从属于scroll-track-color属性控制。
IE浏览器滚动条自定制功能并不是很强,只能控制一样显示各个部分的颜色,宽度,结构等都无法控制.
webkit内核的浏览器滚动条定制
在所有浏览器,滚动条可定制性最强的当属webkit内核的浏览器了。例如有:Google Chrome、Opera、360极速浏览器,猎豹浏览器等,搜狗浏览器······
CSS ::-webkit-scrollbar 滚动条整体部分,其中的属性有width,height,background,border(就和一个块级元素一样)等。 ::-webkit-scrollbar-button 滚动条两端的按钮。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果。 ::-webkit-scrollbar-track 外层轨道。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果。 ::-webkit-scrollbar-track-piece 内层轨道,滚动条中间部分(除去)。 ::-webkit-scrollbar-thumb 滚动条里面可以拖动的那部分 ::-webkit-scrollbar-corner 边角 ::-webkit-resizer 定义右下角拖动块的样式
以上CSS代码所管辖的区域对就关系:以上注释中的数字与下图中数字相对应。
注意:对以上各个部分定义width,height时。有如下功能:若是水平滚动条,则width属性不起作用,height属性用来控制滚动条相应部分竖直方向高度;若是竖直滚动条,则height属性不起作用,width属性用来控制相应部分的宽度。
能过上面的不断的测试。在Chrome中,滚动条中的各个部分和DOM中块级元素是一样的。通过::-webkit-scrollbar等就类似于原来所说的CSS中的选择器。而{}中的属性,你就像控制一般块级元素一样简单。
十五.中文网页字体的最佳选择
body {font-family: Helvetica, Tahoma, Arial, "Microsoft YaHei", "Hiragino Sans GB", "WenQuanYi Micro Hei", sans-serif;}
1)记住这个事实:绝大部分中文字体里包含西文字母,但是基本上都很丑,而西文字体里不包含中文字符。在网页里中英混排是很常见的,你绝对不会喜欢用中文字体显示西文的效果,所以一定不要忘了先声明西文字体,并且西文字体应该在中文字体之前。
2)正文字体应该尽量使用黑体
从字体的样式来看,宋体是衬线的,黑体是非衬线的。所以应该把中文网页正文的font-family尽量写成以sans-serif结尾。
3)照顾不同的操作系统
对于Windows:在中易宋体和微软雅黑之间二选一。没有微软雅黑的系统会回退到中易宋体。 对于Mac OS X:首先使用冬青黑体简体中文。没有冬青黑体简体中文的系统会回退到华文黑体。 对于iOS:系统会自动使用华文黑体。 对于Linux:首先使用文泉驿微米黑。没有文泉驿微米黑的系统会回退到别的字体。 对于Android:系统会自动使用Droid Sans。
跳转链接的相对路径
假设info.html路径是:c:Inetpubwwwrootsiteslablainfo.html 假设index.html路径是:c:Inetpubwwwrootsiteswowstoryindex.html 在info.html加入index.html超链接的代码应该这样写:
十六.标签的转译
1.转移escape
2.解移unescape
十七.study下子regularUI对父UI的操作
1.直接关系
子:this.$emit('event',_data);
父:this.$on('event',function(){ todo});
2.间接接关系
如:父UI弹窗,调用nej弹窗,弹窗组件里内嵌regularUI,这时可以把父组件挂在window下,子组件取到从而进行父组件的状态更新
十八.sessionStorage
共同点:都是保存在浏览器端,且同源的。
1.sessionstorage,localstorage和cookie之间的区别
cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
2.sessionstorage的使用
sessionstorage存储的是字符串,存储对象,可以先把对象转换成字符串
var obj = { name:'Jim' }; var str = JSON.stringify(obj); //存入 sessionStorage.obj = str; //读取 str = sessionStorage.obj; //重新转换为对象 obj = JSON.parse(str);
十九.js数值类型的范围
js数值类型的范围:−9007199254740992 and 9007199254740992 (即正负2的53次方)
二十.loading 加载的实现
主要是等待图片加载完成
updateProgress: function(cb) { var $img = $('.m-section').find('img'), imgNum = $img.length, sucNum = 0; var _that = this; $img.load(function() { sucNum ++; _that.data.loadLen = _that.data.len + (sucNum/imgNum)*(_that.data.totalLen-_that.data.len); _that.$update(); if(imgNum === sucNum){ _that.$refs.progress.style.display = 'none'; cb && cb.call(this); } }); }
加载条的演示
给加载条的父级定宽度
进度条宽度随着img加载完成的数量而增加
二十一.答题的基本实现逻辑(基于regular)
1.list出所有的题目,并设定当前题目currenIndex,显示当前,隐藏起他;点击选项时,currenIndex++,及时更新
2.题目的对错判断。
设定正确答案的数组(长度与题目数相同),同时设置选择的数组,每次点击时向选择数组里添加选中题号的index(代表选项),最后对比2个数组即可
3.答题结束
通过currenIndex的值与正确答案的数组长度(即题目的长度)比较即可,每次答完题都要进行判断
二十一.移动端背景图
.ux-question_result { 100%; background: url(http://nos.netease.com/edu-image/36AD363C3B2EA38A2C72C1F2BFD46E6C.png) center top no-repeat; background-size: 100%; position: absolute; top: 0; left: 0; bottom: 0; right: 0;
二十二.bower
Bower的主要作用是,为模块的安装、升级和删除,提供一种统一的、可维护的管理模式。
首先,安装Bower。$ npm install -g bower
然后,使用bower install命令安装各种模块。下面是一些例子。
# 模块的名称 $ bower install jquery # github用户名/项目名 $ bower install jquery/jquery # git代码仓库地址 $ bower install git://github.com/user/package.git # 模块网址 $ bower install http://example.com/script.js
所谓"安装",就是将该模块(以及其依赖的模块)下载到当前目录的bower_components子目录中。下载后,就可以直接插入网页。
src="/bower_componets/jquery/dist/jquery.min.js"
bower update命令用于更新模块。$ bower update jquery
如果不给出模块的名称,则更新所有模块。
bower uninstall命令用于卸载模块。$ bower uninstall jquery
注意,默认情况下,会连所依赖的模块一起卸载。比如,如果卸载jquery-ui,会连jquery一起卸载,除非还有别的模块依赖jquery。
二十三.angular路由
g.adminApp.config(function($stateProvider,$urlRouterProvider){ $stateProvider .state('questionnaire1',{ url:'/questionnaire1/', templateUrl:'questionnaire1.htm', controller:'questionnaire1' }) .state('questionnaire2',{ url:'/questionnaire2/', templateUrl:'questionnaire2.htm', controller:'questionnaire2' }); $urlRouterProvider.otherwise('/questionnaire1/'); }).run(function($rootScope,$state,$stateParams,ngdwr){ $rootScope.tabs = [ {title:"questionnaire_tab1",active:false}, {title:"questionnaire_tab2",active:false} ]; $rootScope.saveTmp = [{}]; $rootScope.selectTab = function(_type){ $rootScope.selectType = _type; switch($rootScope.selectType){ case 0: $state.go('questionnaire1',{ }); break; case 1: $state.go('questionnaire2',{ }); break; } for(var i = 0; i < $rootScope.tabs.length; i++) { $rootScope.tabs[i].active = false; } $rootScope.tabs[$rootScope.selectType].active = true; }; }); /* 问卷设置 */ g.adminApp.controller("questionnaire1",function($scope,$rootScope,ngdwr,$stateParams,$interval){ $rootScope.tabs[0].active = true; $scope.save = function(_objTmp,_key){ /* Long specialId, ListquestionList */ if(!$scope.validate($scope.questionList)){ return; } ngdwr.sendRequest('MicroSpecialAllowBean.saveQuestion1',[{ productId:specialId, productType:30, questionList:$scope.questionList }]).then(function(_data){ if(!!_data){ _bu._$showToastTips({content:"保存成功",type:1}); } else { _bu._$showToastTips({content:"保存失败",type:2}); } }); }; /*请求数据 todo: Long specialId*/ ngdwr.sendRequest('MicroSpecialAllowBean.getQuestion1', [specialId]).then(function(_data){ console.log(_data); if(!!_data){ $scope.questionList = angular.fromJson(_data); }else{ $scope.questionList = []; } }); }); /* 报名管理 */ g.adminApp.controller("questionnaire2",function($scope,$rootScope,ngdwr,$stateParams,$interval){ $rootScope.tabs[1].active = true; /* 导出 */ $scope.export =function(){ ngdwr.sendRequest('MicroSpecialAllowBean.exportExcel1',[specialId]).then(function(_data){ var _frame; if(!!_data){ console.log(_data); _frame = document.createElement("iframe"); _frame.setAttribute("style", "display:none;0;height:0;position: absolute;top:0;left:0;border:0;height:0;0;"); _frame.src = _data; document.body.appendChild(_frame); setTimeout(function() { _bu._$showToastTips({content:"导出成功",type:1}); },2000); } else { _bu._$showToastTips({content:"导出失败",type:2}); } }); }; $scope.changePage = function (index) { $scope.loadData(index); }; $scope.loadData = function (_index) { if(_index == undefined){ _index == 1; } /*请求数据 todo: Long specialId*/ ngdwr.sendRequest('MicroSpecialAllowBean.getList1', [specialId,30,_index]).then(function(_data){ console.log(_data); if(!!_data){ $scope.result = angular.fromJson(_data); console.log(_data); $scope.signupList = $scope.result.list || []; $scope.pagination = $scope.result.query || {}; $scope.totlePageCount = $scope.pagination.totlePageCount; }else{ $scope.signupList = []; $scope.signupList = {}; } }); }; $scope.loadData(1); }); g.adminApp.filter('getStatusDesc1',function(){ return function(status){ if(status == 0){ return '--'; }else if(status == 1){ return 'do'; }else if(status == 2){ return 'undo'; } } }); /*必不可少*/ angular.resumeBootstrap(['backend','colorpicker.module']);
二十四.点击出现分享的蒙层提示,点击蒙层消失
shareClick: function(){ var maskObj = jQuery.showComMask({clickFn:deleNode}); maskObj.showMask(); jQuery('.j-shareTips').show(); jQuery('.j-shareTips').on('click',function(){ deleNode(); }); function deleNode() { maskObj.removeMask(); jQuery('.j-shareTips').hide(); }; }
二十五.移动端前端开发真机调试攻略
一、IOS 移动端 (Safari开发者工具) 手机端:设置 → Safari → 高级 → Web 检查器 → 开。 mac端:Safari → 偏好设置 → 高级 → 在菜单栏中显示“开发”菜单。 在 OS X 中启动 Safari 之后,以 USB 电缆正常接入 iOS 设备,并在此移动设备上启动 Safari。此时点击计算机上的 Safari 菜单中的“开发”,可以看到有 iOS 设备的名称显示,其子菜单项即为移动设备上 Safari 的所有标签页,点击任意一个开始调试。 便捷,简单,还可以调试外壳包裹的浏览器如微信。
二十六.js 小数取整
1).丢弃小数部分,保留整数部分
js:parseInt(7/2)
2).向上取整,有小数就整数部分加1
js: Math.ceil(7/2)
3).四舍五入
js: Math.round(7/2)
4).向下取整
js: Math.floor(7/2)
二十七.用 JQUERY 取得 DIV 的宽度与高度
1.Block 对象由四部份组成:
Content – 放内容的地方
Padding – 边框与内容之间的留白
Border – 边框
Margin – 边框以外的留白
2.一般讲的宽度指的是内容宽度,但一个 div 的实际宽度不仅只于内容宽度,尤其在做 CSS 排版时更不能搞错,必须同时考虑 Padding、Border 与 Margin 的宽度,四个加起来才是 div 真正占有的宽度。jQuery获取各个值的方法如下:
var content = $(‘div’). width();
var contentWithPadding = $(‘div’). innerWidth();
var withoutMargin = $(‘div’). outerWidth();
var full = $(‘div’). outerWidth(true);
二十九.each与forEach
Jq:$(selector).each(function(index,element));
原生:arrayx.forEach(function(value,index,arrayy){…});
三十:git创建ssh
1.创建
ssh-keygen -t rsa -C "jingwhale@126.com"
然后填写信息,回撤
2.查看公钥
cat ~/.ssh/id_rsa.pub
三十一.mac获取ip地址
ifconfig en0
三十二.选装cnpm
4.1、说明:因为npm安装插件是从国外服务器下载,受网络影响大,可能出现异常,如果npm的服务器在中国就好了,所以我们乐于分享的淘宝团队干了这事。32个�!来自官网:“这是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。”;
4.2、官方网址:http://npm.taobao.org;
4.3、安装:命令提示符执行npm install cnpm -g --registry=https://registry.npm.taobao.org; 注意:安装完后最好查看其版本号cnpm -v或关闭命令提示符重新打开,安装完直接使用有可能会出现错误;
注:cnpm跟npm用法完全一致,只是在执行命令时将npm改为cnpm(以下操作将以cnpm代替npm)。
三十三.移动端h5播放器不调用系统播放器
IOS APP可以使用:可以在 video 标签上加一个 “playsinline webkit-playsinline” 属性
Safari浏览器是没有办法禁止 iPhone Safari video标签视频自动全屏
Obj-C中,添加配置:webview.allowsInlineMediaPlayback = YES;
三十四. js数组的操作
1)数组元素的添加
arrayObj. push([item1 [item2 [. . . [itemN ]]]]);// 将一个或多个新元素添加到数组结尾,并返回数组新长度
arrayObj.unshift([item1 [item2 [. . . [itemN ]]]]);// 将一个或多个新元素添加到数组开始,数组中的元素自动后移,返回数组新长度
arrayObj.splice(insertPos,0,[item1[, item2[, . . . [,itemN]]]]);//将一个或多个新元素插入到数组的指定位置,插入位置的元素自动后移,返回""。
2)数组元素的删除
arrayObj.pop(); //移除最后一个元素并返回该元素值
arrayObj.shift(); //移除最前一个元素并返回该元素值,数组中元素自动前移
arrayObj.splice(deletePos,deleteCount); //删除从指定位置deletePos开始的指定数量deleteCount的元素,数组形式返回所移除的元素
3)数组的截取和合并
arrayObj.slice(start, [end]);
以数组的形式返回数组的一部分,注意不包括 end 对应的元素,如果省略 end 将复制 start 之后的所有元素
arrayObj.concat([item1[, item2[, . . . [,itemN]]]]);
将多个数组(也可以是字符串,或者是数组和字符串的混合)连接为一个数组,返回连接好的新的数组
4)数组的拷贝
arrayObj.slice(0); //返回数组的拷贝数组,注意是一个新的数组,不是指向
arrayObj.concat(); //返回数组的拷贝数组,注意是一个新的数组,不是指向
5)数组元素的排序
arrayObj.reverse(); //反转元素(最前的排到最后、最后的排到最前),返回数组地址
arrayObj.sort(); //对数组元素排序,返回数组地址
6)数组元素的字符串化
arrayObj.join(separator); //返回字符串,这个字符串将数组的每一个元素值连接在一起,中间用 separator 隔开。
toLocaleString 、toString 、valueOf:可以看作是join的特殊用法,不常用
三十五. trackEvent打点
/** * * 使用ga跟踪事件点击处理 * * _category,_action必填 * _opt_label选填,_opt_value选填 * */ p._$trackEvent =function(_category, _action, _opt_label,_opt_value){ if(!!_category && !!_action){ var _arr = [g.gaTrackEvent,_category,_action]; if(!!_opt_label){ _arr.push(_opt_label); if((_opt_value != undefined) && (_opt_value != null)){ _arr.push(parseInt(_opt_value)); } } //google统计 if(!!g[g.gaqStr]){ g[g.gaqStr].push(_arr); } } }
三十六. scaleImage图片处理方法
/** * 通过相册或者的服务动态缩放图片,走CDN * @method _$scaleImage * @param {String} _url 图片地址 * @param {Number} _width 图片压缩后的宽 * @param {Number} _height 图片压缩后的高 * @param {String} _otherProp 附加属性,默认为1x95,可以不传 * */ _module._$scaleImage = _module._$scalePicDynamic = function(_url,_width,_height,_otherProp){
三十七. NEJ打包命令
在工程根目录下运行下面两个命令: nej build tools ewestPublish elease_dev.conf 新文件 nej build tools ewPublish elease.conf 旧文件
三十八. CSS BEM规范
这些CSS类名真是太不精确了,并不能告诉我们足够的信息。尽管我们可以用它们来完成工作,但它们确实非常含糊不清。用BEM记号法就会是下面这个样子:
我们能清晰地看到有个叫.site-search的块,他内部是一个叫.site-search__field的元素。并且.site-search还有另外一种形态叫.site-search--full。
.m-thanks{//块 &_title{...}//元素 &_body{...}//元素 &_img{...}//元素(m-thanks_img在m-thanks_body结构里,尽量不嵌套) &--full{...}//修饰符,表示m-thanks的不同状态 }
三十九. node scroll
that.$refs.chatScroll.onscroll = function () { var _curScrollDistance = that.$refs.chatScroll.scrollTop; if(_initScrollDistance - _curScrollDistance > _halfChatHeight){ that.data.moreMessagePosition = true; } if(_curScrollDistance >= that._getBottomScroll()){ that.data.moreMessagePosition = false; that.data.moreMessage = false; that.data.moreMessageCount = 0; }; that.$update(); }
四十. nej animation
_onAnimationBottom: function (_from, _to) { var that = this; // 创建动画实例 var easeoutAnimation = easeout._$$AnimEaseOut._$allocate({ from: { offset: _from }, to: { offset: _to }, duration: 1000, onupdate: function (_event) { that.$refs.chatScroll.scrollTop = _event.offset; }, onstop: function () { this._$recycle(); } }); // 开始动画 easeoutAnimation._$play(); },
结点没有scrollto()方法,使用scrollTop移动
四十一. mac 查杀进程
➜ study-platform git:(feature/newversion_tag_jsj_20170205) ✗ lsof -i :8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 1249 jingwhale 509u IPv6 0x4f1e2718150a993 0t0 TCP *:http-alt (LISTEN) ➜ study-platform git:(feature/newversion_tag_jsj_20170205) ✗ kill -9 1249
四十二. mooc更新组件
cd src
然后:
bower update
最后:
npm run sync -p web
四十三. 起工程大法
第一步:
autoconfig
第二步:
mvn clean compile -U
四十四. 起edu-front-platform
node node/bin/www
打开页面:
http://localhost:2996/#/sequence
四十五. 校验emoji表情
var pattern = /uD83C[uDF00-uDFFF]|uD83D[uDC00-uDE4F]/g; if(pattern.test(_tagName)){ this.data.warnTipTxt = "不能添加emoji表情!"; return false;; }
四十六. 校验特殊字符校验
//特殊字符校验 //var pattern = new RegExp("([`~!@#$^&*()=|{}^':;',\[\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?\s])"); //var pattern = new RegExp("([\;,/;,、\s])"); var pattern = /[\;,/;,、]/; if(pattern.test(_tagName)){ this.data.warnTipTxt = "标签不可含有以下字符:逗号、分号、顿号、斜杠!"; this.data.suggestListShow = false; return false; }
四十七. 运营后台设置2c
配置路径
src/views/admin/common/config.ftl
改为2c
四十八. 模块设计
1.父模块没有最后的'/''/m/column/manage/topbar': '/m/column/admin/edit', '/m/column/manage/topbar/info/': '/m/column/admin/edit/info/', '/m/column/manage/topbar/list/': '/m/column/admin/edit/list/'
四十九. git pull
养成git操作前 git pull一把
五十. css3 兼容性写法
//flex
ul { display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */ display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */ display: -ms-flexbox; /* TWEENER - IE 10 */ display: -webkit-flex; /* NEW - Chrome */ display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */ } li { -webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */ -moz-box-flex: 1; /* OLD - Firefox 19- */ 20%; /* For old syntax, otherwise collapses. */ -webkit-flex: 1; /* Chrome */ -ms-flex: 1; /* IE 10 */ flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */ }
// transform
transform: translate(-50%,-50%); -ms-transform: translate(-50%,-50%); -webkit-transform: translate(-50%,-50%); -o-transform: translate(-50%,-50%); -moz-transform: translate(-50%,-50%);
五十一. 移动端弹窗样式修复
body div.m-basewin { position: fixed!important; top: 50%!important; transform: translateY(-50%); -webkit-transform: translateY(-50%); -ms-transform: translateY(-50%); }
五十二. 后端取不到#后的参数
如:
"http://www.icourse163.org/course/BIT-46003#/info?inviterId=9436180&activityId=14001&isWebShare=1"
"http://www.icourse163.org/course/BIT-46003"
五十三. chrome全局搜索
option+command+f
五十四. charles使用
1.将 Charles 设置成系统代理
之前提到,Charles 是通过将自己设置成代理服务器来完成封包截取的,所以使用 Charles 的第一步是将其设置成系统的代理服务器。
2.截取移动设备上的网络封包
要截取 iPhone 上的网络请求,我们首先需要将 Charles 的代理功能打开。在 Charles 的菜单栏上选择 “Proxy”->”Proxy Settings”,填入代理端口 8888,并且勾上 “Enable transparent HTTP proxying” 就完成了在 Charles 上的设置。如下图所示:
3.修改服务器返回内容
根据具体的需求,Charles 提供了 Map 功能、 Rewrite 功能以及 Breakpoints 功能,都可以达到修改服务器返回内容的目的。这三者在功能上的差异是:
Map 功能适合长期地将某一些请求重定向到另一个网络地址或本地文件。
Rewrite 功能适合对网络请求进行一些正则替换。
Breakpoints 功能适合做一些临时性的修改。
Map 功能
Charles 的 Map 功能分 Map Remote 和 Map Local 两种,顾名思义,Map Remote 是将指定的网络请求重定向到另一个网址请求地址,Map Local 是将指定的网络请求重定向到本地文件。
在 Charles 的菜单中,选择 “Tools”->”Map Remote” 或 “Map Local” 即可进入到相应功能的设置页面。
对于 Map Local 功能,我们需要填写的重定向的源地址和本地的目标文件。对于有一些复杂的网络请求结果,我们可以先使用 Charles 提供的 “Save Response…” 功能,将请求结果保存到本地(如下图所示),然后稍加修改,成为我们的目标映射文件。
五十五. intellij idea解决慢的问题
1.将intellij idea的VM设置的尽可能大
# custom IntelliJ IDEA VM options
-Xms2g
-Xmx4096m
-XX:ReservedCodeCacheSize=1024m
-XX:+UseCompressedOops
2.不使用没有的插件
3.将不要提交的代码not excluded
五十六. CSS动画效果的回调
1.通过@keyframes我们可以定义动画从开始到结束的样式变化 :
@keyframes show { 0% {color: red;} 25% {color: yellow;} 50% {color: blue;} 100% {color: green;} } @-webkit-keyframes show /* Safari 与 Chrome */ { 0% {color: red;} 25% {color: yellow;} 50% {color: blue;} 100% {color: green;} }
div:hover{ animation:show 5s; }
2.CSS动画的回调函数
像以上的CSS动画,如果想使用回调函数来控制动画完成后的事务处理,是比较麻烦的.
1)延时函数setTimtout(function(){ dosomething() //动画的回调函数 }, delaytime); //动画的持续时间
但是这种方法由于并不是真正意义的回调,会造成以下几个问题:
-由于动画和延时函数并不一定是同一时间开始,导致函数和动画不同步
-会造成JS代码和CSS代码相互关联耦合,修改和维护比较麻烦
-存在多个动画需要回调时会造成代码混乱和臃肿
-在多个动画效果同时结束时会引起回调函数冲突
因此,不建议使用延时函数作为动画的回调函数.
2)JS事件其实,JS提供了两个事件,可以完美的解决动画的回调函数问题,那就是 transtionend 和 animationend,当动画完成时,即会触发对应的事件。具体用法如下:
transtionend
document.getElementById("myDIV").addEventListener("transitionend", myFunction); //myFunction即为动画回调函数
animationend
document.getElementById("myDIV").addEventListener("animationend", myFunction); //myFunction即为回调函数
例子如下:回调函数触发div变为粉色五十七. js数组的map与forEach方法的区别及兼容性用法
原理:
高级浏览器支持forEach方法
语法:forEach和map都支持2个参数:一个是回调函数(item,index,list)和上下文;
forEach:用来遍历数组中的每一项;这个方法执行是没有返回值的,对原来数组也没有影响;
数组中有几项,那么传递进去的匿名回调函数就需要执行几次;
每一次执行匿名函数的时候,还给其传递了三个参数值:数组中的当前项item,当前项的索引index,原始数组input;
理论上这个方法是没有返回值的,仅仅是遍历数组中的每一项,不对原来数组进行修改;但是我们可以自己通过数组的索引来修改原来的数组;
forEach方法中的this是ary,匿名回调函数中的this默认是window;
var ary = [12,23,24,42,1]; var res = ary.forEach(function (item,index,input) { input[index] = item*10; }) console.log(res);//-->undefined; console.log(ary);//-->会对原来的数组产生改变;
map:和forEach非常相似,都是用来遍历数组中的每一项值的,用来遍历数组中的每一项;
区别:map的回调函数中支持return返回值;return的是啥,相当于把数组中的这一项变为啥(并不影响原来的数组,只是相当于把原数组克隆一份,把克隆的这一份的数组中的对应项改变了);
不管是forEach还是map 都支持第二个参数值,第二个参数的意思是把匿名回调函数中的this进行修改。
var ary = [12,23,24,42,1]; var res = ary.map(function (item,index,input) { return item*10; }) console.log(res);//-->[120,230,240,420,10]; console.log(ary);//-->[12,23,24,42,1];
兼容写法:
不管是forEach还是map在IE6-8下都不兼容(不兼容的情况下在Array.prototype上没有这两个方法),那么需要我们自己封装一个都兼容的方法,代码如下:
/** * forEach遍历数组 * @param callback [function] 回调函数; * @param context [object] 上下文; */ Array.prototype.myForEach = function myForEach(callback,context){ context = context || window; if('forEach' in Array.prototye) { this.forEach(callback,context); return; } //IE6-8下自己编写回调函数执行的逻辑for(var i = 0,len = this.length; i < len;i++) { callback && callback.call(context,this[i],i,this); } }
/** * map遍历数组 * @param callback [function] 回调函数; * @param context [object] 上下文; */ Array.prototype.myMap = function myMap(callback,context){ context = context || window; if('map' in Array.prototye) { return this.map(callback,context); } //IE6-8下自己编写回调函数执行的逻辑var newAry = []; for(var i = 0,len = this.length; i < len;i++) { if(typeof callback === 'function') { var val = callback.call(context,this[i],i,this); newAry[newAry.length] = val; } } return newAry; }
五十八. 0.14*100
0.14*100 = 14.000000000000002
五十九. 模块中禁止使用id获取模板节点
this._saveBtnNode = e._$getByClassName(this.__body, 'j-save-btn')[0];
六十. 图片压缩问题
所有图片必须小于100k
多张图标使用精灵图,减少请求
图片使用压缩方法 imageUtil#_$scaleImage
六十一. 避免全局查找
function search() { //当我要使用当前页面地址和主机域名 alert(window.location.href + window.location.host); } //最好的方式是如下这样 先用一个简单变量保存起来 function search() { var location = window.location; alert(location.href + location.host); }
六十二. http & https 协议不带
//错误的 var link = 'http://study.163.com'; //正确的 var link = '//study.163.com';
六十三. 使用AlloyDesigner进行视觉的修改优化
AlloyDesigner六十四. Git如何忽略已经被提交的文件
为什么我增加了 .gitignore 里的规则却没有效果?
这是因为我们误解了 .gitignore 文件的用途,该文件只能作用于 Untracked Files,也就是那些从来没有被 Git 记录过的文件(自添加以后,从未 add 及 commit 过的文件)。
之所以规则不生效,是因为那些 .log 文件曾经被 Git 记录过,因此 .gitignore 对它们完全无效。
问题解决
1.先把.gitignore中css/忽略规则删掉,提交代码 2.删除git对于该文件的追踪信息; git rm -r --cached3.add+commit + push
六十五. 如何清除图片下方出现几像素的空白间隙?
方法1: img{display:block;} 方法2: img{vertical-align:top;} 除了top值,还可以设置为text-top | middle | bottom | text-bottom,甚至特定的和 值都可以 方法3: #test{font-size:0;line-height:0;} #test为img的父元素
六十六. 如何使连续的长字符串自动换行?
方法: #test{150px;word-wrap:break-word;} word-wrap的break-word值允许单词内换行
六十七. 如何做1像素细边框的table?
方法1: #test{border-collapse:collapse;border:1px solid #ddd;} #test th,#test td{border:1px solid #ddd;}
姓名 | Joy Du |
---|---|
年龄 | 26 |
姓名 | Joy Du |
---|---|
年龄 | 26 |
六十八. -webkit-line-clamp
overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
六十九. NEJ调用登录弹窗
NEJ.P('edu.cms').showLoginDialog();
七十. ykt默认字体样式f-f0
默认字体样式:f-f0
七十一. img加上类名选择
img加上类名选择
七十二. setTimeout 0
function a() { setTimeout( function(){ alert(1) }, 0); alert(2); } a();
实际的执行结果确是 “2”、“1”
JavaScript 是单线程执行的,也就是无法同时执行多段代码,当某一段代码正在执行的时候,所有后续的任务都必须等待,形成一个队列,一旦当前任务执行完毕,再从队列中取出下一个任务。这也常被称为 “阻塞式执行”。所以一次鼠标点击,或是计时器到达时间点,或是 Ajax 请求完成触发了回调函数,这些事件处理程序或回调函数都不会立即运行,而是立即排队,一旦线程有空闲就执行。假如当前 JavaScript 进程正在执行一段很耗时的代码,此时发生了一次鼠标点击,那么事件处理程序就被阻塞,用户也无法立即看到反馈,事件处理程序会被放入任务队列,直到前面的代码结束以后才会开始执行。如果代码中设定了一个 setTimeout,那么浏览器便会在合适的时间,将代码插入任务队列,如果这个时间设为 0,就代表立即插入队列,但不是立即执行,仍然要等待前面代码执行完毕。所以setTimeout 并不能保证执行的时间,是否及时执行取决于 JavaScript 线程是拥挤还是空闲。