Mr. Panda
Tech For Fun

前端面试题集锦(4)

temp-or8

1. 你能描述一下渐进增强和优雅降级之间的不同吗?

 

优雅降级Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工作。由于IE独特的盒模型布局问题,针对不同版本的IE的hack实践过优雅降级了,为那些无法支持功能的浏览器增加候选方案,使之在旧式浏览器上以某种形式降级体验却不至于完全失效.

渐进增强:从被所有浏览器支持的基本功能开始,逐步地添加那些只有新式浏览器才支持的功能,向页面增加无害于基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用。


2. 线程与进程的区别

 

(1)一个程序至少有一个进程,一个进程至少有一个线程。线程的划分尺度小于进程,使得多线程程序的并发性高

(2)另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率

(3)线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制

(4)从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。


3. 说说你对语义化的理解?

 

①去掉或者丢失样式的时候能够让页面呈现出清晰的结构

有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息;爬虫依赖于标签来确定上下文和各个关键字的权重

方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页;PDA、手机等设备可能无法像普通电脑的浏览器一样来渲染网页(通常是因为这些设备对 CSS 的支持较弱)。

④便于团队开发和维护,语义化更具可读性,是下一步吧网页的重要动向,遵循W3C标准的团队都遵循这个标准,可以减少差异化。


4. 你如何对网站的文件和资源进行优化?

 

文件合并文件最小化 / 文件压缩使用 CDN 托管缓存的使用(多个域名来提供缓存)其他。


5. 为什么利用多个域名来提供网站资源会更有效?

 

1.CDN 缓存更方便

2. 突破浏览器并发限制一般每个域名建立的链接不超过 6 个

3.Cookieless,节省带宽(可以节约用户上行和服务器下行的带宽),尤其是上行带宽一般比下行要慢。参考:cookieless domain

4. 对于 UGC 的内容和主站隔离防止不必要的安全问题 (上传 js 窃取主站 cookie 之类的)。正是这个原因要求用户内容的域名必须不是自己主站的子域名,而是一个完全独立的第三方域名。

5. 数据做了划分,-+切到了不同的物理集群,通过子域名来分流比较省事。这个可能被用的不多。

 

PS: 关于 Cookie 的问题,带宽是次要的,安全隔离才是主要的。关于多域名,也不是越多越好,虽然服务器端可以做泛解释浏览器做 dns 解释也是耗时间的,而且太多域名,如果要走 https 的话,还有要多买证书和部署的问题。


6. 请说出三种减少页面加载时间的方法。(加载时间指感知的时间或者实际加载时间)

 

1. 优化图片

2. 图像格式的选择(GIF:提供的颜色较少,可用在一些对颜色要求不高的地方)

3. 优化 CSS(压缩合并 css,如 margin-top,margin-left...)

4. 网址后加斜杠(如 www.campr.com / 目录,会判断这个 “目录是什么文件类型,或者是目录。)

5. 标明高度和宽度如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小,如果图片很多,浏览器需要不断地调整页面。这不但影响速度,也影响浏览体验。当浏览器知道了高度和宽度参数后,即使图片暂时无法显示,页面上也会腾出图片的空位,然后继续加载后面的内容。从而加载时间快了,浏览体验也更好了。)

6. 减少 http 请求(合并文件,合并图片)。


7. 如果你参与到一个项目中,发现他们使用 Tab 来缩进代码,但是你喜欢空格,你会怎么做?

 

(1)建议这个项目使用像 EditorConfig之类的规范。参考:editorConfig 编辑器配置;

(2)为了保持一致性,接受项目原有的风格(项目已经进行);

(3)直接使用 VIM 的 retab 命令

详细:

(1) EditorConfig帮助开发者定义和维护代码风格,包含一个用于定义代码格式的文件和一批编辑器插件,这些插件是让编辑器读取配置文件并以此来格式化代码。


8. 请写一个简单的幻灯效果页面

用CSS实现一个简单的幻灯片效果页面:

方法一:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css">
        .myDiv {
            width:300px;
            height: 300px;
            margin: 20px auto;
            -webkit-animation-name: 'loop';
            -webkit-animation-duration: 10s;
            -webkit-animation-iteration-count: infinite;
        }
        @-webkit-keyframes "loop"{
            0% { background: url("images/m15.jpg") no-repeat;}
            25% { background: url("images/m10.jpg") no-repeat;}
            50% { background: url("images/m11.jpg") no-repeat;}
            75% { background: url("images/m12.jpg") no-repeat;}
            100% {background:  url("images/m15.jpg") no-repeat;}
        }
    </style>
</head>
<body>
<div class="myDiv"></div>
</body>
</html>

方法二:

<!DOCTYPE html>
<head>
    <meta charset="utf-8" />
    <title>css3实现幻灯片效果</title>
    <meta content="" name="description" />
    <meta content="" name="author" />
    <style type="text/css">
        .cb-slideshow{
            width:400px;
            height:400px;
            margin:0 auto;
            z-index:0;
        }
        .cb-slideshow li{
            position:absolute;
            width:400px;
            height:400px;
            background-size:cover;
            background-repeat: none;
            opacity:0;
            z-index:0;
            -webkit-animation: loops 36s linear infinite 0s;
        }
        .cb-slideshow li:nth-child(1){
            background-image: url(images/m10.jpg);
        }
        .cb-slideshow li:nth-child(2){
            background-image: url(images/m11.jpg);
            -webkit-animation-delay: 6s;
        }
        .cb-slideshow li:nth-child(3){
            background-image: url(images/m12.jpg);
            -webkit-animation-delay: 12s;
        }
        .cb-slideshow li:nth-child(4){
            background-image: url(images/m15.jpg);
            -webkit-animation-delay: 18s;
        }
        .cb-slideshow li:nth-child(5){
            background-image: url(images/m16.jpg);
            -webkit-animation-delay: 24s;
        }
        .cb-slideshow li:nth-child(6){
            background-image: url(images/m17.jpg);
            -webkit-animation-delay: 30s;
        }
        @-webkit-keyframes "loops" {
            0% {
                opacity: 0;
            }
            8% {
                opacity:1;
            }
            17% {
                opacity:1;
            }
            25% {
                opacity:0.5;
            }
            100% {
                opacity: 0;
            }
        }
    </style>
</head>
<body>
<ul class="cb-slideshow">
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>
</body>

原生JS实现一个简单的幻灯片效果:

简易版:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Easy slides</title>
<script>
var imgArr=new Array("img/1.jpg","img/2.jpg","img/3.jpg","img/4.jpg","img/5.jpg");
var index=0;
var cycle_b=false;
// 展示上一张图片
function previous(){
index--;
if(index<0)
index=imgArr.length-1;
document.getElementById("img").src=imgArr[index];
}

// 展示下一张图片
function next(){
index++;
if(index==imgArr.length)
index=0;
document.getElementById("img").src=imgArr[index];

}

// 循环播放,每三秒播放一张
function cycle(){
if(cycle_b){
cycle_b=false;
window.clearInterval(i);
document.getElementById("body").bgColor="cornflowerblue";
document.getElementById("btn1").type="button"// 停止时显示按钮
document.getElementById("btn2").type="button"
}else{
cycle_b=true;
i=window.setInterval("next()",1500); // 获取 setInterval 的返回值 ,用于停止
document.getElementById("body").bgColor="black";
document.getElementById("btn1").type="hidden" // 循环时隐藏按钮
document.getElementById("btn2").type="hidden"
}
}

</script>
</head>
<body align="center" bgcolor="cornflowerblue">
<br/><br/>
<br/><br/>
<img src="img/1.jpg" width="600" height="500"  οnclick="cycle()"/><br/><br/>
<p> 点击图片自动播放,再次点击取消自动播放 </p>
<input type="button"  value="<" οnclick="previous()"/>
<input type="button"  value=">" οnclick="next()"/>
</body>
</html>

复杂版:

HTML:

<div class="img-wrap">
   <ul>
     <li><img src="./image/aa.webp"/></li>
     <li><img src="./image/bb.jpg"/></li>
     <li><img src="./image/cc.jpg"/></li>
     <li><img src="./image/ee.webp"/></li>
   </ul>
   <div class="nav-dot">
     <span class="on"></span>
     <span></span>
     <span></span>
     <span></span>
   </div>
 </div>

CSS:

.img-wrap {
   width: 520px;
   height: 280px;
   position: relative;
   margin: 100px auto 0;
   border: 1px solid #F00;
   overflow: hidden; /* 浏览器底部就不会有滚动条了 */
 }

.img-wrap ul {
   position: absolute;
   left: 0;
   top: 0;
   margin: 0;
   padding: 0;
 }

.img-wrap ul li {
   list-style: none;
   float: left;
 }

.img-wrap ul li img {
   display: block; /* 消除img的魔鬼间距 */
 }

.nav-dot {
   font-size: 0; /* 消除inline-block自带的间距 */
   position: absolute;
   left: 50%;
   bottom: 10px;
   margin-left: -26px;
 }

.nav-dot span {
   display: inline-block;
   padding-top: 8px; /* 利用padding-top的值代替高度 */
   width: 8px;
   height: 0;
   background: #fff;
   border-radius: 50%;
   margin-right: 5px;
   cursor: pointer;
 }

.nav-dot span.on {
   background: #FF5000;
 }

 

JS:

window.onload = function () {
   var oUl = document.querySelector('ul');
   var aLi = oUl.getElementsByTagName('li');
   var aWidth = aLi[0].offsetWidth;
   var liLen = aLi.length;
   oUl.style.width = liLen * aWidth + 'px';

  var oNavDot = document.querySelector('.nav-dot');
   var aSpan = oNavDot.querySelectorAll('span');
   for (var i = 0; i < aSpan.length; i++) {
     aSpan[i].index = i;
   }

  // 事件委托 - 利用事件冒泡机制
  oNavDot.addEventListener('click', function (e) {
     var target = e.target || e.srcElement;
     if (target.tagName == 'SPAN') {
       oUl.style.left = -aWidth * target.index + 'px';
       for (var i = 0; i < aSpan.length; i++) {
         aSpan[i].className = '';
       }
       target.className = 'on';
     }
   })

}

 

匿名闭包IIFE模式(IIFE(Immediately-Invoked Function Expression),即立即执行的函数表达式,IIFE可以创造一个块级的作用域是js中模块化开发的一种模式。)模块化改造:

var slide = (function () {
   var module = {};

  var attr = {
     oUl: document.querySelector('ul'),
     oNavDot: document.querySelector('.nav-dot')
   };

  // 设置包裹图片的ul的宽度方法
  module.setUlWidth = function () {
     var aLi = attr['oUl'].getElementsByTagName('li');
     var aWidth = aLi[0].offsetWidth;
     var liLen = aLi.length;
     attr['oUl'].style.width = liLen * aWidth + 'px';
   };

  // 设置span的索引值(index)方法
  module.setIdx = function () {
     var aSpan = attr['oNavDot'].querySelectorAll('span');
     for (var i = 0; i < aSpan.length; i++) {
       aSpan[i].index = i;
     }
   };

  // 滑动方法
  module.slider = function () {
     // 事件委托 - 利用事件冒泡机制
    attr['oNavDot'].addEventListener('click', function (e) {
       var target = e.target || e.srcElement;
       if (target.tagName == 'SPAN') {
         attr['oUl'].style.left = -attr['oUl'].getElementsByTagName('li')[0].offsetWidth * target.index + 'px';
         for (var i = 0; i < attr['oNavDot'].querySelectorAll('span').length; i++) {
           attr['oNavDot'].querySelectorAll('span')[i].className = '';
         }
         target.className = 'on';
       }
     })
   };
   return module;
 }());

window.onload = function () {
   slide.setUlWidth();
   slide.setIdx();
   slide.slider();
 }

 

JQuery实现一个简单的幻灯片效果:

HTML:

<div class="carousel">

    <!--左侧按钮-->
    <button class="left"><i class="fa fa-x fa-angle-left"> </i></button>

    <ul id="carousel">
        <!--循环输出-->
        {loop $advs_pc $row}
            <li class="item"><a target="_blank" href="{$row['link']}"><img src="{$row['thumb_pc']}" height="420" alt="{$row['advname']}"></a></li>
        {/loop}
    </ul>

    <!--下方小圆点-->
    <div class="dot">
        {loop $advs_pc $row}
            <span></span>
        {/loop}
    </div>

    <!--右侧按钮-->
    <button class="right"><i class="fa fa-x fa-angle-right"></i></button>
</div>

CSS:

/*轮播图图片*/
.carousel {width: 100%;margin: auto;position: relative;}
.carousel ul {margin: 0;padding: 0;position: relative;width: 100%;height: 420px;}
.carousel ul li {list-style: none;float: left;position: absolute;top: 0;left: 0;display: none;}

/*向左向右的按钮*/
.left, .right {position: absolute;top: 200px;z-index: 10;width: 60px;height: 60px;font-size: 45px;border: none;background: #000;color: #fff;text-align: center;padding: 0;opacity: 0.1;cursor: pointer;border-radius: 2px;}
.left {left: 100px;}
.right {right: 100px;}
.left:hover, .right:hover {opacity: 1;}

/*圆点*/
.dot {width: 100%;bottom: 0;height: 30px;position: absolute;text-align: center;z-index: 10;}
.dot span {display: inline-block;width: 12px;height: 12px;border-radius: 50px;background: #fff;margin: 0 15px 0 0;cursor: pointer;z-index: 99;}
.dot .active {background: #851218 !important;}

JS:

$(function () {
      $('.dot').children('span').eq(0).addClass('active');//圆点
      $('#carousel img').width($('body').width());
      var items = $('#carousel').children();
      var len = items.length;
      var index = 0;
      var str = 0;
      var dots = $('.dot').children();

      //自动播放函数autoPlay()
      function autoPlay() {
            $(items[index]).fadeIn(1000);

            function play() {
                $(dots).removeClass("active");
                if (index >= 0 & index < len - 1) {
                    $(items[index]).fadeOut(1500);
                    index++;
                    $(items[index]).fadeIn(1500);
                    $(dots[index]).addClass("active");
                } else {
                    $(items[index]).fadeOut(1500);
                    index = 0;
                    $(items[index]).fadeIn(1500);
                    $(dots[index]).addClass("active");
                }
                str = index;
            }
            setInterval(play, 5000);
        }
        autoPlay();

        //点击左侧按钮的函数
        $(".left").click(function () {
            $(dots).removeClass("active");
            if (str == 0) {
                $(items[str]).fadeOut(1500);
                str = len - 1;
                $(items[str]).fadeIn(1500);
                $(dots[str]).addClass("active");
                index = str;

            } else {
                $(items[str]).fadeOut(1500);
                str--;
                $(items[str]).fadeIn(1500);
                $(dots[str]).addClass("active");
                index = str;
            }
        });
        //点击右侧按钮的函数
        $(".right").click(function () {
            $(dots).removeClass("active");
            if (str == len - 1) {
                $(items[str]).fadeOut(1500);
                str = 0;
                $(items[str]).fadeIn(1500);
                $(dots[str]).addClass("active");
                index = str;
            } else {
                $(items[str]).fadeOut(1500);
                str++;
                $(items[str]).fadeIn(1500);
                $(dots[str]).addClass("active");
                index = str;
            }
        })
        //小圆点
        $(".dot span").click(function () {
            var num = $(this).index();
            $(dots).removeClass("active");
            $(dots[num]).addClass("active");
            $(items).fadeOut(1500);
            $(items[num]).fadeIn(1500);
            index = num;
        })
 });

9. 你都使用哪些工具来测试代码的性能?

 

JSPerf

介绍:

JSPerf 是一个在线的代码片段性能测试工具,可以对代码片段的性能进行测试,并输出比对结果。

原理:

将给定的测试用例循环在指定环境下运行许多次,然后输入比对结果。

参考:JSPerf-javascript代码性能测试利器

Dromaeo、Profiler


10. 如果今年你打算熟练掌握一项新技术,那会是什么?

 

(1)React Native:使用JavaScript和React编写原生移动应用

React Native应用是真正的移动应用:

React Native产出的并不是“网页应用”, 或者说“HTML5应用”,又或者“混合应用”。 最终产品是一个真正的移动应用,从使用感受上和用Objective-C或Java编写的应用相比几乎是无法区分的。 React Native所使用的基础UI组件和原生应用完全一致。 你要做的就是把这些基础组件使用JavaScript和React的方式组合起来。

别再傻等编译了!

React Native让你可以快速迭代开发应用。 比起传统原生应用漫长的编译过程,现在你可以在瞬间刷新你的应用。开启Hot Reloading的话,甚至能在保持应用运行状态的情况下热替换新代码!

可随时呼叫原生外援:

React Native完美兼容使用Objective-C、Java或是Swift编写的组件。 如果你需要针对应用的某一部分特别优化,中途换用原生代码编写也很容易。 想要应用的一部分用原生,一部分用React Native也完全没问题 —— Facebook的应用就是这么做的。

参考:React Native中文网

(2)WebAssembly:

它到底是什么?

WebAssembly 是一种可以使用非 JavaScript 编程语言编写代码并且能在浏览器上运行的技术方案。

参考:

几张图让你看懂 WebAssembly - 简书

WebAssembly 概念 - WebAssembly | MDN

WebAssembly 完全入门——了解 wasm 的前世今身

(3)React、nodejs,html5,css3,less 等。


11. 请谈一下你对网页标准和标准制定机构重要性的理解。

 

网页标准和标准制定机构都是为了能让 web 发展的更健康,开发者遵循统一的标准,降低开发难度开发成本SEO 也会更好做,也不会因为滥用代码导致各种 bug、安全问题,最终提高网站易用性

w3c 存在的意义就是让浏览器兼容性问题尽量小,首先是他们对浏览器开发者的约束,然后是对开发者的约束。


12. 什么是 FOUC(无样式内容闪烁)?你如何来避免 FOUC?

 

FOUC(Flash Of Unstyled Content)-- 文档样式闪烁

<style type="text/css"media="all">@import"../fouc.css";</style > 而引用 CSS 文件的 @import 就是造成这个问题的罪魁祸首。IE 会先加载整个 HTML 文档的 DOM,然后再去导入外部的 CSS 文件,因此,在页面 DOM 加载完成到 CSS 导入完成中间会有一段时间页面上的内容是没有样式的,这段时间的长短跟网速,电脑速度都有关系。解决方法简单的出奇,只要在 < head > 之间加入一个 < link > 或者 < script > 元素就可以了。

如果使用import方法对CSS进行导入,会导致某些页面在Windows 下的Internet Explorer出现一些奇怪的现象:以无样式显示页面内容的瞬间闪烁,这种现象称之为文档样式短暂失效(Flash of Unstyled Content),简称为FOUC.原因大致为: 1,使用import方法导入样式表。 2,将样式表放在页面底部 3,有几个样式表,放在html结构的不同位置。其实原理很清楚:当样式表晚于 结构性html 加载,当加载到此样式表时,页面将停止之前的渲染。此样式表被下载和解析后,将重新渲染页面,也就出现了短暂 的 花屏现象。解决方法:使用LINK标签将样式表放在文档HEAD中


13.doctype(文档类型)的作用是什么?你知道多少种文档类型?

 

此标签可告知浏览器文档使用哪种 HTML 或 XHTML 规范。该标签可声明三种 DTD 类型,分别表示严格版本、过渡版本以及基于框架的 HTML 文档。

HTML 4.01 规定了三种文档类型:Strict、Transitional 以及 Frameset。

XHTML 1.0 规定了三种 XML 文档类型:Strict、Transitional 以及 Frameset。

Standards(标准)模式(也就是严格呈现模式)用于呈现遵循最新标准的网页,而 Quirks(包容)模式(也就是松散呈现模式或者兼容模式)用于呈现为传统浏览器而设计的网页。


14. 浏览器标准模式和怪异模式之间的区别是什么?在 js 中如何判断当前浏览器正在以何种方式解析?

 

W3C 标准推出以后,浏览器都开始采纳新标准,但存在一个问题就是如何保证旧的网页还能继续浏览,在标准出来以前,很多页面都是根据旧的渲染方法编写的,如果用的标准来渲染,将导致页面显示异常。为保持浏览器渲染的兼容性,使以前的页面能够正常浏览,浏览器都保留了旧的渲染方法(如:微软的 IE)。这样浏览器渲染上就产生了 Quircks mode 和 Standars mode,两种渲染方法共存在一个浏览器上。IE 盒子模型和标准 W3C 盒子模型:ie 的 width 包括:padding\border。标准的 width 不包括:padding\border

 

document 对象有个属性 compatMode, 它有两个值:BackCompat 对应 quirks mode,CSS1Compat 对应 strict mode。

参考:document.compatMode 介绍;


15. 使用 XHTML 的局限有哪些?

 

XHTML 与 HTML 的区别为:

  • XHTML 元素必须被正确地嵌套
  • XHTML 元素必须被关闭
  • 标签名必须用小写字母
  • XHTML 文档必须拥有根元素
  • 局限:

    所有的 XHTML 元素都必须被正确地嵌套,XHTML 必须拥有良好的结构,所有的标签必须小写,并且所有的 XHTML 元素必须被关闭。所有的 XHTML 文档必须拥有 DOCTYPE 声明,并且 html、head、title 和 body 元素必须存在。虽然代码更加的优雅,但缺少容错性,不利于快速开发。


    16. 如果网页内容需要支持多语言,你会怎么做?

     

    下面这些问题需要考虑:

  • 应用字符集的选择,选择 UTF-8 编码
  • 语言书写习惯 & 导航结构
  • 数据库驱动型网站
  • 搜索引擎 & 市场推广(SEO)
  •  

    详细:

     

    1- 应用字符集的选择;采用统一编码 UTF-8 方式编码,所以对提供了多语言版本的网站来说,Unicode 字符集应该是最理想的选择。它是一种双字节编码机制的字符集,不管是东方文字还是西方文字,在 Unicode 中一律用两个字节来表示,因而至少可以定义 65536 个不同的字符,几乎可以涵盖世界上目前所有通用的语言的每一种字符。 所以在设计和开发多语言网站时,一定要注意先把非中文页面的字符集定义为 “utf-8” 格式,即:这一步非常重要,原因在于若等页面做好之后再更改字符集设置,可说是一件非常非常吃力不讨好的工作,有时候甚至可能需要从头再来,重新输入网站的文字内容。

    2- 语言书写习惯 & 导航结构 ;有些国家的语言书写习惯是从右到左,例如许多中东地区所使用的阿拉伯语,波斯语和希伯来语等等。如果你的市场目标是这些语言的国家,那么在网站设计中就需要考虑这些特殊的语言书写习惯。而且如果你在网站导航结构设计中使用的是一个竖直导航栏,这时候就应该把它放在右边,而不是象我们习惯的那样放在左边了。

    3- 数据库驱动型网站
    对一个数据库驱动型的网站,尤其是当客户可以留言并向数据库添加信息时,则应当考虑如何从技术上实现对不同语言数据信息的收集和检索。

    4- 搜索引擎 & 市场推广;最好的办法是找一个专业的网站推广公司来帮助进行市场调研。调研内容主要应包括:目标市场国家或地区对什么搜索引擎或门户网站的使用率最高? 一些主要的门户网站的用户真实查询率又是多少? 这一点尤为重要。就象我们常使用新浪、搜狐等大型国内门户网站,但一般更多是为了使用其邮件服务。而查询的话还是喜欢百度或 Google 一样,你需要了解在这些人们青睐有加的门户网站上,到底有多少人是奔查询而来的。充分的市场考察才能做到有的放矢,从而保证最丰厚的投资回报

    多语言网站实现计划 :

    1、静态:就是为每种语言分辨准备一套页面文件,要么通过文件后缀名来区分不同语言,要么通过子目录来区分不同语言。
    例如对于首页文件 index_en.htm 供给英语界面,index_gb.htm 供给简体中文界面,index_big.htm 供给繁体中文界面,或者是 en/index.htm 供给英语界面,gb/index.htm 供给简体中文界面,big/index.htm 供给繁体中文界面,一旦用户选择了需要的语言后,主动跳转到相应的页面,首页以下其他链接也是按照同样方法处理。从保护的角度来看,通过子目录比通过文件后缀名来区分不同语言版本显得要简略明了。
    2,动态:站点内所有页面文件都是动态页面文件(PHP,ASP 等)而不是静态页面文件,在需要输出语言文字的处所同一采用语言变量来表现,这些语言变量可以根据用户选择不同的语言赋予不同的值,从而能够实现在不同的语言环境下输出不同的文字。
    例如:语言变量 ln_name,当用户选择的语言是英语时赋值为 “Name”,当用户选择的语言是简体中文时赋值为 “姓名”,这样就可以适应不同语言时的输出。
    采用静态方法的长处是页面直接输出到客户端,不需要在服务器上运行,占用服务器的资源比拟少,系统能够支撑的并发连接数较多,毛病是要为每种语言制作一套页面文件,很多内容即使是和语言无关的也要分不同语言来存储,因此占用的存储空间较多。
    采用动态方法和静态方法的优毛病正好相反,它的长处是动态页面文件只有一套,不同语言的文字应用语言变量来存储,和语言无关的内容只存储一份,占用的存储空间较少,并且扩大新语言比拟轻易,毛病需要在服务器上运行,然后把成果输进到客户端,占用服务器的资源比拟多,系统能够支撑的并发连接数较少。
    动态数据存贮涉及的一些技巧标题
    由于现在网站上动态利用日益增多,相当多的网站还会应用文件或者数据库来存储利用信息,因此假如文件或者数据库中存储的内容与语言相干时,还需要特别留心。对于存储在数据库中信息,可以采用以下几种方法支撑多语言:
    1,在数据库级别支撑多语言:为每种语言建立独立的数据库,不同语言的用户把持不同的数据库。
    2,在表级别支撑多语言:为每种语言建立独立的表,不同语言的用户把持不同的表,但是它们在同一个数据库中。
    3,在字段级别支撑多语言:在同一个表中为每种语言建立独立的字段,不同语言的用户把持不同的字段,它们在同一个表中。
    由于数据库中有大批的信息(如标记,编码,数字等)是用于内部处理应用的,与语言无关的,因此在数据库级别支撑多语言会导致空间的极大浪费,在字段级别支撑多语言最大的标题是一旦需要支撑新的语言,由于需要修正表结构,保护起来非常麻烦,可扩大性不好。
    相比之下,在表级别支撑多语言比拟好,由于并不是所有的表都需要支撑多语言,对于与语言无关的表,不同语言的用户共用一套,那些和语言相干的表根据支撑语言的种类来建立,不同语言的用户存取拜访不同的表格。这样使得保护简略,节俭了存储空间,即使是扩大起来也比拟方便,只要把需要支撑多语言的表,多建立一套即可。
    还需要留心的标题是:有些表中某些字段是不同语言版本的表共享的(例如库存量),由于各种语言的表之间的相对独立性,使得数据共享有些艰苦。解决的方法有两个:
    1,不同语言的表的共享字段同步:也就是说,只要修正了其中一个表的共享字段,其他语言表中该字段也作相应转变,实际上当不同语言的用户同时拜访时处理还是比拟麻烦的,并且扩充新语言时修正工作比拟大。
    2,增加一个新的表:把所有语言共享的字段(例如货物编号,产地编码等)全部放在这个表,支撑多语言的表只存放与各种语言相干的字段。不同语言的用户在应用数据库时,需要把持两个数据表。 比拟而言,第二种方法比拟简略,并且效率比拟高,保护也比拟方便。


    17.data - 属性的作用是什么?

     

    data-* 属性用于存储页面或应用程序的私有自定义数据。data-* 属性赋予我们在所有 HTML 元素上嵌入自定义 data 属性的能力。存储的(自定义)数据能够被页面的 JavaScript 中利用,以创建更好的用户体验(不进行 Ajax 调用或服务器端数据库查询)。

    data-* 属性包括两部分:

  • 属性名不应该包含任何大写字母,并且在前缀 "data-" 之后必须有至少一个字符

 

  • 属性值可以是任意字符串

 

JS实现获取自定义属性data值的方法:

HTML&JS:

<div id="tree" data-leaves="47" data-plant-height="2.4m"></div>
var tree = document.getElementById("tree");
//getAttribute()取值属性
console.log(tree.getAttribute("data-leaves"));
console.log(tree.getAttribute("data-plant-height"));
//setAttribute()赋值属性
tree.setAttribute("data-leaves","48");
//data-前缀属性可以在JS中通过dataset取值,更加方便
console.log(tree.dataset.leaves);
console.log(tree.dataset.plantHeight);
//赋值
tree.dataset.plantHeight = "3m";
tree.dataset.leaves--;
//新增data属性
tree.dataset.age = "100";
//删除,设置成null,或者delete
tree.dataset.leaves = null;
delete tree.dataset.age;

jQuery实现获取自定义属性data值的方法:

var $tree = $('#tree');
console.log($tree.data("plant-height"));

18. 如果把 HTML5 看作做一个开放平台,那它的构建模块有哪些?

 

<nav>,<header>,<section>,<footer > 等。


19. 请描述一下 cookies,sessionStorage 和 localStorage 的区别?

 

sessionStorage 和 localStorage 是 HTML5 Web Storage API 提供的,可以方便的在 web 请求之间保存数据。有了本地数据,就可以避免数据在浏览器和服务器间不必要地来回传递。sessionStorage、localStorage、cookie 都是在浏览器端存储的数据,其中 sessionStorage 的概念很特别,引入了一个 “浏览器窗口” 的概念。sessionStorage 是在同源的同窗口(或 tab)中,始终存在的数据。也就是说只要这个浏览器窗口没有关闭,即使刷新页面或进入同源另一页面,数据仍然存在。关闭窗口后,sessionStorage 即被销毁同时 “独立” 打开的不同窗口,即使是同一页面,sessionStorage 对象也是不同的 。cookies 会发送到服务器端。其余两个不会。Microsoft 指出 InternetExplorer8 增加 cookie 限制为每个域名 50 个,但 IE7 似乎也允许每个域名 50 个 cookie。

Firefox 每个域名 cookie 限制为 50 个。

Opera 每个域名 cookie 限制为 30 个。

Firefox 和 Safari 允许 cookie 多达 4097 个字节,包括名(name)、值(value)和等号。

Opera 允许 cookie 多达 4096 个字节,包括:名(name)、值(value)和等号。

InternetExplorer 允许 cookie 多达 4095 个字节,包括:名(name)、值(value)和等号。


20. 描述下 “reset”CSS 文件的作用和使用它的好处。

 

因为浏览器的品种很多,每个浏览器的默认样式也是不同的,所以定义一个 css reset 可以使各浏览器的默认样式统一

 

Normalize.css:

Normalize.css 是一种 CSS reset 的替代方案。它在默认的 HTML 元素样式上提供了跨浏览器的高度一致性。相比于传统的 CSS reset,Normalize.css 是一种现代的、为 HTML5 准备的优质替代方案。

创造 normalize.css 有下面这几个目的

保护有用的浏览器默认样式而不是完全去掉它们;

一般化的样式:为大部分 HTML 元素提供;

修复浏览器自身的 bug 并保证各浏览器的一致性;

优化 CSS 可用性:用一些小技巧;

解释代码:注释和详细的文档。

Normalize.css 支持包括手机浏览器在内的超多浏览器,同时对 HTML5 元素、排版、列表、嵌入的内容、表单和表格都进行了一般化。尽管这个项目基于一般化的原则,但我们还是在合适的地方使用了更实用的默认值。

Normalize vs Reset:

1. Normalize.css 保护了有价值的默认值

Reset 通过为几乎所有的元素施加默认样式,强行使得元素有相同的视觉效果。相比之下,Normalize.css 保持了许多默认的浏览器样式。这就意味着你不用再为所有公共的排版元素重新设置样式。当一个元素在不同的浏览器中有不同的默认值时,Normalize.css 会力求让这些样式保持一致并尽可能与现代标准相符合。

2. Normalize.css 修复了浏览器的 bug

它修复了常见的桌面端和移动端浏览器的 bug。这往往超出了 Reset 所能做到的范畴。关于这一点,Normalize.css 修复的问题包含了 HTML5 元素的显示设置、预格式化文字的 font-size 问题、在 IE9 中 SVG 的溢出、许多出现在各浏览器和操作系统中的与表单相关的 bug。

3、Normalize.css 不会让你的调试工具变的杂乱

使用 Reset 最让人困扰的地方莫过于在浏览器调试工具中大段大段的继承链。在 Normalize.css 中就不会有这样的问题,因为在我们的准则中对多选择器的使用时非常谨慎的,我们仅会有目的地对目标元素设置样式。

4、Normalize.css 是模块化的

这个项目已经被拆分为多个相关却又独立的部分,这使得你能够很容易也很清楚地知道哪些元素被设置了特定的值。因此这能让你自己选择性地移除掉某些永远不会用到部分(比如表单的一般化)。

5. Normalize.css 拥有详细的文档

Normalize.css 的代码基于详细而全面的跨浏览器研究与测试。这个文件中拥有详细的代码说明并在 Github Wiki 中有进一步的说明。这意味着你可以找到每一行代码具体完成了什么工作、为什么要写这句代码、浏览器之间的差异,并且你可以更容易地进行自己的测试。

如何使用 normalize.css

首先,安装或从 Github 下载 Normalize.css,接下来有两种主要途径去使用它。

策略一:将 normalize.css 作为你自己项目的基础 CSS,自定义样式值以满足设计师的需求。

策略二:引入 normalize.css 源码并在此基础上构建,在必要的时候用你自己写的 CSS 覆盖默认值。

jonsam ng

jonsam ng

文章作者

海阔凭鱼跃,天高任鸟飞。

前端面试题集锦(4)
1. 你能描述一下渐进增强和优雅降级之间的不同吗?   优雅降级:Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工作。由于IE…
扫描二维码继续阅读
2019-10-12