项目实践

标准html页面head编写

     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="keywords" content="中"/>   
    <meta name="description" content="中"/>  
    <title>中首页</title>
    <link rel="shortcut icon" href="common/img/favicon.ico">
    <link href="common/css/reset.css" rel="stylesheet" type="text/css"/>
    <link href="css/index.css" rel="stylesheet" type="text/css"/> 
    <link href="css/jdt.css" rel="stylesheet" type="text/css"/> 
    <!--[if lt IE 9]>
    <script src="common/js/html5.js" type="text/javascript" language="javascript"></script>
    <script src="common/js/selectivizr.js" type="text/javascript" language="javascript"></script>
    <script src="common/js/PIE.js" type="text/javascript" language="javascript"></script>
    <![endif]-->
    <!--让IE6、IE7、IE8支持html5和css3结束-->         
    <!--IE6支持png图片透明开始-->
    <!--[if IE 6]>
    <script src="common/js/DD_belatedPNG.js" mce_src="DD_belatedPNG.js" type="text/javascript"></script>
    <script type="text/javascript">
        DD_belatedPNG.fix('a, div, ul, img, input, span');
    </script>
    <![endif]-->
    <!--IE6支持png图片透明结束-->
    <script src="common/js/jquery-1.11.1.min.js" type="text/javascript" language="javascript"></script>
    <script src="common/js/echarts.min.js" type="text/javascript" language="javascript"></script>
    <script src="common/js/jquery.SuperSlide.2.1.1.js" type="text/javascript" language="javascript"></script>

    <!--自建js文件-->
    <script type="text/javascript" src="./common/js/circle-progress.js"></script>
    <script type="text/javascript" src="js/index.js"></script>

CSS3的[class^="icon-"]

[attribute^=value] 选择器匹配属性值以指定值开头的每个元素。

[class^="icon-"]意思就是选择CLASS名是以icon-开头的元素,

[attribute=value] 选择器匹配属性值包含指定值的元素*

[class=" icon-"]意思就是CLASS名包含有icon-的元素*

[attribute$=value] 选择器匹配属性值以指定值结尾的每个元素。

CSS的单位及css3的calc()及line-height百分比

#CSS3的新增单位: rem/ vw vh/vmin vmax/ ch ex等等

#CSS以前的单位:em /百分比/rem

##em:相对单位,参考物是父元素的font-size,可继承 eg:若使用浏览器默认值,字体大小位16px,则1em=16px

##百分比:相对于父元素 [使用padding和margin,实际百分比会变化]

#1、对于普通定位元素就是我们理解的父元素

#2、对于position: absolute;的元素是相对于已定位的父元素(offset parent)

#3、对于position: fixed;的元素是相对于 ViewPort

##rem:IE9及以上,相对于根html

html {font-size: 62.5%; /**10 ÷ 16 × 100% = 62.5%    1rem = 10px   **/}   
body {font-size: 1.4rem; /**1.4 × 10px = 14px **/}
h1 { font-size: 2.4rem; /**2.4 × 10px = 24px**/}

##vh和vw :IE10和现代浏览器都支持

#vw Viewport的宽度,1vw等于viewport的1%

#vh Viewport的宽度,1vh等于viewport的1% vw和vh会随着viewport变化自动变化,不需要再用js控制全屏 也可以字体大小用vw vh控制,达到字体和viewport大小同步的效果

##vmin和vmax :IE10+和现代浏览器都支持vmin,但是webkitl浏览器旧版和IE都不支持vmax

#vmin vh和vw中比较小的

#vmax vh和vw中比较大的

##ch和ex:IE9+和现代浏览器支持 根据当前font-family的相对单位

#ch 字符0的宽度

#ex 小写字符x的高度

##CSS3 calc(): IE9+、FF4.0+、Chrome19+、Safari6+ 需要用数学表达式来表示

.haorooms {
  width: calc(expression);
  width: calc(100% - 20px);  //注:减号前后要有空格,否则很可能不生效!!
    width: 90%;/*写给不支持calc()的浏览器*/
    width:-moz-calc(100% - (10px + 5px) * 2);
    width:-webkit-calc(100% - (10px + 5px) * 2);
    width: calc(100% - (10px + 5px) * 2);
}

##line-height :带单位的行高都有继承性,不带行高的直接继承,而不是计算值

#定义行高line-height:2em;父元素字体大小14px 行高28px;则子元素的字体大小为12px的时候,其行高还是28px

#定义行高line-height:2; 父元素大小14px,行高为28px[14乘2],而子元素字体大小12px,则其行高会变成24px

<style>
    .haorooms_bfb{font-size:14px;line-height: 150%; background: green;padding:10px}
    .haorooms_nodw{font-size:14px;line-height: 1.5; background: green;padding:10px}
    .haorooms_children{font-size:26px;background: red}
</style>

<div class="haorooms_bfb">
    <div class="haorooms_children">行高测试</div>
</div>

<br/><br/>

<div class="haorooms_nodw">
    <div class="haorooms_children">行高测试</div>
</div>

有百分比的haorooms_children 继承了父级元素14*1.5=21px

#没有百分比,不带单位的是自己的1.5倍,也就是26*1.5=39px;

window.location

  • 只读属性,返回一个Location对象。其中包含有关文档当前位置的信息 但可以进行赋值
//导航到新的页面;  但要注意安全设置,如COR(跨域资源共享),否则会限制实际加载新页面

window.location = new location
window.location.assign(new location)

//强制服务器重新加载当前页面

window.location.reload(true);

//使用replace重新加载页面
function reloadPageWithHash(){
    var initialPage = window.location.pathname;
    window.location.replace("http://example.com/#" + initialPage);
}
//通过search属性向服务器发送字符串数据
function sendData(sData){
    window.location.search  = sData;
}

##Url统一资源定位符由 scheme :// host: port/path?query#fragment

scheme:通信协议 常用http ftp maito

#window.location.href 整个url字符串

#window.location.protocol URL协议部分

#window.location.host URL主机部分

#window.location.port URL端口部分

#window.location.pathname URL的路径不扥即文件的地址

#window.location.search 查询参数部分

#window.location.hash 锚点

js给url添加时间戳,解决浏览器缓存问题

//解决浏览器缓存
function timestamp(url){
     //  var getTimestamp=Math.random();
       var getTimestamp=new Date().getTime();
      if(url.indexOf("?")>-1){
        url=url+"&timestamp="+getTimestamp
      }else{
        url=url+"?timestamp="+getTimestamp
      }
      return url;
    }

JavaScript 获取当前时间戳: 第一种方法:

var timestamp = Date.parse(new Date()); 结果:1280977330000 第二种方法:

var timestamp = (new Date()).valueOf(); 结果:1280977330748

第三种方法:

var timestamp=new Date().getTime(); 结果:1280977330748

第一种:获取的时间戳是把毫秒改成000显示,

第二种和第三种是获取了当前毫秒的时间戳。

encodeURIComponent() 函数

  • 把字符串作为 URI 组件进行编码。 encodeURIComponent(URIstring)

图像对象

  • 建立图像对象 图像对象的名称 = new Image([宽],[高])
  • 图像对象的属性: border complete height hspace vspace id isMap lowsrc longDes alt align
  • 图像对象的事件:onabort onerror onkeydown onkeypress onkeyup onload
  • src属性一定要写到onload的后面,否则程序IE出错
  • FF中,img对象加载包含在body的加载过程中,img加载完,body才算加载完 触发window.onload是事件
  • IE中 img.onload十几件会在window.onload之后触发
  • ie 火狐等大众浏览器均支持 Image对象的onload事件。
  • ie8及以下、opera 不支持onerror事件

mustache 用法

  • 1.先script引入其js
  • 2.定义模板字符串

方法一:[...].join('')方式在js代码中定义

//通过一些根据属性名称对应的标记定义模板
var tpl = [
        '<ul class="nav navbar-nav navbar-left nav-system">',
        '  <li class="dropdown">',
        '    <a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown" title="切换系统">',
        '     {{curSystemName}} {{#multiple}}<i class="fa fa-caret-down"></i>{{/multiple}}',
        '    </a>',
        '    {{#multiple}}<ul class="dropdown-menu">',
        '        {{#systems}}',
        '           {{^first}}<li role="separator" class="divider"></li>{{/first}}',
        '           <li>',
        '               <a href="{{{systemHttpUrl}}}" target="_self">{{systemName}}</a>',
        '           </li>',
        '        {{/systems}}',
        '    </ul>{{/multiple}}',
        '  </li>',
        '</ul>'
    ].join('');

方法二:直接把模板内容用script定义在html中

<script id="tpl" type="text/html">
    Hello {{name}}!
</script>

然后再编译模板之前,通过获取id的innerHTML定义原始模板串

var tpl = document.getElementById('tpl').innerHTML.trim();

如果此模板用于多页面,建议方法一,如果此页面只用于当前页面,推荐直接定义到script标签中。方便管理

  • 3.预编译模板:由模板串编译之后,数据类型变为数组类型
    Mustache.parse(tpl);
    
  • 4.渲染模板:
    var htmlAfterRendered = Mustache.render(tpl,obj);
    
    obj引用的是一个数据源对象,mustache会把模板中的那些属性标签,根据约定的规则,替换成对象的内容。

mustache的思想

  • 核心是标签和logic-less轻逻辑
  • 常用标签:{{prop}} {{{prop}}} {{#prop}} {{/prop}} {{^prop}} {{/prop}}

  • 1.{{prop}} 将数据源对象上prop属性对应的值,转换成字符串进行输出

mustache渲染{{prop}}的逻辑:

#1. 如果prop引用的值是null或undefined ,则渲染成空串

#2. 如果prop引用的是一个函数,则在渲染时自动执行这个函数,并把这个函数的返回值转换为字符串作为渲染结果。

#3. 其他场景,直接把prop引用的值转换成字符串作为渲染结果

<script id="tpl1" type="text/html">
    -{{prop}}-
</script>
<script>
    var tpl1 = document.getElementById('tpl1').innerHTML.trim();
    Mustache.parse(tpl1);
    //测试falsy值
    console.log(Mustache.render(tpl1, {prop: ''}));//--
    console.log(Mustache.render(tpl1, {prop: 0}));//-0-
    console.log(Mustache.render(tpl1, {prop: null}));//--
    console.log(Mustache.render(tpl1, {prop: undefined}));//--
    console.log(Mustache.render(tpl1, {prop: false}));//-false-
    console.log(Mustache.render(tpl1, {prop: NaN}));//-NaN-

    //测试简单对象
    console.log(Mustache.render(tpl1, {prop: {name: 'jason'}}));//-[object Object]-
    //测试数组
    console.log(Mustache.render(tpl1, {prop: [{name: 'jason'}, {name: 'frank'}]}));//-[object Object],[object Object]-
    //测试日期对象
    console.log(Mustache.render(tpl1, {prop: new Date()}));//-Mon Jan 18 2016 15:38:46 GMT+0800 (中国标准时间)-
    //测试自定义toString的简单对象
    var obj1 = {name: 'jason'};
    obj1.toString = function () {
        return this.name;
    };
    console.log(Mustache.render(tpl1, {prop: obj1}));//-jason-

    //测试boolean number string
    console.log(Mustache.render(tpl1, {prop: true}));//-true-
    console.log(Mustache.render(tpl1, {prop: 1.2}));//-1.2-
    console.log(Mustache.render(tpl1, {prop: 'yes'}));//-yes-

    //测试function
    console.log(Mustache.render(tpl1, {
        prop: function () {
        }
    }));//--
    console.log(Mustache.render(tpl1, {
        prop: function () {
            return 'it\'s a fun'
        }
    }));//-it's a fun-
    console.log(Mustache.render(tpl1, {
        prop: function () {
            return false;
        }
    }));//-false-
    console.log(Mustache.render(tpl1, {
        prop: function(){
            return function (text, render) {
                return "<b>" + render(text) + "</b>"
            };
        }
    }));
    //-function (text, render) {
    //   return &quot;&lt;b&gt;&quot; + render(text) + &quot;&lt;/b&gt;&quot;
    //}-
</script>

由于默认情况下,mustache在渲染prop时,都是对prop的原始值进行url编码或者html编码之后再输出。

//对于单引号转换为html实体的用例,需要用{{{prop}}}
Mustache.render(tpl,{prop:function(){
    return 'it \' a fan'
}});
  • 2.{{#prop}} {{/prop}} 可以同时完成if-else和for-each及动态渲染的模板功能; 标签之间,可以定义其他模板内容,嵌套所有标签。

#if-else

<script id="tpl2" type="text/html">
    -{{#prop}}content{{/prop}}-
</script>
<script>
    var tpl2 = document.getElementById('tpl2').innerHTML.trim();
    Mustache.parse(tpl2);
    //测试falsy值
    console.log(Mustache.render(tpl2, {prop: ''}));//--
    console.log(Mustache.render(tpl2, {prop: 0}));//--
    console.log(Mustache.render(tpl2, {prop: null}));//--
    console.log(Mustache.render(tpl2, {prop: undefined}));//--
    console.log(Mustache.render(tpl2, {prop: false}));//--
    console.log(Mustache.render(tpl2, {prop: NaN}));//--
    //测试空数组
    console.log(Mustache.render(tpl2, {prop: []}));//--
    //测试不存在的属性
    console.log(Mustache.render(tpl2, {prop2: 
true
}));//--
    //测试function
    console.log(Mustache.render(tpl2, {
        prop: function () {
        }
    }));//--
    console.log(Mustache.render(tpl2, {
        prop: function () {
            return false;
        }
    }));//--
    console.log(Mustache.render(tpl2, {
        prop: function() {
            return [];
        }
    }));//--

    //测试简单对象
    console.log(Mustache.render(tpl2, {prop: {name: 'jason'}}));//-content-
   //测试日期对象
    console.log(Mustache.render(tpl2, {prop: new Date()}));//-content-
    //测试boolean number string
    console.log(Mustache.render(tpl2, {prop: true}));//-content-
    console.log(Mustache.render(tpl2, {prop: 1.2}));//-content-
    console.log(Mustache.render(tpl2, {prop: 'yes'}));//-content-
    //测试返回非falsy,非空数组的function
    console.log(Mustache.render(tpl2, {
        prop: function () {
            return 'it\'s a fun'
        }
    }));//-content-
</script>
  • 只有prop属性在数据源对象上存在,并且不为false值(JavaScript6个值:null,undefined,NaN,0,false,空字符串),并且不为空数组的情况下,标签之间的内容才会被渲染,,否则不会被渲染、
  • 当prop属性引用的是一个函数,{{#prop}}会自动调用这个函数,并将这个函数的返回值作为if-else判断的依据。

#for-each

  • 当prop属性所引用的是非空数组,这对标签之间的内容将会根据数组大小进行迭代
  • 当数据元素为对象,还会把该对象作为每一次迭代的上下文,以便迭代时的标签可以直接引用数组元素上的属性
<script id="tpl2" type="text/html">
    -{{#prop}}{{name}},{{/prop}}-
</script>
<script>
     var tpl2 = document.getElementById('tpl2').innerHTML.trim();
     Mustache.parse(tpl2);
     console.log(Mustache.render(tpl2, {prop: [{name: 'jason'}, {name: 'frank'}]}));//-jason,frank,-
</script>

{{#prop}}{{/prop}}之间的模板内容根据prop所引用的数组迭代了两次,并且在这对标签内部直接通过{{name}}标签,输出了数组元素对象上的name属性对应的值。

-如果prop属性所引用的是一个函数,但是这个函数返回值是一个数组类型,那么仍然会进行for-each渲染:

<script id="tpl2" type="text/html">
    -{{#prop}}{{name}},{{/prop}}-
</script>
<script>
     var tpl2 = document.getElementById('tpl2').innerHTML.trim();
     Mustache.parse(tpl2);
     console.log(Mustache.render(tpl2, {
         prop: function(){
             return [{name: 'jason'}, {name: 'frank'}];
         }
     }));//-jason,frank,-
</script>

#动态渲染

  • 当prop属性所引用的是一个函数,并且这个函数的返回值还是一个函数的话,mustache会再次调用这个返回的函数,
  • 并给它传递2个参数:text表示原来的模板内容,render表示mustache内部的执行渲染的对象,以便在这个函数内部可以通过这render对象,
  • 结合原来的模板内容,自定义渲染的逻辑,并把函数的返回值作为渲染结果
<script id="tpl2" type="text/html">
    -{{#prop}}content{{/prop}}-
</script>
<script>
     var tpl2 = document.getElementById('tpl2').innerHTML.trim();
     Mustache.parse(tpl2);
     console.log(Mustache.render(tpl2, {
        prop: function(){
            return function (text, render) {
                return "<b>" + render(text) + "</b>"
            };
        }
    }));//-<b>content</b>-
</script>
  • 3.{{^prop}} {{/prop}} 只有prop属性不存在或者引用的是一个false值,或者一个空数组的时候,才会显示标签之间的内容
<script id="tpl2" type="text/html">
    -{{^prop}}content{{/prop}}-
</script>
<script>
    var tpl2 = document.getElementById('tpl2').innerHTML.trim();
    Mustache.parse(tpl2);
    //测试falsy值
    console.log(Mustache.render(tpl2, {prop: ''}));//-content-
    console.log(Mustache.render(tpl2, {prop: 0}));//-content-
    console.log(Mustache.render(tpl2, {prop: null}));//-content-
    console.log(Mustache.render(tpl2, {prop: undefined}));//-content-
    console.log(Mustache.render(tpl2, {prop: false}));//-content-
    console.log(Mustache.render(tpl2, {prop: NaN}));//-content-
    // 测试空数组
    console.log(Mustache.render(tpl2, {prop: []}));//-content-
    // 测试不存在的属性
    console.log(Mustache.render(tpl2, {prop2: true}));//-content-
    //测试function
    console.log(Mustache.render(tpl2, {
        prop: function () {
        }
    }));//-content-
    console.log(Mustache.render(tpl2, {
        prop: function () {
            return false;
        }
    }));//-content-
    console.log(Mustache.render(tpl2, {
        prop: function () {
            return [];
        }
    }));//-content-

    //测试简单对象
    console.log(Mustache.render(tpl2, {prop: {name: 'jason'}}));//--
    //测试日期对象
    console.log(Mustache.render(tpl2, {prop: new Date()}));//--
    // 测试非空数组
    console.log(Mustache.render(tpl2, {prop: [{name: 'jason'},{name: 'tom'}]}));//--

    //测试boolean number string
    console.log(Mustache.render(tpl2, {prop: true}));//--
    console.log(Mustache.render(tpl2, {prop: 1.2}));//--
    console.log(Mustache.render(tpl2, {prop: 'yes'}));//--

    //测试返回非falsy,非空数组的function
    console.log(Mustache.render(tpl2, {
        prop: function () {
            return 'it\'s a fun'
        }
    }));//--

    //测试返回function的function
    console.log(Mustache.render(tpl2, {
        prop: function () {
            return function(text,render){
                return '<b>' + render(text) +'</b>'
            }
        }
    }));//--
</script>
  • 4.渲染上下文栈
  • 1.模板渲染开始,把数据源对象作为当前的渲染上下文,并压入上下文栈。
  • 遇到{{#prop}}标签时,如果prop引用的是一个对象、非空的对象数组、函数返回值为一个对象或非空对象数组的函数,将这个对象或数组元素作为当前渲染的上下文,压入上下文栈
  • 当标签渲染完毕,再弹出该上下文。

  • {{#prop}}标签可以多次嵌套——有多层上下文存在

<script id="tpl2" type="text/html">
    -{{#person}}{{#student}}{{#address}}address: {{home}},age: {{age}}{{/address}}{{/student}}{{/person}}-
</script>
<script>
    var tpl2 = document.getElementById('tpl2').innerHTML.trim();
    var obj2 = {
        age: 20,
        person: {
            student: {
                address: {
                    home: 'xxxxx'
                }
            }
        }
    };
    console.log(Mustache.render(tpl2, obj2));//-address: xxxxx,age: 20-
</script>
  • 在渲染{{#address}}{{/address}}时,上下文对象已经变成了obj2.person.student.address所引用的对象,所以{{home}}渲染时用到的就是obj2.person.student.address.home属性,
  • 而{{age}}渲染时,由于obj2.person.student.address不存在age属性,所以就会到上层上下文中查找,一直到obj2对象才找到,于是就把obj2.age当成了渲染结果。
  • 2.不用通过{{#prop}}创建上下文,也可以做到递归渲染属性的属性
<script id="tpl2" type="text/html">
    -address: {{person.student.address.home}},age: {{age}}-
</script>
<script>
    var tpl2 = document.getElementById('tpl2').innerHTML.trim();
    var obj2 = {
        age: 20,
        person: {
            student: {
                address: {
                    home: 'xxxxx'
                }
            }
        }
    };
    console.log(Mustache.render(tpl2, obj2));//-address: xxxxx,age: 20-
</script>

只要知道当前的上下文对象,再根据属性操作串person.student.address.home

css选择器中的波浪线~ CSS3新增

li:nth-child(1):hover~ .list-bottom{}

此波浪线~用于分隔两个CSS选择器 第二部分的选择器仅匹配那些不是第一个选择器且不是第一个选择器后代的元素

HTML DOM的userAgent 属性

一个只读字符串,声明了浏览器用于HTTP请求的用户代理头的值 navigator.userAgent ="Mozilla/4.0; MISE 6.0; Windows NT 5.2"

layer.js弹窗组件文档 ——MIT开源软件

layer只是Layui的一个弹层模块,可以作为独立的组件

引用

<scritp src="layer.js"></script>
<script>
    layer.msg('hello);
</script>

基础参数

type title content skin area offset icon btn btnAlign closeBtn shade shadeClose time id anim isOutAnim maxmin fixed resize resizing scrollbar maxWidth zindex move moveOut moveEnd tipsTip tipsMore success yes cancel end full min restore

内置方法

config ready open alert confirm msg load tips close closeAll style title getChildFrame getFrameIndex iframeAuto iframeSrc setTop

layer.open({
  type:0,
  title: '在线调试',
  content: 'I am strong',
  skin:'demo-class',
  area:['500px','300px'],
  offset:['100px','50px'],
  icon:0,
/*  
  btn:['按钮1','按钮2','按钮3'],
  yes:function(index,layero){
        return false
  },
  btn2:function(index,layero){
          return false
  },
  btn3: function(index,layero){
      return false;
  }
 */
});

Javascript 中设计setTimeoutout 延迟时间为0

不加setTimeout 增加setTimeout外围函数
input.focus();input.select(); setTimeout(function(){input.focus();input.select();}, 0);
没有聚焦和集中 可以聚焦和集中

setTimeout会在其完成当前任何延迟事件的事件处理器的执行,以及完成文档当前状态更新后,告诉浏览器去启用setTimeout内注册的函数

  • 把需要执行的任务从队列里跳脱
  • JavaScript引擎对于线程实现的问题
  • 当JavaScript引擎在执行onkeypress时,由于没有多线程的同步执行,不可能同时处理刚创建元素的focus和select事件,由于这两个事件都不在队列中,在完成onkeypress之后,JavaScript引擎就丢了这两个事件
JSRUN前端笔记, 是针对前端工程师开放的一个笔记分享平台,是前端工程师记录重点、分享经验的一个笔记本。JSRUN前端采用的 MarkDown 语法 (极客专用语法), 这里只属于前端工程师。