Web前端开发-新知识点及疑问

Web前端开发

script标签<script type="text/template">疑问

在HTML中嵌入模板HTML,往往是类似这样的写法:

1
2
3
<script type="text/template">
<img src="mm1.jpg">
</script>

实际上,并不存在type=”text/template”这样的标准写法.<script>本身的特定,让内部的HTML标签是按照字符串处理的,因此,天生内容不显示。

在js里面,经常需要使用js往页面中插入html内容。比如这样:
var number = 123; $('#d').append('<div class="t">'+number+'</div>')
如果html很短还好说,但是遇到描述里面的这么大段,直接用字符串存储会很困难,因为不光要处理单引号,还需要很多「+」号把字符串一个个连接起来,十分的不方便。
<script>设置type="text/template",标签里面的内容不会被执行,也不会显示在页面上,但是可以在另一个script里面通过获取,然后再通过 相关的模板工具进行处理,插入到页面中。这样就把大段的HTML操作从js里面分离开了。

示例:异步加载每屏内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<body>
<script id="page2" type="text/template">
第二屏
<img src="img/landscape.png" alt="">
</script>

<script id="page3" type="text/template">
第三屏
</script>

<script id="page4" type="text/template">
第四屏
</script>

<div class="wp">
<div class="wp-inner">
<div class="page page1" data-load="1">第一屏</div>
<div class="page page2"></div>
<div class="page page3"></div>
<div class="page page4"></div>
</div>
</div>
<span class="start"><b></b></span>
<script src="js/zepto.min.js"></script>
<script src="../src/zepto.fullpage.js"></script>
<script>
$('.wp-inner').fullpage({
change: function (e) {
var cur = e.cur;
var $page = $('.page').eq(cur);
// 避免重复加载
if ($page.data('load') == 1) {
return 1;
}
// 加载每屏内容
$page.html($('#page' + (cur + 1)).html());
// 标记已加载过的屏
$page.data('load', 1);
}
});
</script>

</body>

jQuery $(‘’).data(‘’)理解。

1
2
3
4
5
6
7
8
9
10
11
<div class="page page4">
<div class="js-animate animated" data-animate="rollIn">rollIn</div>
</div>

$('.page').eq(e.cur).find('.js-animate').each(function() {
$(this).removeClass($(this).attr('data-animate')).hide();
});
//上述代码等价于:
$('.page').eq(e.cur).find('.js-animate').each(function() {
$(this).removeClass($(this).data('animate')).hide();
});

jQuery从1.4.2版本开始支持$.data()方法来直接访问data属性,同时也不需要写data-关键词了

zepto.js中的$()

zepto.js中的$()是一个类似数组的对象.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="music" class="music">
<audio src="media/bg.mp3" loop autoplay="true" preload="auto" id="myAudio" width="25" height="25" ></audio>
</div>
<script src="js/zepto.min.js"></script>
<script src="js/zepto.fullpage.js"></script>
<script>
var myAudio=$("#myAudio");
// var myAudio=$("#myAudio")[0]或者var myAudio=document.getElementById("myAudio");
$('#music').on('click', function (e) {
if (myAudio.paused) {
myAudio.play();
} else{
myAudio.pause();
}
});
</script>

上面的代码会报错,提示信息:
VM361:2 Uncaught TypeError: myAudio.play is not a function(…)
通过调试工具调试,myAudio为一个类数组对象,其值为:
[<audio src=​"media/​bg.mp3" loop autoplay=​"true" preload=​"auto" id=​"myAudio" width=​"25" height=​"25">​</audio>​]
因此,需要将var myAudio=$("#myAudio")修改为如下形式:
var myAudio=$("#myAudio")[0] 或者var myAudio=document.getElementById("myAudio")

HTTPS 网页中加载的 HTTP资源问题: Mixed Content

问题描述:
浏览器默认是不允许在HTTPS里面引用HTTP资源的,一般都会弹出提示框,用户确认后才会继续加载,用户体验非常差。而且如果在一个HTTPS页面里动态的引入HTTP资源,比如引入一个js文件,会被直接block掉的。Chrome 21之后,在SSL加密页面embed非SSL的Flash会怎样呢?会被默默的屏蔽掉,只留下一句console报告。

HTTPS 网页中加载的 HTTP 资源被称之为 Mixed Content(混合内容),不同浏览器对 Mixed Content 有不一样的处理规则。

现代浏览器(Chrome、Firefox、Safari、Microsoft Edge),基本上都遵守了 W3C 的 Mixed Content 规范,将 Mixed Content 分为 Optionally-blockable 和 Blockable 两类:
Optionally-blockable 类 Mixed Content 包含那些危险较小,即使被中间人篡改也无大碍的资源。现代浏览器默认会加载这类资源,同时会在控制台打印警告信息。这类资源包括:

  • 通过 <img>标签加载的图片(包括 SVG 图片);
  • 通过<video> / <audio><source>标签加载的视频或音频;
  • 预读的(Prefetched)资源;
    除此之外所有的 Mixed Content 都是 Blockable,浏览器必须禁止加载这类资源。所以现代浏览器中,对于 HTTPS 页面中的 JavaScript、CSS 等 HTTP 资源,一律不加载,直接在控制台打印错误信息。

解决方案

  1. iframe方式
    可以使用iframe的方式引入HTTP资源,比如在HTTPS里面播放优酷的视频,我们可以先在一个HTTP的页面里播放优酷视频,然后将这个页面嵌入到HTTPS页面里就可以了,另外一个典型的例子是在HTTPS页面里通过AJAX的方式请求HTTP资源,Chrome是不允许直接AJAX请求HTTP的。如果两个页面的内容都可以控制的话,当前窗口可以iframe窗口进行通信的。
  2. 相对协议
    对于同时支持HTTPS和HTTP的资源,引用的时候要把引用资源的URL里的协议头去掉,例如://www.example.com/scirpt.js,这样相当于相对路径,即浏览器会自动根据当前是HTTPS还是HTTP来给资源URL补上协议头的,可以达到无缝切换。
    具体使用方法为:
    <img src="//domain.com/img/logo.png">
    简而言之,就是将URL的协议(http、https)去掉,只保留//及后面的内容。这样,在使用https的网站中,浏览器会通过https请求URL,否则就通过http发送请求。
    附注:如果是浏览本地文件,浏览器通过file://协议发送请求,导致请求失败,因此本地测试最好是搭建一个本地服务器。

参考资源:

  1. 如何在HTTPS里调用HTTP资源不出现提示框 http://www.tuicool.com/articles/VZ3ANj
  2. https 页面中引入 http 资源的解决方式 https://segmentfault.com/a/1190000004200361?utm_source=Weibo

CSS3 content 属性

content一般和:before,:after一起使用,用来生成内容(img和input没有该属性),content的内容一般可以为以下四种:

  • none: 不生成任何值。
  • attr: 插入标签属性值
  • url: 使用指定的绝对或相对地址插入一个外部资源(图像,声频,视频或浏览器支持的其他任何资源)
  • string: 插入字符串

举例:
<a>元素没有文本内容,但是有 href 属性的时候,可以显示它的 href 链接:

1
2
3
a[href^="http"]:empty::before {
content: attr(href);
}

参考:

  1. css3 content 生成内容 http://www.w3cplus.com/solution/css3content/css3content.html

transform:rotate(1turn)

transiform rotate 单位有好几种:
一、deg

1
2
3
4
5
6
7
.example {  
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-o-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}

二、grad
Gradians (grad)

1
2
3
.example {  
transform: rotate(400grad);
}

三、rad
Radians (rad)

1
2
3
.example {  
transform: rotate(6.2831853rad);
}

四、turn 这个单位Firefox不可行,有兼容。
Turns (turn)

1
2
3
.example {  
transform: rotate(1turn);
}

参考:http://www.css88.com/book/css/values/angle/turn.htm

css3的calc()

calc是英文单词calculate(计算)的缩写,是css3的一个新增的功能,用来指定元素的长度。比如说,你可以使用calc()给元素的border、margin、pading、font-size和width等属性设置动态值。
calc()最大的好处就是用在流体布局上,可以通过calc()计算得到元素的宽度。

calc()能做什么?

calc()能让你给元素做计算,你可以给一个div元素,使用百分比、em、px和rem单位值计算出其宽度或者高度,比如说“width:calc(50% + 2em)”,这样一来你就不用考虑元素DIV的宽度值到底是多少,而把这个烦人的任务交由浏览器去计算。

calc()语法

calc()语法非常简单,就像我们小时候学加 (+)、减(-)、乘(*)、除(/)一样,使用数学表达式来表示:

1
2
3
.elm {
width: calc(expression);
}

其中”expression”是一个表达式,用来计算长度的表达式。
表达式中有“+”和“-”时,其前后必须要有空格,如”widht: calc(12%+5em)”这种没有空格的写法是错误的;
例如:

1
2
3
.haorooms{
width: calc(100% - 20px); //注:减号前后要有空格,否则很可能不生效!!
}

参考资料:
CSS3的calc()使用 http://www.w3cplus.com/css3/how-to-use-css3-calc-function.html

滚动条样式设置

设置是否显示滚动条主要是在CSS中设置下列的属性:
overflow: visible | auto | hidden | scroll
overflow-x:横向滚动条
overflow-y:纵向滚动条

滚动条外观设置:
在IE中,主要是使用各种颜色属性:

1
2
3
4
5
6
7
8
scrollbar-3dlight-color:color;设置或检索滚动条亮边框颜色;    
scrollbar-highlight-color:color;设置或检索滚动条3D界面的亮边颜色;
scrollbar-face-color:color;设置或检索滚动条3D表面的颜色;
scrollbar-arrow-color:color;设置或检索滚动条方向箭头的颜色;当滚动条出现但不可用时,此属性失效;
scrollbar-shadow-color:color;设置或检索滚动条3D界面的暗边颜色;
scrollbar-darkshadow-color:color;设置或检索滚动条暗边框颜色;
scrollbar-base-color:color;设置或检索滚动条基准颜色。其它界面颜色将据此自动调整。
scrollbar-track-color:color;设置或检索滚动条的拖动区域颜色

在Chrome中,基本上是使用webkit专用属性设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
::-webkit-scrollbar-track-piece{
background-color:#fff;/*滚动条的背景颜色*/
-webkit-border-radius:0;/*滚动条的圆角宽度*/
}
::-webkit-scrollbar{
width:8px;/*滚动条的宽度*/
height:8px;/*滚动条的高度*/
}
::-webkit-scrollbar-thumb:vertical{/*垂直滚动条的样式*/
height:50px;
background-color:#999;
-webkit-border-radius:4px;
outline:2px solid #fff;
outline-offset:-2px;
border: 2px solid #fff;
}
::-webkit-scrollbar-thumb:hover{/*滚动条的hover样式*/
height:50px;
background-color:#9f9f9f;
-webkit-border-radius:4px;
}
::-webkit-scrollbar-thumb:horizontal{/*水平滚动条的样式*/
width: 5px;
background-color: #CCCCCC;
-webkit-border-radius: 6px;
}

CSS Reset样式重置

reset.css和normalize.css
reset是重置所有元素的样式,normalize重置部分元素。
reset.css: https://cssreset.com
normalize.css:https://necolas.github.io/normalize.css/3.0.2/normalize.css

根据浏览器当前的分辨率改变font-size的值

通过JS去动态计算根元素的font-size,作用:所有设备分辨率都能兼容适配。
js代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
docEl.style.fontSize = 20 * (clientWidth / 320) + 'px';
};

if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);

/*
另一种方案:这种方式,可以精确地算出不同屏幕所应有的rem基准值
这个方案同时解决了三个问题:
1.border: 1px问题
2.图片高清问题
3.屏幕适配布局问题
*/

var dpr, rem, scale;
var docEl = document.documentElement;
var fontEl = document.createElement('style');
var metaEl = document.querySelector('meta[name="viewport"]');

dpr = window.devicePixelRatio || 1;
rem = docEl.clientWidth * dpr / 10;
scale = 1 / dpr;


// 设置viewport,进行缩放,达到高清效果
metaEl.setAttribute('content', 'width=' + dpr * docEl.clientWidth + ',initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no');

// 设置data-dpr属性,留作的css hack之用
docEl.setAttribute('data-dpr', dpr);

// 动态写入样式
docEl.firstElementChild.appendChild(fontEl);
fontEl.innerHTML = 'html{font-size:' + rem + 'px!important;}';

// 给js调用的,某一dpr下rem和px之间的转换函数
window.rem2px = function(v) {
v = parseFloat(v);
return v * rem;
};
window.px2rem = function(v) {
v = parseFloat(v);
return v / rem;
};

window.dpr = dpr;
window.rem = rem;

不用JS我们也可以做适配,一般我们在做web app都会先统计自己网站有哪些主流的屏幕设备,然后去针对那些设备去做media query设置也可以实现适配,例如下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
html {
font-size : 20px;
}
@media only screen and (min-width: 401px){
html {
font-size: 25px !important;
}
}
@media only screen and (min-width: 428px){
html {
font-size: 26.75px !important;
}
}
@media only screen and (min-width: 481px){
html {
font-size: 30px !important;
}
}
@media only screen and (min-width: 569px){
html {
font-size: 35px !important;
}
}
@media only screen and (min-width: 641px){
html {
font-size: 40px !important;
}
}

参考资源:web app变革之rem http://isux.tencent.com/web-app-rem.html

body选择器中声明Font-size=62.5%的原因

  • px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。
  • em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。
  • rem是CSS3新增的一个相对单位(root em,根em)

任意浏览器的默认字体高都是16px。所有未经调整的浏览器都符合: 1em=16px。那么12px=0.75em,10px=0.625em。
为了简化font-size的换算,需要在css中的body选择器中声明Font-size=62.5%,这就使em值变为 16px*62.5%=10px, 这样12px=1.2em, 10px=1em, 也就是说只需要将你的原来的px数值除以10,然后换上em作为单位就行了。

在写CSS的时候,需要注意两点:

  1. body选择器中声明Font-size=62.5%;
  2. 将你的原来的px数值除以10,然后换上em作为单位;
  3. 重新计算那些被放大的字体的em数值。避免字体大小的重复声明。
    也就是避免1.2 * 1.2= 1.44的现象。比如说你在#content中声明了字体大小为1.2em,那么在声明p的字体大小时就只能是1em,而不是1.2em, 因为此em非彼em,它因继承#content的字体高而变为了1em=12px。

jQuery:focusin/focusout与focus/blur事件区别:

本质区别:是否支持冒泡处理
focusin当一个元素,或者其内部任何一个元素获得焦点的时候会触发这个事件。这跟focus事件区别在于,他可以在父元素上检测子元素获取焦点的情况。例如:

1
2
3
4
5
<p><input type="text" /> <span>focusout fire</span></p>
<p><input type="password" /> <span>focusout fire</span></p>jQuery 代码:
$("p").focusin(function() {
$(this).find("span").css('display','inline').fadeOut(1000);
});

focusout当一个元素,或者其内部任何一个元素失去焦点的时候会触发这个事件。这跟blur事件区别在于,他可以在父元素上检测子元素失去焦点的情况。

BFC 块级格式化上下文(Block Formatting Context)

Block Formatting Context (块格式化上下文)是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。
也可以说BFC就是一个作用范围。可以把它理解成是一个独立的容器,并且这个容器的里box的布局,与这个容器外的毫不相干。

BFC布局规则:

  • 内部的Box/子元素会在垂直方向,一个接一个地放置。
  • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
  • 每一个元素左外边与包含块的左边相接触(对于从右到左的格式化,右外边接触右边), 即使存在浮动也是如此
  • BFC的区域不会与float box重叠。
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  • 计算BFC的高度时,浮动元素也参与计算

触发BFC的条件

  • 根元素
  • float属性不为none
  • position为absolute或fixed
  • display为inline-block, table-cell, table-caption, flex, inline-flex
  • overflow不为visible

BFC的作用

  1. BFC 防止垂直 margin 重叠
  2. BFC 可以清除浮动
  3. BFC 可以阻止元素被浮动元素覆盖

参考资源:

  1. 前端精选文摘:BFC 神奇背后的原理 http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html

浏览器解析CSS的两种模式:标准模式(strict mode)和怪异模式(quirks mode)

标准模式:浏览器按W3C标准解析执行代码;
怪异模式:使用浏览器自己的方式解析执行代码,因为不同浏览器解析执行的方式不一样,所以我们称之为怪异模式。

浏览器解析时到底使用标准模式还是怪异模式,与你网页中的DTD声明直接相关,DTD声明定义了标准文档的类型(标准模式解析)文档类型,会使浏览器使用相应的方式加载网页并显示,忽略DTD声明,将使网页进入怪异模式(quirks mode)。

IE的X-UA-Compatible混搭:
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">。这样写的好处:可以让ie在最好的渲染方式下渲染页面。
“IE=edge,chrome=1”,可以写成”chrome=1,IE=edge”、”chrome=1; IE=edge”。

表单post提交数据方式:

enctype这个属性管理的是表单的MIME编码。共有三个值可选:
1、application/x-www-form-urlencoded
2、multipart/form-data
3、text/plain
其中application/x-www-form-urlencoded是默认值,作用是设置表单传输的编码。例如我们在AJAX中见过xmlHttp.setRequestHeader(“Content-Type”,”application/x-www-form- urlencoded”);,因为默认的HTML表单就是这种传输编码类型(enctype=application/x-www-form-urlencoded)的。
而multipart/form-data是用来制定传输数据的特殊类型的,主要就是我们上传的非文本的内容,比如图片或是是mp3/文件等等。
text/plain是纯文本传输的意思,在发邮件的时候要设置这种编码类型,否则会出现接收时编码混乱的问题。

网络上经常拿text/plain和 text/html做比较,其实这两个很好区分,前者用来传输纯文本文件,后者则是传递html代码的编码类型,在发送头文件时才用得上。①和③都不能用于上传文件,只有multipart/form-data才能完整的传递文件数据。

共同点:都是在浏览器端存储的数据,且同源的。

区别:

  • 与服务器端通信: cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。
  • 存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
  • 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
  • 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
  • Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。
  • Web Storage 的 api 接口使用更方便。

图片延迟加载

思路:让在可视区域的图片立即加载进来,而让不在可视区域并且需要通过滚动条进行滚动显示的图片在图片滚动到可视区域内再显示出来

img标签中的src,一开始我们并没有给它具体的图片的资源路径,而是自己定义了一个属性 x-src,该属性的值是图片图片的资源路径,每一行的img都是如此,接下来,当页面载入的时候,我们使用jquery(当然,你想javascript原生的代码也可以,我这里只是为了省时间而已)来循环遍历每一个img,判断每一个图片是否在当前可视区域内,是则显示图片,否则稍后处理

如果图片先对于文档的偏移量+图片元素本身的高度的一半 < 浏览器可视区域的高度,即表明图片已经有一半进入的可视区域了,那么我就应该要把这张图片加载进来了,可是img标签的src是为空的,x-src的值才是图片的资源路径,这个时候就需要用jquery将img 标签的x-src值传给src,从而将图片加载进来,具体实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
$(document).ready(function(){
$("img").each(function(){
if (($(this).offset().top+$(this).width()/2) < $(window).height()) {
$(this).attr("src",$(this).attr("x-src"));
}
})
$(window).scroll(function(){
$("img").each(function(){
if($(this).attr("src")==""){
if (($(this).offset().top+$(this).width()/2) < $(window).height()+$(window).scrollTop()) {
$(this).attr("src",$(this).attr("x-src"));
}
}
})
})
})
</script>

坚持原创技术分享,您的支持将鼓励我继续创作!