us项目小经验加坑

js按照属性排序

通常在项目中后台会返回一个json对象数组给我们,并且是无序的,而在页面上我们需要按照一定的顺序排序,通常是按照某个属性来进行排序的,那么怎么按照某个属性给一个元素都是对象的数组进行排序。
var arr=[
    {age:13,name:'sdsd'},
    {age:12,name:'ewewr'},
    {age:10,name:'fdggf'}
]
我们想按照age这个属性来进行排序。
function sortArr(property,objArr){
    return objArr.sort(obj1,obj2){
        var val1=obj1[property],
            val2=obj2[property];
        return val1-val2;    //这是按升序排的,要按降序排的话就把val1和val2的顺序对调
    }
}
sortArr('age',arr);  
--> var arr=[
    {age:10,name:'fdggf'},
    {age:12,name:'ewewr'},
    {age:13,name:'sdsd'}
]

json数据缓存sessionStorage或者localStorage

众所周知的是,无论什么类型的数据存入sessionStorage或者localStorage或者cookie之后都会被转换成字符类型,如:存入之后变成string
那么我们怎么将这个字符串取出来之后变成和原来一样的数据类型呢(这里的就是json类型的数组)我们一开始会想的是不是用split(‘,’)方法想办法拆分成数组,但是取出来的结果是这样的。每个元素对象还是字符串所以这种方法是不可行的,最简单的方法就是一开始咱们就将这个json数组转换成json类型的字符串存入到sessionStorage里面,然后取出来的时候咱们再用JSON.parse()方法将json类型的字符串转换成JSON数组,其实这个方法我们是投机使用了JSON数据类型提供给我们的类型转换方法。具体如下:
var arr=[
    {age:10,name:'fdggf'},
    {age:12,name:'ewewr'},
    {age:13,name:'sdsd'}
];
sessionStorage.setItem('abc',JSON.stringify(arr));
JSON.parse(sessionStorage.getItem('abc'));

具体示例

正则表达式起航

匹配单个字符.

.号可以用来匹配任何的单字符(除换行符以外),包括点号本身,如:
var str="abc.md,abd.md";
var reg=new RegExp('ab.\.md','g'); 
var res=[];
res=str.match(reg);
--> ["abc.md", "abd.md"]  输出结果
上面的g表示全局匹配,也就是说返回所有的这个表达式匹配到的结果,否则只返回第一个匹配到的结果;然后\是正则表达式的一个元字符,表示转义,也就是说’\.‘表示后面的的就是真实的.不是正则表达式的元符号,不匹配任何东西。如果我们要匹配’\’的话就应该这样’\\’,前面加一个\就可以了。最后再次强调.只能匹配单个字符,但不包括空,如:
var str="ab";
var reg=new RegExp('ab.');
var res=[];
res=str.match(reg);
-->null  输出结果

匹配一组字符[]+^+-

[]是一个需想要匹配的单个字符的集合,比如说,在某个位子上我只想匹配a或者n,那我就可以这样写[an];那这样这个位置只会匹配a或者n,不匹配其他的,所以[]就是匹配这个字符集合中的任何一个字符即可。比如你想匹配0到9之间的数字,那就可以[0123456789]这样写,但是这样写会不会觉得太麻烦,所以’-‘就挺身而出了,[0123456789]可以写成[0-9],这里的-就是一个连接符,在[]里面-没有任何的作用,只有链接的作用,不匹配任何一个字符。效果如下:
var str="ab.xls,sb.xls,jb.xls,";
var reg=new RegExp('[sj]b.xls','g');
var res=[];
res=str.match(reg);
--> ["sb.xls", "jb.xls"]  输出结果(不匹配ab.xls);
还有这样的
var str="sbc.xls,sb1.xls,jb2.xls,";
var reg=new RegExp('[sj]b[0-9].xls','g');
var res=[];
res=str.match(reg);
--> ["sb1.xls", "jb2.xls"]  输出结果(不匹配sbc.xls);
现在该轮到^出场了,^是元字符,表示取非匹配,就是说不是这个的都匹配,[^0-9]表示这个位置不匹配0-9的数字。还可以连着写[^0-9^a-z^A-Z]表示不配数字,大小写字母。如:
var str="sbc.xls,sb1.xls,jb2.xls,sb!.xls";
var reg=new RegExp('[sj]b[^0-9^a-z^A-Z].xls','g');
var res=[];
res=str.match(reg);
--> ["sb!.xls"]  输出结果

各种元字符

空白元字符

  • [\b]:回退并删除一个字符(Backspace),\f:换页符 ,\n:换行符,\r:回车符,\t:制表符(Tab),\v:垂直制表符

数字和字母(非)匹配

  • \d:匹配数字,相当于[0-9], \D:匹配非数字的任意一字符,相当于[^0-9];
  • \w:任何一个字母数字字符(大小写均可)或下划线字符(等价于[a-zA-Z0-9_])
  • \W:任何一个非字母数字字符(大小写均可)或非下划线字符(等价于[^a-zA-Z0-9_])

(非)空白元字符匹配

  • \s:任何一个空白元字符(相当于[\r\f\t\n\v]);
  • \S:任何一个非空白元字符(^\r\t\v\n\f);

angular之directive浅谈

angular之directive浅谈

directive就是angular提供的一种方法,他注重对DOM的操作,简化controller里面的操作,她可以根据需求对DOM变形以及行为操作,ng-controller,ng-model等就是angular内置的directive。这里说的directive是我们自己根据需求自定义的。

命名

directive的命名规则是多样的,并不局限与于种,如my:directive,my-directive,my_directive等等,但是推荐使用的是第二种my-directive;在js里对应的就是myDirective,就和普通的js样式写法一样,去掉-然后-后面的字母大写。

声明形式(restrict)

directive声明形式一共有四种:E,A,C,M。
E:<my-directive></my-directive>,通俗理解就是可以把directive名作为HTML标签名;
A:<div my-directive></div>,这个就是说directive名作为属性名;
C:<div class="my-directive sjf">,这个就是说directive名作为class名;
M:(//这个可以忽略)
directive默认的声明形式是A,就是说默认当做属性名

HTML模板指定

template和templateUrl,template就是直接把你想要的HTML模板写在template里面,templateUrl就是你把想要的HTML内容写在一个模板里面了,然后引入这个模板。
replace参数有俩个值,一个true,一个false,默认是false,true就是会把<div my-directive></div>替换成你的模板里面的内容,false就是把模板的内容插入进去。

directive的编译三阶段

1.将HTML转换成DOM,所以自定义HTML标签必须符合HTML格式

2.搜索匹配directive,执行directive上的compile方法

3.执行directive上的link方法以及进行scope和事件绑定

compile是在DOM渲染之前执行的就是把模板HTML渲染成想要的HTML的过程,compile方法的参数的element和attr是tElement和tAttr,就是说还是处于模板阶段,然后compile方法还可以返回一个函数,这个函数就是link要执行的函数,因为在一个directive里面,compile属性被设置后,link属性的方法就不会在被执行。所以这时就只有通过compile的返回函数来代替link方法要干的活了。

app.directive('sideBar',function(){
    return {
        link:function(){
            console.log('link');
        }, 
        compile:function(){
            console.log('compile');
            //return function(){
               // console.log('link');
            //};
        }
    }
})          -->结果只输出了compile,如果去掉注释就会输出link

然后这个compile方法返回的函数其实可以分为pre-link和post-link方法

app.directive('sideBar',function(){
    return {
        compile:function(){
            console.log('213');  //第一执行
            return {
                post:function(){
                    console.log('post');  //最后执行
                },
                pre:function(){
                    console.log('pre');  //第二执行
                }
            }
        }
    }
})
compile阶段结束之后,pre()的参数里面的element是模板编译之后的element,
<!-- HTML部分 --> 
<my-directive>
    <lever>{{name}}</lever>
</my-directive>   
<!-- js部分 -->
app.directive('myDirective',function(){
    return {
        restrict:'E',
        compile:function(tEle,tAttr){
            console.log(name+':compile =>' +tEle.html());
            return {
                pre:function(scope,ele,attrs){
                    console.log(name+':pre =>'+ele.html());
                },
                post:function(scope,ele){
                    console.log(name+':post =>'+ele.html());
                }
            }
        }
    }
});
结果是这样的

compile方法执行后的结果;
可以看到compile执行之前和之后的HTML是不一样的。

compile阶段发生的事情

在angular中compile用来改变DOM,首先在不执行js的时候,浏览器创建的element就是;当执行js之后,ng会遍历DOM,这时会发现my-directive,就会去执行一些函数,compile函数定义在这个指令对象里面,所以这时会被调用执行,并传递一个element对象做参数。并且会递归深度遍历DOM节点重复上述操作。
pre-link方法执行的时候是从最外层指令的依次往里执行,这样就会在所有的子指令pre-link之前执行,也就能够保证运行在他所有子指令以及自身的post-link和pre-link之前。
post-link方法是从最里层依次向外执行的,也就是说这个指令的post-link函数是最后才执行的,这样才能确保所有的子模板都渲染完成,这样自身的渲染才能真正的完成,post-link有人说就是相当于link方法。
示例如下:
<!-- html部分 -->
<my-directive-one>
     <my-directive-two>
         <my-directive-three>
            {{name}}
         </my-directive-three>
    </my-directive-two>
</my-directive-one> 
<!-- js部分 -->
function directiveFunction(name){
    return function(){
        return {
            restrict:'E',
            compile:function(tEle,tAttr){
                console.log(name+':compile =>' +tEle.html());
                return {
                    pre:function(scope,ele,attrs){
                        console.log(name+':pre =>'+ele.html());
                    },
                    post:function(scope,ele){
                        console.log(name+':post =>'+ele.html());
                    }
                }
            }
        }
    }
}
app.directive('myDirectiveOne',directiveFunction('myDirecitve1'));
app.directive('myDirectiveTwo',directiveFunction('myDirecitve2'));
app.directive('myDirectiveThree',directiveFunction('myDirecitve3'));

结果如图:pre和compile和post的节点层次执行顺序

最后各个方法使用的环境

compile适合于只有一个模板,然而要重复使用这个模板去修改DOM的环境,ng-repeat使用的就是这个思想,这样大大提高了性能
pre-link函数可以运行一些业务代码在compile函数执行完之后,在所有的子指令post-link函数执行之前。
post-link函数用来执行业务逻辑,因为这时本身的DOM以及深成子指令的DOM也已经渲染完成。

Hexo和Github Page搭建免费博客的各种坑'

Hexo和Github page搭建免费博客

1、首先下载node,git,然后github 的账号(必备);
2、装hexo,npm install -g hexo-cli
3、装好之后就先创建一个博客文件夹,然后在这文件夹里git bash,先hexo init创建项目目录,如图:
hexo初始化项目目录

然后再去配置config_yml,第一个坑出现配置各个选项的值得时候就需要先打一个空格再去配置值不然就会报错,如:title: your title

4、第二个坑就是配置deploy选项的时候就先要配置类型,不要写成github,现在的版本就是git,然后还要装一个库,npm install hexo-deployer-git –save;然后就是配置github你的git hub page仓库的地址时要用ssh模式的,不要用http模式的不然deploy的时候就会说没有权限。
5、第三个坑就是配置主题的时候去github上clone下人家的代码的时候要进入到你的博客文件夹下面的theme文件夹下再clone
6、hexo n ‘md文件的名字’,可以再source文件夹里面找到,hexo g 生成public文件,就是将你的.md文件转换成HTML格式的文件存放在public文件夹里面;hexo d就是将你的代码push到你的github仓库里;hexo server就是运行hexo的本地服务器,监听的端口默认是4000。
7、第四个坑就是你想删除一个博客怎么办,如果你只将source文件夹下的md文件删掉是不行的,因为根据md文件他还生成了一堆文件.这是需要的就是hexo clean命令,他会删除整个public文件夹,然后再将根目录下的db.json删除。这时你在hexo g重新生成public文件就会删除掉你想删除掉的博客

'DOM各种问题'

DOM各种问题

  • cloneNode()

    cloneNode()方法支持一个参数,这个参数为布尔值,即true或false,当为true时,进行深复制,
即不仅仅复制该文档节点,还复制改文档节点里面的文档节点,如:
var swfEveryCookieWrap=document.getElementById('swfEveryCookieWrap');
var def=swfEveryCookieWrap.cloneNode(true);
console.log(def)
结果是
<div data-for="result" id="swfEveryCookieWrap">
 <object type="application/x-shockwave-flash" id="sharedObjectBIDUPSID">
 <param name="swliveconnect" value="true">
 <param name="allowScriptAccess" value="always"><param>
</div>
</br>
但是如果接受的参数是false,那么只会进行浅复制,即只会复制该文档节点,不会复制他的子节点,如:
var swfEveryCookieWrap=document.getElementById('swfEveryCookieWrap');
var def=swfEveryCookieWrap.cloneNode(false);
console.log(def)
结果是
<div data-for="result" id="swfEveryCookieWrap" style="width: 0px; height: 0px; overflow: hidden;"></div> 
  • 通过什么someNode.nodeName得到的结果都是大写的,所以有时候我们要比较的话一定要记得转换成小写的,即toLowerCase(),之后再去比较,这样才不容出错。
  • div.classList.toggle(value),如果这个div已有了这个类名,那就删除,如果没有,就添加进去
  • chorme与其他浏览器不同的地方:
    • 1.chorme下的document.hasFocus()方法执行后的结果和其他浏览器不一样,自行注意
  • 浏览器的渲染模式是由你自己写的html文档的头部声明决定的,也就是说你在头部加了html的声明或者加了html5的文档声明,浏览器的渲染模式就会是标准模式(document.compatMode=”CSS1Compat”),如果不加的话就是简单的html结构,浏览器就会采取混杂模式来渲染(document.compatMode=”BackCompat”)