深入了解html、css以及javascript

712 阅读12分钟

前言

        首先说下这篇讲的比较杂,包括html、css和javascript都会有涉猎,所以还是请各位大大见谅,有的可能比较基础但是很大一部分是比较深入的内容的,也请各位大大批评指正,谢谢了。

正文

html部分

        好了开始正文部分,首先讲讲html。

1. title与h1的区别、b与strong的区别、i与em的区别

        首先谈谈title与h1的区别、关于title状语从句:h1,title是网页的标题。主要面向的对象是搜索引擎和通过搜索结果过来的人(面向外人,可以理解为报纸首页的标题)。而h1是网页内部的标题,是给已经进到页面的人看的(可以理解为报纸某个版面的大标题)。从人类的语境上来理解,两者并没有差别。

        其次谈谈b与strong的区别,b与strong的效果人眼上是无法区分的。在语义上,仅b表示加粗既装饰用,我们应该使用CSS而不应该使用b;而strong则表示被包围的内容很重要,是语气上的感觉。对于搜索引擎来说,会把b状语从句:strong视为同一含义。因此我们在使用上需要注意。

        最后谈谈i与em之间的区别,i与em的区别类似b和strong的区别。i用于斜体展示,我们应该使用CSS而不应该使用i;而em则是对内容的强调,但程度没有strong那么高。同样,对搜索引擎来说,两者是没有区别的。

2. 元素的alt和title有什么区别?

        首先是ALT属性,最常见用在 < img > 标签上,那我们先来看下 < img > 标签的 alt 属性。
alt 属性是一个必需的属性,它规定在图像无法显示时的替代文本。
假设由于下列原因用户无法查看图像,alt 属性可以为图像提供替代的信息:
网速太慢
src 属性中的错误
浏览器禁用图像
用户使用的是屏幕阅读器
< img > 标签的 alt 属性指定了替代文本,用于在图像无法显示或者用户禁用图像显示时,代替图像显示在浏览器中的内容。
强烈推荐您在文档的每个图像中都使用这个属性。这样即使图像无法显示,用户还是可以看到关于丢失了什么东西的一些信息。而且对于残疾人来说,alt 属性通常是他们了解图像内容的唯一方式。

        其次是 TITLE 属性

        定义和用法:
title 属性规定关于元素的额外信息。
这些信息通常会在鼠标移到元素上时显示一段工具提示文本(tooltip text)。
提示:title 属性常与 form 以及 a元素一同使用,以提供关于输入格式和链接目标的信息。同时它也是 abbr 和 acronym 元素的必需属性。当然 title 属性是比较广泛使用的,可以用在除了base,basefont,head,html,meta,param,script 和 title 之外的所有标签。但是并不是必须的。
title 属性有一个很好的用途,即为链接添加描述性文字,特别是当连接本身并不是十分清楚的表达了链接的目的。这样就使得访问者知道那些链接将会带他们到什么地方,他们就不会加载一个可能完全不感兴趣的页面。另外一个潜在的应用就是为图像提供额外的说明信息,比如日期或者其他非本质的信息。

3. 表的作用和优缺点是什么?

        table 用于表格数据的展示,并且很符合人们的直观认知。
在div+ css布局流行之前,普遍使用table进行布局。曾经的神器Dreamweaver的可视化拖拖table也是基于布局。
table布局的好处在于样式好控制,特别是居中,对齐。缺点在于会多处非常多的DOM节点(想想一个td里面再来一个table),会导致页面加载变慢,不table利于SEO(原本就不是用来布局的,也因此,在CSS成熟之后,table布局马上就变成历史了。

4. html中的置换元素和非置换元素的理解?

        置换元素的定义如下:
一个 内容 不受 CSS 视觉格式化模型控制,CSS 渲染模型并不考虑对此内容的渲染,且元素本身一般拥有固有尺寸(宽度,高度,宽高比)的元素,被称之为置换元素。
一般来说 span 这种行内非置换元素设置宽高是没有意义的,除非修改 display: inline-block。对于行内置换元素,是可以设置宽高的。比如常用的 img 标签自适应图片时,我们只需要定义一个宽或者高,剩下的就会自动帮我们计算。

5. js放在html的和有什么区别?

        js放在< head >中,如果不添加async或者defer时,当浏览器script遇到时,会阻塞DOM树的构建,进而影响页面的加载。当js文件较多时,页面白屏的时间也会变长。
在这个过程中,如果解析器遇到了一个脚本(script),它就会停下来, 并且执行这个脚本,然后才会继续解析HTML。如果遇到了一个引用外部资源的脚本(script),它就必须须停下来等待这个脚本资源的下载,而这个行为会导致一个或者多个的网络往返,并且会延迟页面的首次渲染时间。
把js放到< body >里(一般在< /body >的上面)时,由于DOM时序序解析的,因此js不会阻塞DOM的解析。对于必须要在DOM解析前就要加载的js,我们需要放在< head >中。

css部分

  1. style标签写在body前和body后的区别是什么?

        在 HTML4 的时候,不应该把 style 放到 body 中间。
浏览器在渲染页面时 DOM 和 CSSOM 是并行的,然后两者结合形成 Render Tree 显示页面。从直觉上来说,style 写在 body 前不会对 DOM 的渲染进行阻塞;而写在 body 内会对 DOM 渲染进行阻塞。会产生 FOUC(Flash of Unstyled Content) 的现象,既一瞬间的白屏或者样式的突然变化(原因是 Render Tree 重新生成了)。
不过 W3C 在 HTML5.2 的定义中对于 style 标签的使用的定义中是允许将 style 放到 body 中的。
Contexts in which this element can be used:
Where metadata content is expected.
In a noscript element that is a child of a head element.
In the body, where flow content is expected.

7. margin边界叠加是什么及解决方案

        1,使用填充代替,但是父盒子要减去相应的高度
        2,使用boder (透明)代替(不推荐,不符合书写规范,如果父盒子子盒子时有颜色的不好处理)
        3,给父盒子设置overflow:hidden(如果有移除元素无法使用)
        4,给父盒子设置1px的padding
        5,给父盒子设置1px的透明border,高度减1px
        6,子盒子使用定位position
        7,子盒子浮动,但是居中比较难以控制
        8,给子盒子设置display:inline-block;
        9,子盒子上面放一个表标签

8. CSS sprites的原理和优缺点分别是什么?

        原理:多张小图标合并成一张图片,利用background-position来显示相对应的图标
优点:请求数量少,预先加载图标
缺点:难管理,资源大

9. 什么是FOUC?如何避免FOUC的?

        FOUC即Flash of Unstyled Content,是指页面一开始以样式A(或无样式)的渲染,突然变成样式B. 原因是样式表的晚于HTML加载导致页面重新进行绘制。
通过@import方式导入样式表
style标签在body中
解决方法:把link标签将样式放在head中

10. 要让Chrome支持小于12px的文字怎么做?

        Chrome中有最小字号的限制,一般为12px。原因是Chrome认为小于这个字号会影响阅读。
当需要小于12px字体的时候,有以下几个方法可以使用。
-webkit-文字大小调整:无; 这个属性在高版本的Chrome中已经被废除。
使用transform: scale(0.5, 0.5),使用但transform需要注意下面几点:
transform对行内元素无效,因此使用要么display: block;要么使用display: inline-block;
transform 即使进行了缩放,原来元素还是会占据对应的位置。因此需要做调整,最好是在外面再包一层元素,以免影响其他元素。
作为图片。
最好的办法还是进行切图,或者就不要使用小于12px的字体。

11. 说说浏览器解析CSS选择器的过程?

        浏览器解析CSS选择器的顺序是从右到左的,而不是直观上的从左到右。
之所以是从右到左,是因为选择器一般也是有规律的,一般选择器的最右边是最宽泛的,比如div标签等,而选择器的最左边一般是最具体的,比如属性等。所以从最左边开始解析有助于能一开始就快速的判断出大部分标签是否是潜在的符合要求的目标

js部分

  1. 写一个数组去重的方法

        这是我之前写的一个例子。

var arrys = []
function arrs(arr) { // 先把所有的提出来
    for (var i = 0; i < arr.length; i++) {
        if (Array.isArray(arr[i]) === true) {
            arrs(arr[i])
        } else {
        arrys.push(arr[i])
        }
    }
}
function Arrys(arr, arrys) { // 之后去重
    arrs(arr)
    return [...new Set(arrys)]
}
Arrys([1, 2, 3, 4, 4, 3, 2, 1, [1, 2, 3, 5, [5, 4, 3, 2, 1]]], arrys)

        这个方法比较笨的,但是挺管用的,大家可以试试。

13. 返回到顶部的方法有哪些?

        前几天写的跳转页面后jquery的锚点方法

function getUrlParam(name) {
  var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
  var r = window.location.search.substr(1).match(reg);  //匹配目标参数
  if (r != null) return unescape(r[2]); return null; //返回参数值
}
var abouts = getUrlParam("about")
if (abouts == "about") {
  $("html,body").animate({scrollTop:$("#about").offset().top},1000);
}
  1. typeof('abc')和typeof 'abc'都是string, 那么typeof是操作符还是函数?

        typeof 是操作符,不是函数。可以添加括号,但是括号的作用是进行分组而非函数的调用

15. "attribute"和"property"有什么不同?

        在操作 DOM 时,我们经常会操作 attribute 和 property。不过从两者的所属关系上来说: property 属于 DOM Object,而 atrribute 属于 HTML。
property 通常比较容易获取,并且有固定的值(当然,类似 JavaScript 的对象,我们可以添加自定义的值,只是这些不会被 DOM 所认识)。比如 el.id、el.value、el.style 都是 property 而设置也只需要 el.id=newId 即可。attribute 的值不是固定的,我们可以自己为 DOM 添加需要的属性(以前常常用来存放数据或者标志位,在 HTML5 有了 data-* 的属性后,一般就利用 data-* 来存放数据了)。对于 attribute 的设定和获取我们使用 setAttribute 和 getAttribute 两个方法。
在书写方面 property 对于大小写敏感;而 attribute 对于大小写不敏感。
总的来看 property 的值更偏向于标准而 attribute 的值更偏向于自定义和非标准。

16. new操作符的理解是什么?手动实现一个new方法

        构造函数:

        先准备一个构造函数来new使用。

function constructorFunction(name, age){
  this.name = name;
  this.age = age;
}
constructorFunction.prototype.say = function(){
  return 'Hello '+ this.name
}

        原生new:

var obj = new constructorFunction('willian', 18)
console.log(obj.name, obj.age);//'willian', 18
console.log(obj.say())//Hello willian

        模拟new

        模拟的new 暂称为newNew (囡..囡 哈哈~)
使用:newNew(constructor, arg1, arg2, ..)
第0个参数传入构造函数,1~n个参数是构造函数的形参。
使用上面的构造函数试一下:

function newNew(){
 var newObj = {}
 // 1. 创建一个新对象
 var Con = [].shift.call(arguments)
 // 得到构造函数
 newObj.__proto__ = Con.prototype;
 // 2. 把新对象的原型指向构造函数的prototype
 var res = Con.apply(newObj, arguments)
 // 3. 把构造函数里的this指向新对象
 return typeof res === 'object' ? res : newObj;
 // 4. 返回新对象
}
var obj = newNew(constructorFunction, 'willian', 18)
console.log(obj.name, obj.age);//'willian', 18
console.log(obj.say())//Hello willian

        得到和new 一样的答案,说明模拟成功。
你也可以F12 打开控制台试一试。

结语

        通过这次深入了解html、css、javascript的一些常规使用方式,有些呢是我们日常工作中常用的,都很有用,有些呢是面试会问到的,在这里呢还是要感谢《前端面试每日 3+1(每日三问)》这个代码仓库提供了这些优质的问题,要不然也不会有这期的文章了。

        另外再次安利一下《前端面试每日 3+1(每日三问)》:

        github.com/haizlin/fe-…

        另外各位大大有啥问题欢迎在评论区留言,大家一起讨论。

        下一期有可能会讲一些es6深入的知识或者增加些算法的讲解,暂定就是这样。感谢观看。