- 写出一个符合W3C规范的HTML文件,要求
i. 页面标题为“我的页面”
ii. 页面中引入一个外部CSS文件,路径为/style.css
iii. 页面中引入另一个外部CSS文件,路径为/print.css
,该文件仅在在打印时生效
iv. 页面中引入了另一个外部CSS文件,路径为/mobile.css
,该文件仅在设备宽度小于500像素时生效
v. 页面中引入一个外部JS文件,路径为/main.js
vi. 页面中引入另一个外部JS文件,路径为/gbk.js
,文件编码为GBK
vii. 页面中有一个SVG标签,SVG里面有一个直径为100像素的圆圈,颜色随意
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./style.css">
<link rel="stylesheet" href="./print.css" media="print">
<link rel="stylesheet" href="./mobile.css" media="(max-width:500px)">
<script src="./main.js"></script>
<script src="./gbk.js" charset="gbk"></script>
<title>我的页面</title>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="100" r="50" stroke="red" fill="none">
</svg>
</body>
</html>
- 移动端是怎么做适配的?
回答要点:
i. meta viewport
ii. 媒体查询(参考CSS学习笔记)
ii. 动态rem方案(参考CSS学习笔记)
- 设置移动端自适应要添加meta标签,它可以防止手机页面模拟980像素宽度、防止用户缩放页面
<meta name="viewport" content="width=device-width,initial-scale=1.0">
- 通过媒体查询可以设置满足不同查询条件时,显示不同样式(用在style标签内或者link外部CSS文件都可以),所以可以根据手机页面宽度来调整对应CSS做适配,例如
//当屏幕宽度小于500px时,背景颜色变红
<style>
@media(max-width: 500px) {
body {
background: red;
}
}
</style>
//当屏幕宽度小于500px时,引入一个CSS文件
<link rel="stylesheet" media="(max-width:500px)" href="./style.css">
- 首先rem等于根元素的font-size,将根元素的font-size设置成viewport的宽度时,1rem==html font-size==viewport width,我们使用rem作为长度单位就可以将一切大小按视口宽度的比例呈现,所以移动端适配可以使用动态rem方式。为了不使小数太小,使用不便,让根元素font-size的十分之一作为1rem比较合适。以下两种方式可以实现动态rem:
i. js动态调整rem
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<script>
var pageWidth = window.innerWidth
document.write('<style>html {font-size:'+pageWidth/10+'px;}</style>')
</script>
ii. SCSS实现动态rem
在scss文件里添加如下代码,可以实现px自动变rem
@function px($px) {
@return $px/$designWidth*10 + rem;
}
$designWidth: 640;//设计稿宽度
.child{
width: px(320);
height: px(160);
margin: px(40) px(40);
border: 1px solid red;
float: left;
font-size: 1.2em;
}
小知识点:
- 在 SCSS 里使用 PX2REM
npm config set registry [https://registry.npm.taobao.org/](https://registry.npm.taobao.org/ "null")
touch ~/.bashrc
echo 'export >SASS_BINARY_SITE="[https://npm.taobao.org/mirrors/node-sass"'](https://npm.taobao.org/mirrors/node-sass%22' "null") >> ~/.bashrc
source ~/.bashrc
npm i -g node-sass
mkdir ~/Desktop/scss-demo
cd ~/Desktop/scss-demo
mkdir scss css
touch scss/style.scss
start scss/style.scss
node-sass -wr scss -o css
- 页面默认字体大小(font-size)为16px;Chrome有默认最小字号12px,设置比12px小的话也会自动变成12px。
- rem 可以与其他单位同时存在,像border、font-size这样很小的可以就用px而不用rem。
- CSS3如何实现圆角矩形和阴影?
- 圆角用
border-radius
属性
语法border-radius: 1-4 length|% / 1-4 length|%;
圆角的半径可以用(数值+单位)或百分比确定,值为4个时,分别表示左上角、右上角、右下角、左下角;值为3个时,分别表示左上角、右上角和左下角、右下角;值为2个时,分别表示左上角和右下角、右上角和左下角;值为1个时,四个角相同。 - 阴影用
box-shadow
属性
语法box-shadow: h-shadow v-shadow blur spread color inset;
值 | 含义 |
---|---|
h-shadow | 必选,水平阴影,可正负值。 |
v-shadow | 必选,垂直阴影,可正负值。 |
blur | 可选,模糊距离。 |
spread | 可选,阴影大小。 |
color | 可选阴影颜色。 |
inset | 可选,从外层阴影(开始时)改变阴影内侧阴影。 |
- 什么是闭包?闭包的用途?
- 如果一个函数用到了它范围外的变量,那么这个函数+这个变量就叫闭包。(芳芳的定义)
- 闭包就是能够读取其他函数内部变量的函数,在JavaScript中就是“定义在一个函数内部的子函数”,是连接函数内部和外部的桥梁。(阮一峰的定义)
- 闭包的用途:一是可以读取函数内部的变量;二是记住诞生环境,让这些变量始终保持在内存中;三是封装对象的私有属性和私有方法。
示例1-读取函数内部变量
function f1() { var n = 900 function f2() { console.log(n) } return f2 } var result = f1() result()//900
示例2-保留外层函数的内部变量
function createIncrementor(start) { return function() { return start+=1 } } var inc = createIncrementor(5) console.log(inc())//6 console.log(inc())//7 console.log(inc())//8,每一次调用都是在上一次调用的基础上进行计算
示例3-封装对象的私有属性和私有方法
function Person(name) { var age function setAge(n) { age = n } function getAge() { return age } return { name: name, setAge: setAge, getAge: getAge } } var p1 = Person('Jack') p1.setAge(18) p1.getAge() console.log(p1.getAge())//18 //函数Person的内部变量age通过闭包getAge和setAge,变成返回对象p1的私有变量。
- call、apply、bind的用法是什么?
- JavaScript提供call、apply、bind三个方法来切换/固定this的指向。
- call方法可以指定函数内部this的指向(即函数执行时所在的作用域),然后在指定的作用域种调用该函数。
var obj = {}
var f = function () {
return this
}
f(obj) === window//true
f.call(obj) === obj//true
call方法的参数应该是个对象,如果为空、null、undefined则默认传入全局对象,如果是一个原始值,会自动转成对应的包装对象再传入call。
- apply与call非常相似,不同之处在于提供参数方式,call()使用的是若干个参数的列表,而apply()使用的是一个包含若干参数的数组(或类数组对象)
- bind方法用于将函数体内的this绑定到某个对象,然后返回一个新函数。
//创建绑定函数
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 返回 81
var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域
// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81
bind()的用法还有以下:
i. 使一个函数拥有预设的初始参数,初始参数在this之后,且在传入参数之前的位置。
ii. 配合set Timeout。
iii. 快捷调用。例如将类数组对象转换成真正的数组:
// 1.使用apply方法
function fun1() {
var slice = Array.prototype.slice;
return slice.apply(arguments);
}
fun1(1,2,3);//[1,2,3]
// 2.使用call(或apply)和bind方法一起
function fun2() {
var unboundSlice = Array.prototype.slice;
// 把函数的call方法绑定在数组slice方法上,之后再给call方法传递参数,这里call换成apply也可以。
var slice = Function.prototype.call.bind(unboundSlice);
return slice(arguments);
}
fun2(1,2,3);//[1,2,3]
- 有哪些HTTP状态码和意义?
状态码 | 含义 |
---|---|
1xx | 不常用 |
200 | 请求成功,请求所希望的响应头或数据体会随此响应返回。 |
204 | 服务器成功处理了请求,但不需要返回任何实体内容。 |
301 | 被请求资源已永久移动到新位置 |
302 | 请求资源临时搬到新的位置 |
400 | 1.语义有误,当前请求无法被服务器理解;2.请求参数有误。 |
401 | 当前请求需要用户验证。 |
403 | 服务器已经理解请求,但拒绝执行。 |
404 | 请求失败,请求资源未在服务器上发现。 |
500 | 服务器出错,无法处理请求。 |
503 | 临时性服务器维护或过载,无法处理请求。 |
- 写出一个HTTP post请求的内容,包括四部分。
其中
i. 第四部分的内容是username=ff&password=123
ii. 第二部分必须包含Content-Type字段
iii. 请求的路径为/path
curl -X POST -d "username=ff&password=123" -s -v -- "http://www.baidu.com"
POST /path HTTP/1.1
Host: www.baidu.com
User-Agent: curl/7.55.0
Accept: /
Content-Length: 24
Content-Type: application/x-www-form-urlencodedusername=ff&password=123
- 说出至少三种排序的思路,这三种排序的时间复杂度分别为O(n*n)、O(n log2 n)、O(n+max)
- 时间复杂度O(n*n),冒泡排序、插入排序
冒泡排序思路:假设是要从小到大排序,就将要排序的数组,从下标0的数开始往后比较相邻的两个数,小的放前面、大的放后面,一轮下来最大的数就冒到最后面了,接下来每轮继续重复比较和换序,除了后面已确定位置的数,直到没有需要比较的数为止,也是轮数为(数组长度-1)轮为止。 - 时间复杂度O(n log2 n),快速排序、堆排序
快速排序思路:假设是要从小到大排序,在要排序的数组中任意选一个数,将其他所有数与这个数比较,小的都放其前面,大的都放其后面,再分别在这两部分中采用同样方法进行排序,直到每个部分都没有数可以比较 - 时间复杂度O(n+max),基数排序:
基数排序思路:准备10个桶,编号0,1,2...9,按个位数分配入桶(个位数为0的进0号桶,个位数为1的进1号桶),全部入桶后按桶的编号依次取出(同一个桶先入的数先取出),完成一趟排序,接着依次按十位数、百位数逐步到最高位的数字重复以上分配入桶、取出步骤(没有高位的该位数视为0)。 - 排序可视化:https://visualgo.net/bn/sorting
- 一个页面从输入URL到页面加载显示完成,这个过程中都发生了什么?
- i. 分析URL。URL包括几个部分:协议、网络地址、资源路径;协议是网络数据交换的规则、标准或约定的集合,譬如HTTP、FTP协议;网络地址可以是域名或者IP地址,可以包括端口号。
ii. 域名解析。如果地址不是IP地址,通过DNS进行域名解析,将域名解析成对应的IP地址。解析过程:浏览器搜索自己的DNS缓存——>搜索操作系统种的DNS缓存——>搜索操作系统的hosts文件——>发送域名到本地域名服务器查询——>向根域名服务器查询——> 向顶级域名服务器查询,找到IP地址返回给浏览器,浏览器将IP地址缓存。
iii. 如果地址不包含端口号,根据协议确定一个默认端口,譬如HTTP默认80端口。
iv. 建立连接。向获得的IP地址的端口建立连接——三次握手:
(1)主机向服务器发送建立连接的请求;
(2)服务器收到请求后发送同意连接的信号;
(3)主机收到同意连接信号后,再次向服务器发送确认信号;建立连接。
v. 浏览器发起HTTP请求。HTTP请求包括请求方法、资源路径、协议/版本、相关内容等。
vi. 服务器接收并返回响应。HTTP响应包括协议/版本、状态码、状态解释、要下载的内容等。
vii. 浏览器下载相应内容,渲染、显示页面。
viii. 断开连接——四次挥手:
(1)主机向服务器发送断开连接的请求;
(2)服务器收到请求后发送同意断开的信号;
(3)服务器向主机发送断开通知;
(3)主机收到断开通知后,断开连接,并再次向服务器发送确认信号,服务器收到信号后断开连接。
IP地址:IP协议为互联网上的每个网络和每台主机分配的一个逻辑地址,相当于门牌号。
DN域名:IP地址由四个数字组成,中间有点号连接,比较难记容易输错,所以用有意义的字母、数字组合代替纯数字IP,这个就叫域名。例如百度域名www.baidu.com,比它的IP220.181.112.224好记很多。
DNS域名系统:每个域名对应一个或多个提供相同服务器的IP地址,只有知道服务器IP地址才能建立连接,这就需要DNS把域名解析成IP地址。
- 如何实现数组去重?
假设有数组array=[1,5,2,3,4,2,3,1,3,4],写出一个函数unique,使得unique(array)的值为[1,5,2,3,4]。要求:
i. 不要做多重循环,只能遍历一次
ii. 请给出两种方案,一种能在ES5环境中运行,一种能在ES6环境中运行(提示:ES6环境中多了一个Set对象)
//ES5中
function unique(array) {
var newArray = []
var hash = {}
for(var i = 0;i < array.length;i++) {
if(!hash[array[i]]) {
newArray.push(array[i])
hash[array[i]] = 1
}
}
return newArray
}
var array = [1,5,2,3,4,2,3,1,3,4]
console.log(unique(array))
//ES6中
function unique(array) {
return [...new Set(array)]
}
var array = [1,5,2,3,4,2,3,1,3,4]
console.log(unique(array))
网友评论