面试简书(五)

2019-07-18 14:36:52 浏览数 (1)

1.图片太大怎么处理

a.用不减分辨率的压缩方式进行压缩

用PS打开图片,点击点击“文件”——“存储为Web所用格式”将图片存储为Web所用格式,点击“存储”。

或者寻找第三方压缩方式https://tinypng.com/

b.将图片改为jpeg渐进式图片

想要将转化成渐进型jpeg格式,需要使用phtoshop

1、首先打开一个图片,选择“文件 -> 存储为”,选择“JPEG”格式,点击“保存”按钮。在“JPEG选项”界面的“格式选项”中选择“连续”,然后在“扫描”选项中设置为“5”

2、打开一张图片,选择“文件 -> 存储为Web和设备所用格式”,在弹出的界面右上角选择“JPEG”格式,勾选“连续”,点击“存储”按钮即可。

c.懒加载

当我们打开一个页面时,浏览器就会从上往下读取页面中的<img>标签src中的地址,并且开启线程来进行加载。

倘若用户的网速不给力或者此页面中的图片太多时,就会发生每张图片都加载了一点但是都没有加载完成,导致最后没有一个图片能正常显示。一方面让用户的体验非常之差,试问谁会一直耐心的等待着页面的加载?另一方面,加载每个图片都要向服务器发送请求,这会增大服务器的压力。

针对这种情况,就需要运用懒加载技术:先只加载可视窗口区域的图片,当用户向下拖动滚动条时再继续加载后面的图片(也是只加载目前可视窗口区域内的图片)。1.这样减少了加载时的线程数量,使可视区域内的图片也能够快速加载,优化了用户体验。2.减少了同一时间发向服务器的请求数,服务器压力剧减。

d.用图片进行操作

如果是一个gif图片,那么可以利用一张大图,通过位置的移动,通过肉眼的视觉残留弄成一个gif图,链接:https://blog.csdn.net/qq_34633111/article/details/82985827

如果是需要很多icon,那么可以直接放一张有很多icon的大图片,利用位置移动选择不同的icon

参考博客:https://blog.csdn.net/qq_34633111/article/details/83576364

2.视频在上面(无法设置优先级)

1.安卓端下的video标签播放时会被浏览器接管。此时已经脱离了文档流,并且与文档已经非同层了,所以设置z-index是无效的。 2.安卓下qq的x5内核浏览器,提供了相关属性。分别为:x5-playsinline:行内播放。x5-video-player-type="h5":播放层级为文档层级。如果页面只有一个视频而且该视频在页面的顶部用起来还是比较顺心的。否则会发现,额。。。播放视频的时候会紊乱的。 所以移动端中,不建议做视频和dom重合的设计。 如果一定要做,请继续阅读。 以下内容范围:安卓 1.在video未被播放之前,video标签属于正常文档元素,z-index也是生效的。此时层级高的dom可以展示在video标签区域上方。 2.video标签播放中和播放之后均会覆盖dom。 3.浏览器同时只能播放一个video标签。当切换播放视频内容时体验不是很好:

  • 浏览器播放组件切换视频时花费的时间可以明显的感知的到。
  • 浏览器播放组件的底色一般是黑色,而我们的web底色大多时候不是黑色,切换时,会出现闪动。是由于浏览器播放组件的关闭然后再次打开造成的。

解决思路: 1.删除和添加video标签这一节点,这样做会让video标签恢复到1中的状态。 2.删除video标签,浏览器的视频播放组件会立即消失,时间大幅度缩短。 比如:

  1. 我们要解决弹窗被视频遮挡的问题,此时我们可以将视频这一节点刷新(删除后再次添加)
  2. 我们想要切换视频,就先把当前正在播放的视频刷新,然后播放下一个视频。

3.图片太多怎么处理

方案一:将图片服务和应用服务分离(从架构师的角度思考)

把图片服务器与应用服务器分开,图片服务器采用独立域名 ,css、js和图片就可以并发请求了

方案二:简单粗暴的压缩方案

方案三:图片懒加载

像淘宝或者京东这样的APP页面上有很多图片,当我们滑到下一屏时下一屏的图片才会加载,这就采用了图片懒加载的方式.

图片懒加载,简单来说就是在页面渲染过程中,图片不会一次性全部加载,会在需要的时候加载,比如当滚动条滚动到某一个位置时触发事件加载图片,通过js将img标签的data-src属性赋值给src属性

方案四:css Sprites

当网站或者APP有大量小icon,如果上传到图片服务器比如CDN, 要加载所有这些小icon将增加大量请求,而CDN是按流量收费的,这无疑将增加很多成本.

此方案是将网站上的一些小logo拼合成一个大图,如图:

不过这也有一定的缺点:在长期开发多人合作的项目中,会不好维护这些sprites,每次对icon做修改,都得相应的改动css里background-position的值,相当繁琐.

方案五:将图片压缩成base64格式来节约请求

将图片压缩成base64,随html或者css一起下载到浏览器,不需要额外的请求,这样就节约了请求.

我们知道图片在传输过程中是流传输,如果将图片转换成base64,实际上是变大了,并且浏览器在decode base64编码的图片时需要耗费很多时间的,所以如果我们选择此种方案的话,最好选择一些小图片,不然得不偿失,在webpack中可以设置最大多少byte的图片压缩成base64

针对decode base64编码的图片比较慢的问题,我们可以选择使用canvas来加速.当向canvas发出绘画命令时,浏览器直接将指令发到图形加速器而不需要开发者更多的干预,硬件图形加速器则以难以执行的运算速度实时绘画和渲染图形.因此,我们可以使用canvas来渲染base64编码后的图片

具体代码如下:

代码语言:javascript复制
 // 缓存图片,并将图片渲染
var renderCvs = function(parent,max){
    //将img标签的class设置为lazyload,其父节点是a标签
    var lazyloadImage = $('.lazyload',parent);
    if(lazyloadImage.length<1){
       return;
    }
    var max = max||lazyloadImage.length;
    for(var i=0;i<max;i  ){
        var imgId = lazyloadImage[i].id;
       //再次打开网页,读取缓存,如果有,就从缓存中展示
        var imageCache = localStorage.getItem(imgId);
        if(imageCache){
            lazyloadImage[i].src = imageCache;
            continue;
        }
        var img = new Image();
        img.index = i;
        img.id = imgId;
        img.crossorigin="anonymous";
        img.onload = function(){
            var _this = this;
        var zCvs = $('#' this.id);
        var domCvs = zCvs[0];
        domCvs.src = this.src;
        zCvs.removeClass('lazyload');
        try{
            var cvs = document.createElement('canvas');
            cvs.style.display = 'none';
            document.body.appendChild(cvs);
            var rcvs = cvs.getContext('2d');
            cvs.width = 140;
            cvs.height = 108;
            rcvs.drawImage(this,0,0,140,108);
                            
              //这里进行缓存 ,toDataURL()方法将url转成base64字符串
            setTimeout(function(){
              var data = cvs.toDataURL();
             //将字符串保存到localStorage中
              localStorage.setItem(_this.id,data);
              document.body.removeChild(cvs);
            },200);
        }catch(ex){
        
        }
        }
        img.src = lazyloadImage[i].getAttribute('data-src');
    }
}

参考博客:https://www.jianshu.com/p/637cba4079ae

canvas图片懒加载 的参考博客:https://www.jianshu.com/p/ea7c0ee8aa64

4.上传图片

1.表单上传

最传统的图片上传方式是form表单上传,使用form表单的input[type=”file”]控件,打开系统的文件选择对话框,从而达到选择文件并上传的目的。

表单上传需要注意以下几点:

(1).提供form表单,method必须是post。

(2).form表单的enctype必须是multipart/form-data。

2.ajax上传

ajax和FormData可实现页面无刷新的文件上传效果,主要用到了jQuery的ajax()方法和XMLHttpRequest Level 2的

FormData接口。通过FormData对象可以更灵活方便的发送表单数据,因为可以独立于表单使用。如果你把表单的编码类型设置为multipart/form-data ,则通过FormData传输的数据格式和表单通过submit()方法传输的数据格式相同。

ajax无刷新上传

Ajax无刷新上传的方式,本质上与表单上传无异,只是把表单里的内容提出来采用ajax提交,并且由前端决定请求结果回传后的展示结果。

3.各类插件上传

当上传的需求要求可预览、显示上传进度、中断上传过程、大文件分片上传等等,这时传统的表单上传很难实现这些功能,我们可以借助现有插件完成。

如百度上传插件Web Uploader、jQuery图片预览插件imgPreview 、拖拽上传与图像预览插件Dropzone.js等等,大家可根据项目实际需求选择适合的插件。

5.测试数据是否满足正则表达式用什么方法

test(): 用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。

正则表达式优秀博客:https://blog.csdn.net/qq_35321405/article/details/90669101

6.swiper怎么同时操控两个互相关联的轮播

html:

代码语言:javascript复制
<!-- 主要轮播 -->
<div id="product-image-slides" class="swiper-container">
 <div class="swiper-wrapper"> 
  <div class="swiper-slide" v-for="item in swiper">
   <img :src="item">
    </div>
   </div>
  </div> 
  <!-- 导航轮播 --> 
<div id="product-image-nav" class="swiper-container">
 <div class="swiper-wrapper">
  <div class="swiper-slide" v-for="item in swiper">
   <img :src="item">
   </div>
  </div> 
  <!-- 自定义翻页器-->
  <div class="swiper-prev"></div> 
  <div class="swiper-next"></div> 
</div>

js:

代码语言:javascript复制
var imgSlide = new Swiper("#product-image-slides", {
 loop: false,
 centeredSlides: true, 
 autoplay: { 
   delay: 3000,
   disableOnInteraction: false 
  },
  slidesPerView: 1, 
  spaceBetween: 10, 
  navigation: {
   nextEl: '#product-image-nav .swiper-next',
   prevEl: '#product-image-nav .swiper-prev', 
  } 
}); 
var galleryThumbs = new Swiper('#product-image-nav', {
 spaceBetween: 10,
 slidesPerView: 5,
 touchRatio: 0.2, 
 loop: false, 
}); 
imgSlide.controller.control = galleryThumbs; 

// 点击缩略图 控制切换对应大图 
var objThumbs = $("#product-image-nav .swiper-wrapper .swiper-slide"); 
var objTop = $("#product-image-slides .swiper-wrapper .swiper-slide"); 
objThumbs.click(function(e) { 
  var currentId = $(this).attr("data-image-index");
  for(var i = 0; i < objTop.length; i  ) { 
    if($(objTop[i]).attr("data-image-index") === currentId) {
     e.preventDefault(); 
     imgSlide.slideTo(i, 1000, false); 
     } 
    } 
  }) 
},

注:代码是在vue框架下写的 不会vue的同学看一下结构也能明白

在vue框架下 这个swiper的js代码写在mounted内

不互相关联的多个swiper:

代码语言:javascript复制
<!--下载插件http://www.swiper.com.cn/download/-->
<!--引入插件-->
<link rel="stylesheet" href="path/to/swiper.min.css">
<script src="path/to/swiper.min.js"></script>
<!--HTML-->
<div class="swiper-container" id="swiper1"><!--第一个轮播-->
    <div class="swiper-wrapper">
        <div class="swiper-slide">图1</div>
        <div class="swiper-slide">图2</div>
        <div class="swiper-slide">图3</div>
    </div>
 </div>
 <div class="swiper-container" id="swiper2"><!--第二个轮播-->
    <div class="swiper-wrapper">
        <div class="swiper-slide">图4</div>
        <div class="swiper-slide">图5</div>
        <div class="swiper-slide">图6</div>
    </div>
 </div>
 <!--JS-->
<script>       
  var mySwiper1 = new Swiper ('#swiper1');    //第一个轮播   
  var mySwiper2 = new Swiper ('#swiper2');    //第二个轮播   
</script>

7.图片的自适应

方法一:

js代码,以宽度为例:

代码语言:javascript复制
var img = $(.img);
img.load(function(){
 var imgW = img.width();
 var screenW = $(window).width();
 if(imgW<screenW){ 
   img.css( 'width': 'auto');
   }else{ 
     img.css('width', '100%');
    } 
 })

方法二(div 包着 img):

代码语言:javascript复制
img {
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
}

如果图片为背景图片

style="background-image: url(${user.headimgurl});background-size: cover; "

如果你用了背景图片的方式:下面是background-size 的各个属性

length

设置背景图像的高度和宽度。第一个值设置宽度,第二个值设置高度。如果只设置一个值,则第二个值会被设置为 "auto"。

percentage

以父元素的百分比来设置背景图像的宽度和高度。第一个值设置宽度,第二个值设置高度。如果只设置一个值,则第二个值会被设置为 "auto"。

cover

把背景图像扩展至足够大,以使背景图像完全覆盖背景区域。背景图像的某些部分也许无法显示在背景定位区域中。

contain

把图像图像扩展至最大尺寸,以使其宽度和高度完全适应内容区域。

前端中的图片优化:https://www.jianshu.com/p/b55e951e9f03

0 人点赞