表示图片想要表达的意思,当图片无法显示的时候会显示文字
<img scr='hahaha.jpg'>img> //应该去掉img>
<input type='text' value=''/> //应该去掉末尾的/
但是如果用React写jsx模板,它就要求每个标签都要闭合,但是它始终不是原生html
有些浏览器可能不会帮你矫正,各家浏览器处理方式不统一
<table> //td没有放在tr里
<td>td>
table>
在ul或ol里面直接写一个div或span是不规范的
因为ul或ol的直接子元素的display:list-item,如果加上一个div,不同浏览器的处理方式不同,同一个样式在不同浏览器中可能会有不同的表现
section/aside/article/nav这种标签,里面需要写一个h1/h2/h3之类的标题标签,因为这四个标签能够划分章节,他们是独立的章节,需要有标题
如果UI里面没有标题,那就可以写一个隐藏的标签,出于SEO的目的,不能display:none,要用一些特殊的处理方式
Listing Detail
使用section可以分章节
在行内元素里面嵌套块级元素是不合法的
如果在a标签里面嵌套块元素,可能会导致点击无法跳转页面
解决:可以把inline元素的display改成block
将页面设置为标准模式,如果不这么写则默认为怪异模式
浏览器解析css代码有两种模式:标准模式、怪异模式
标准模式:浏览器按照w3c标准解析代码
怪异模式:浏览器按照自己的方式去解析代码,因为每个浏览器都不一样,所以称为怪异模式
盒模型:
标准模式:标准盒子模型
宽度:content的宽度
外盒尺寸:width+padding *2+border *2+margin *2
元素宽度:width+padding *2+border *2+margin *2
怪异模式:IE盒子模型
宽度:content+border *2+padding *2
外盒尺寸:width+margin*2
元素宽度:width
图片元素的垂直对齐方式
对于inline元素和table-cell元素,标准模式下vertical-align属性默认取值是baseline;在怪异模式下,table单元格中的图片的vertical-align属性默认取值是bottom。因此在图片底部会有几像素的空间
元素中的字体
CSS中,对于font的属性都是可以继承的。怪异模式下,对于table元素,字体的某些元素将不会从body等其他封装元素继承中的得到,特别是font-size属性
内联元素的尺寸
标准模式下,inline元素无法自定义大小;
怪异模式下,定义这些元素的width、height属性可以影响这些元素显示的尺寸
元素的百分比高度
CSS中对于元素的百分比高度规定:百分比为元素包含块的高度,不可为负值;如果包含块的高度没有显示给出,该值等同于auto,所以百分比的高度必须是在元素有高度声明的情况下使用。
当一个元素使用百分比高度是,标准模式下,百分比高度被准确应用,怪异模式下,百分比高度被准确应用高度取决于内容变化
元素溢出的处理
标准模式下,overflow取值默认为visible;在怪异模式在,该溢出会被当做扩展box来对待,即元素的大小由内容决定,溢出不会裁剪,元素框自动调整,包含溢出内容
邮箱客户端多种多样,对HTML/CSS的支持也不一样,所以不能用高级的布局(flex,float,absolute等),需使用较初级的table以达到兼容性最好的效果
邮件模板不能用媒体查询,不能写script,不能写外联样式,可以先写外联,在通过一些工具生成对应的内联HTML
为了兼容移动端和pc端,应该设置最大宽度(比如最外面的table宽度100%,里面的table有一个max-width:600px,相对于外面的table居中。这样在PC上最大宽度就为600px,而在手机客户端上宽度就为100%)
不管是JS还是CSS,把缩进都调整成四个空格
每个属性名冒号后面要加一个空格
每个选择器前面也要加一个空格
多个选择器共用一个样式时,每个选择器独占一行
但是有一个特例,就是和时间有关的单位都要带上s
因为rgb是一个函数,他还要计算一下转化,透明的还要设置rgba
border:none 即说明不存在,页面不会渲染,即不会消耗内存值
border:0 页面会对其进行渲染,会占用内存
注意使用系统字体的对应的font-family名称,如SFUIText Font这个字体,在Safari是-apple-system,而在Chrome是BlinkMacSystemFont,所以font-family可以这么写
font-family{
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}
开发过程中很难统一,尽量保持自己的页面业务逻辑的z-index为各位数
比如margin-right,margin-left这些可以合并的属性,一般写成合并形式,让代码看起来更整洁
比如设置了浮动,目标元素就会具有块级盒模型的特点,即使设置display:inline也是没有用的,默认为display:block了
如果是display:flex,那么float将会被忽略
一般采用clearfix
.clearfix:after{
content:"";
display: table;
clear:both; //清除元素两端的浮动
}
但是如果字体名称刚好是关键字,就要加上双引号
font-family: "inherit", "serif", "sans-serif", "monospace", "fantasy", and "cursive"
一般来说可以不加,但是当url里面有特殊字符没有转义的话,就要加上双引号
background-url: url(//cdn.test.me/hello world.jpg)
所以一般我们都是要加上双引号,可以兼容
普遍推荐HTML写双引号,css写单引号
在不同浏览器下可能不太兼容,一般要用哪个属性做动画就用写那个,如果有多个那就隔开
transition: transform 2s linear,
opacity 2s linear;
能用transform做动画就不用left这些,因为transform不会造成重绘,性能比position高很多
一个页面从加载到完成,首先是构建DOM树,然后根据DOM节点的几何属性形成render树(渲染树),当渲染树构建完成,页面就根据DOM树开始布局了,渲染树也根据设置的样式对应的渲染这些节点。
在这个过程中,回流与DOM树,渲染树有关,重绘与渲染树有关
回流:比如我们增删DOM节点,修改一个元素的宽高,页面布局发生变化,DOM树结构发生变化,那么肯定要重新构建DOM树,而DOM树与渲染树是紧密相连的,DOM树构建完,渲染树也会随之对页面进行再次渲染
重绘:当你给一个元素更换颜色,这样的行为是不会影响页面布局的,DOM树不会变化,但颜色变了,渲染树得重新渲染页面
- DOM的增删行为:添加节点的时候,最好使用文档碎片的方式添加,减少回流
- 几何属性的变化:如果要改变多个几何属性,就将他们放入一个类中,然后通过添加类的方法添加属性,这样只引起一次回流
- 元素位置的改变:一般不修改margin和padding之类的操作,而是使用定位让其脱离文档流后改变位置
- 获取元素的偏移量属性:获取scrollTop之类的属性,浏览器为了获取准确值会重新回流一次
- 页面初次渲染:无法避免
- 浏览器窗口尺寸的变化:无法避免
DocumentFragment 表示一个没有父级文件的最小文档对象。它被当做一个轻量版的 Document 使用,用于存储已排好版的或尚未打理好格式的XML片段。最大的区别是因为DocumentFragment不是真实DOM树的一部分,它的变化不会引起DOM树的重新渲染的操作(reflow) ,且不会导致性能等问题
直接操作DOM:
使用DocumentFragment一次性添加:
使用文档碎片添加节点:
fragment = document.createDocumentFragment(); fragment.appendChild(document.createElement("li"));
hyphens:auto; //断词的属性,一般不用,因为断的不彻底
不在每一个图标里面都添加一个font-family:”icon-font“
而是设置一个类,相关的font-family都设置在这个类里面
修改各个浏览器的默认样式
https://tinypng.com/
如果是头图直接展示的图片则用img标签,可以设置alt增强SEO
如果是背景图就用background,可以设置background-position:center center
一般不杂合着使用rem,文字要么全用要么全不用
可以用来画页面上一些视觉上的辅助性元素,比如三角形,短竖线等
但是正常的文本元素就一般不用
absolute扩展性很差,性能好
float扩展性较好,但是性能相对较差
inline-block是行内元素,在里面添加块元素的话不合法,详见HTML规范中的第8点
UI给的图片一般是固定的,但是现实中图片的长宽不一,所以应该借助JS来拉伸图片
<div class="img-container"> <img src="test.jpg" alt onload="resizeImg(this, '400px', '300px')"></div>
可能会导致safari的光标变得很大,所以一般不用此方法垂直居中,而是使用padding
可以把行内元素撑开
建议布尔变量不用以is/do之类的开头
另外变量名不要使用否定的名词,如notOk,notReady,因为否定的词取反的时候就会比较奇怪,如if(!notOk). 要使用肯定的布尔变量名
不使用中文拼音
可以让人提前知道变量所表示的数据类型,也有利于JS解释器提前做一些优化处理
undefined表示未定义,而定义了一个变量又说未定义可能会造成歧义
我们经常使用undefined来判断变量是否定义
如果要赋值的值是空值,则对象赋null,数字赋NAN,字符串赋空字符串
函数的返回值也不要显式地return undefined
逗号后面带个空格
双目运算符中间两边都要带空格
一行一般不超过100个字符,太长了就换行
会带上类型转化,所以一般不用
要用===强类型进行判断
对一些比较重要的变量起一个名字
在全局作用域下,变量查找的时间会更长
会污染全局作用域,有时候会造成一些意想不到的结果
使用let的好处
- 避免变量重复定义
- for循环的变量作用域是独立的
const适合给常量取个名字,或者是定义一些不需要的变量防止被修改
比如进行大量的DOM操作,可以改用文档碎片进行操作
比如window.location这个属性被多次调用,就可以定义一个局部变量储存他,加快查找时间
在修改代码的适合比较麻烦,需要同时注意css和JS两个地方的代码
一般使用添加类的方式添加css样式
但是动态计算position的值这些只能用JS实现
添加非空判断提高代码的稳健性,告诉调用者传的为空就不用处理,也可以找出后台数据出错的地方
如果在对数组遍历时使用for in循环,并且循环对象的原型中添加了某个函数,那么遍历出来的元素会包含这个原型上添加的函数,导致遍历出现问题
所以一般使用forEach或map
可以不加,但是在开发过程中最好还是加上,不容易出错
对于那些根据用户输入内容做跳转,需要先把用户内容做转义,如下有问题的代码:
let searchContent = form.search.value.trim();window.location.href = `/search?key=${searchContent}`;
如果用户输入了一个#号如门牌号,将会导致#后面的内容当作锚点了,或者用户可能会输入一个空格。所以如果不确定内容的东西需要先encode转义一下,如下代码
let searchContent = encodeURIComponent(form.search.value.trim());window.location.href = `/search?key=${searchContent}`;
不利于SEO
跳转可以使用a标签去跳转,还可以控制是否打开新页面
移动端中也不用担心onclick是否延迟
Safari的隐身模式本地储存会被禁用,所以无法往localStorage写入数据
但是谷歌不会被禁用,所以应该做一个兼容,判断是否为隐身模式,是的话就用cookie,否的话则用localStorage
Data.hasLocalStorage = true;try{ window.localStorage.trySetData = 1;}catch(e){ Data.hasLocalStorage = false;}setLocalData: function(key, value){ if(Data.hasLocalStorage){ window.localStorage[key] = value; } else{ util.setCookie("_LOCAL_DATA_" + key, value, 1000); }},getLocalData: function(key){ if(Data.hasLocalStorage){ return window.localStorage[key]; } else{ return util.getCookie("_LOCAL_DATA_" + key); }}
+相当于Number
praseInt与Number最大的区别是praseInt可以将10px转化为10,而Number则转化为NAN
let _row = Math.floor(index / columns);let row = parseInt(index / columns);可以改写成:let row = index / columns >> 0;
在if判断里面为false的值:0、false、“”、undefined、null、NAN
所以可以直接用if(array.length){ }判断
但是判断一个变量有没有定义还是要写成:
if (typeof foo !== “undefined”) {} //防止上述的值被认为没有定义
将要添加或者要修改的属性放在一个对象里面,然后在将这个对象与原来的对象用assign合在一起
正则表达式可以很方便地处理字符串,通常只要一行代码就搞定了。例如去掉全局的某一个字符,如去掉电话号码的-连接符
phoneNumer = phoneNumber.replace(/\-/g, “”);
将一个大函数拆成多个小函数,让主函数的逻辑变得清晰
如果label里面有input时,监听label的事件会触发两次
<label> <input type="radio" name="fruit" value="apple"> <span>apple</span></label>
比如给label绑定一个点击事件,点击span时,label会触发input,input又会冒泡到label