面试题四(6道)

目录

    • 1. iframe框架都有哪些优缺点
        • 优点:
        • 缺点:
    • 2. 简述你对BFC规范的理解
      • 介绍:
      • 形成条件(任意一条)
      • 特性
      • 应用场景
    • 3. 统计某一字符或字符串在另一个字符串中出现的次数
      • 方法一:
      • 方法二:
    • 4. 简述下html5的离线储存原理,同时说明如何使用?
      • 原理:
      • 如何使用:
      • 离线存储的manifest一般由三个部分组成:
      • 浏览器如何对离线存储的资源进行管理和加载:
      • 注意:
      • 更新缓存的三种方式:
      • 原文链接
    • 5. 清除浮动的方式有哪些及优缺点?
      • 伪元素清浮动:
      • 原文链接
    • 6. 写一个加密字符串的方法
      • 方法一,加密:
      • 方法一,解密:
      • 原文链接
      • 方法二:

1. iframe框架都有哪些优缺点


优点:

  • 可以实现异步刷新,单个 iframe 刷新不影响整体窗口的刷新(可以实现无刷新上传,在 FormData 无法使用时)
  • 可以实现跨域,每个 iframe 的源都可以不相同(方便引入第三方内容)
  • 多页面应用时,对于共同的 header, footer 可以使用 iframe 加载,拆分代码(导航栏的应用)

缺点:

  • 每一个 iframe 都对应着一个页面,也就意味着多余的 css, js 文件的载入,会增加请求的开销
  • 如果 iframe 内还有滚动条,会严重影响用户体验
  • window.onload 事件会在所有 iframe 加载完成后才触发,因此会造成页面阻塞

2. 简述你对BFC规范的理解


介绍:

  • BFC是CSS中的一个渲染机制,BFC就相当于一个盒子,内部的元素与外界的元素互不干扰。它不会影响外部的布局,外部的布局也不会影响到它。

形成条件(任意一条)

  • html 根元素
  • float的值不是none
  • position 的值不是static或者relative
  • display的值是inline-block,table-cell,flex,table-caption或者inline-flex
  • overflow的值不是visible

特性

  • 内部的盒子会在垂直方向上一个接一个的放置
  • 对于同一个BFC的俩个相邻的盒子的margin会发生重叠,与方向无关。
  • 每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此
  • BFC的区域不会与float的元素区域重叠
  • 计算BFC的高度时,浮动子元素也参与计算
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然

应用场景

  • 解决浮动子元素导致父元素,高度坍塌的问题
  • 解决文字环绕在float 四周的情况
  • 解决边距重叠问题 (父子,兄弟,空元素等)

3. 统计某一字符或字符串在另一个字符串中出现的次数


方法一:

var parent = 'aaasdsd'
var childInNums = parent.split('a').length - 1
console.log(childInNums);

面试题四(6道)_第1张图片

方法二:

function strCount(str, target) {
     
    let count = 0
    if (!target) return count
    while (str.match(target)) {
     
        str = str.replace(target, '')
        count++
    }
    return count
}
console.log(strCount('abcdef abcdef a', 'abc'))

面试题四(6道)_第2张图片

4. 简述下html5的离线储存原理,同时说明如何使用?


原理:

HTML5的离线存储是基于一个新建的.appcache文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示。

如何使用:

① 页面头部像下面一样加入一个manifest的属性。









	...



html>

② 在cache.manifest文件的编写离线存储的资源。

CACHE MANIFEST
    	#v0.1
    	CACHE:
   	 		js/index.js
    		css/index.css
    	NETWORK:
    		images/logo.png
    	FALLBACK:
    		*.html /404.html /* / /404.html 或 /html/ /404.html 也可*/

以#号开头的是注释,一般会在第二行写个版本号,用来在缓存的文件更新时,更新manifest以实现浏览器重新下载新的文件,可以是版本号,时间戳或md5码等。

离线存储的manifest一般由三个部分组成:

① CACHE:必选,表示需要离线存储的资源列表,由于包含manifest文件的页面将被自动离线存储,所以不需要把页面自身也列出来。

② NETWORK:可选,可以使用通配符,表示在它下面列出来的资源只有在在线的情况下才能访问,他们不会被离线存储,所以在离线情况下无法使用这些资源。不过,如果在CACHE和NETWORK中有一个相同的资源,那么这个资源还是会被离线存储,也就是说CACHE的优先级更高。

③ FALLBACK:可选,表示如果访问第一个资源失败,那么就使用第二个资源来替换他,如/html/ /404.html表示用 “404.html” 替代 /html/ 目录中的所有文件,/ /404.html表示用 “404.html” 替代当前目录中的所有文件,*.html /404.html表示用 “404.html” 替代 所有html文件。

浏览器如何对离线存储的资源进行管理和加载:

① 在线的情况下,浏览器发现html头部有manifest属性,它会请求manifest文件,如果是第一次访问app,那么浏览器就会根据manifest文件的内容下载相应的资源并且进行离线存储。如果已经访问过app并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的manifest文件与旧的manifest文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储。

② 离线的情况下,浏览器就直接使用离线存储的资源。

注意:

① 引用manifest的html必须与manifest文件同源,在同一个域下,FALLBACK中的资源也必须和manifest文件同源。

② 站点中的其他页面即使没有设置manifest属性,请求的资源如果在缓存中也从缓存中访问。

③ 如果服务器对离线的资源进行了更新,那么必须更新manifest文件(如更新manifest的版本等)之后这些资源才能被浏览器重新下载,如果只是更新了资源而没有更新manifest文件的话,浏览器并不会重新下载资源,也就是说还是使用原来离线存储的资源。

④ 浏览器在下载manifest文件中的资源的时候,它会一次性下载所有资源,如果某个资源由于某种原因下载失败,那么这次的所有更新就算是失败的,浏览器还是会使用原来的资源。

⑤ 更新了资源后,新的资源要到下次再访问网页时才会生效,出现这种现象的原因是浏览器会先使用离线资源加载页面,再去检查manifest是否有更新,所以要到下次打开页面才能生效。如果需要资源马上就能生效,那么可以使用window.applicationCache.swapCache()方法来使之生效。

更新缓存的三种方式:

① 更新manifest文件

1)给manifest添加或删除文件。

2)若manifest没有添加或删除文件,只是修改了文件,可以通过更改版本号等更新manifest文件。

② 通过javascript操作

html5中引入了js操作离线缓存的方法:window.applicationCache.update(),可以手动更新缓存。

③ 清除浏览器缓存

如果用户清除了浏览器缓存(手动或用其他一些工具),都会重新下载文件。

原文链接

5. 清除浮动的方式有哪些及优缺点?


伪元素清浮动:

/* 伪元素清浮动 */
.clear::after {
     
    content: '';
    display: block;
    clear: both;
}

什么是盒子塌陷?
外部盒子本应该包裹住内部的浮动盒子,结果却没有。

问题出现的原因
父元素只包含浮动元素,那么它的高度就会塌缩为零(前提就是你们没有设置高度(height)属性,或者设置了为auto,就会出现这种情况,如果父元素不包含任何的可见背景,这个问题会很难被注意到。
因为子元素设置了float属性,而float属性会把元素从标准文档流中抽离,直接结果就是外部盒子丢了两个孩子,因为内部没有其它盒子了,所以外部盒子只包裹文本节点内容,却把两个内部盒子扔在外面了。

解决方案

  1. 上面分析了问题出现的原因,不难找到第一种解决方案(既然孩子丢了,那就去找呗)——给外部盒子也添加浮动

    把外部盒子也从标准文档流中抽离,让它和孩子们见面。
    缺点:可读性差,不易于维护(别人很难理解为什么要给父元素也添上float),而且可能需要调整整个页面布局。

  2. 在外部盒子内最下方添上带clear属性的空盒子

    可以是div也可以是其它块级元素,把

    放在盒内底部,用最下面的空盒子清除浮动,把盒子重新撑起来。
    缺点:引入了冗余元素

  3. 用overflow:hidden清除浮动
    给外部盒子添上这个属性就好了,非常简单。
    缺点:有可能造成溢出元素不可见,影响展示效果。

  4. 用after伪元素清除浮动
    给外部盒子的after伪元素设置clear属性,再隐藏它
    这其实是对空盒子方案的改进,一种纯CSS的解决方案,不用引入冗余元素。

.clearfix {
     *zoom: 1;}
.clearfix:before,.clearfix:after {
     display: table;line-height: 0;content: "";}
.clearfix:after {
     clear: both;}123

这也是bootstrap框架采用的清除浮动的方法。

题外话

其实还有一种最直接的办法:给每个盒子规定width和height,要多大给多大即可。但这并不算什么解决方案,因为这样的布局不是内容自适应的,但如果页面内容极少发生变动,这也是一个不错的方案,因为它的兼容性是毋庸置疑的。

原文链接

6. 写一个加密字符串的方法


方法一,加密:

function encodeStr(str) {
     
    if (!str) return;

    var random = function (lower, upper) {
     
        return Math.floor(Math.random() * (upper - lower + 1)) + lower;
    };

    var arr = str.toString().split("").map(function (item) {
     
        return item.charCodeAt(0).toString(8)
    });

    arr.reverse(); //反序数组
    arr = arr.join("_").split(""); //暂时使用 _ 分割字符串;
    var num = 0;
    while (num < str.length) {
     
        var r = String.fromCharCode(random(97, 122)); //生成用于混淆的  的 小写字母
        arr.splice(random(0, arr.length), 0, r);
        num++;
    }
    return arr.join("").replace(/_/ig, function (str) {
     
        return String.fromCharCode(random(65, 90));
    }); //将分割符 _ 替换为随机的 大写字母

}

方法一,解密:

function decodeStr(str) {
     
    if (!str) return;
    var temp = [];
    str.split("").forEach(function (item) {
     
        var code = item.charCodeAt(0);
        if (code <= 90 && code >= 65) {
     
            item = "_"; //将作为分割用的 随机大写字母 统一为 _  以便切割
            temp.push(item);
        } else if (code <= 57 && code >= 48) {
     
            temp.push(item); //提取 数字
        }
    });
    temp = temp.join("").split("_");
    temp.reverse();
    var res = temp.map(function (item) {
     
        return String.fromCharCode(parseInt(item, 8));
    });

    return res.join("");

}

面试题四(6道)_第3张图片

特点:
每次生成的密文都不一样,解密后的文本一致

加密:
将字符串中的字符拆分成数组并将每个字符元素转为他的八进制Unicode码->反序->分割字符串->在字符串中随机加入小写字母->将分割符替换为随机大写字母

这样最终生成了 由数字/小写字母/大写字母 构成的随机密文

解密:
去掉小写字母->将大写字母替换成一个统一分割符并用分割符拆分字符串为数组->反序->将八进制Unicode码转字符串->将数组合并成字符串

使用场景:

隐藏一些不想让用户直接看见的参数, 比如 url中的 id 等参数,cookies中的信息等

生活使用:
也可将自己常用的密码加密后保存在电脑上,避免密码被直接暴露.

原文链接

方法二:

// 利用 base64, 浏览器环境自带 btoa / atob 方法
// Node.js 需要引入相关库
const str = "abcdefg";

// console.log(btoa(str));
// console.log(atob(btoa(str)));

// 凯撒密码
const encodeCaesar = ({
     
        str = "",
        padding = 3
    }) =>
    !str ? str : str.split("").map((s) => String.fromCharCode(s.charCodeAt() + padding)).join("");

const decodeCaesar = ({
     
        str = "",
        padding = 3
    }) =>
    !str ? str : str.split("").map((s) => String.fromCharCode(s.charCodeAt() - padding)).join("");

    console.log(encodeCaesar({
     
        str: "hello world"
    }));
    console.log(decodeCaesar({
     
        str: "khoor#zruog"
}));

面试题四(6道)_第4张图片

你可能感兴趣的:(面试题,javascript)