zoukankan      html  css  js  c++  java
  • 一道面试题带来的前端优化——实现星星点评

    前言

    人人都会失业,这不巧小的这里就准备失业了,团队解散不是病,突然解散要人命。

    我们工作中面对这种突然团队解散的问题,对职业生涯规划是有很大问题的,他可以让你一夜回到革命前:

    比如我几年的工龄(<=1)没了;比如我今年年底年终奖又只有半年的了,比如我在这里努力的结果付诸东流了......

    说来说去,就一个结果,小的需要找工作了。于是那天就把简历挂了出来,也恰好有个招聘,就过去了,应该说毫无感觉,带着及其失落的感情过去了......

    面试过程中的题基本全知道,不管有印象的没印象的,反正全知道......但是知道不等于了解,了解不等于深入!这里又要为自己平时的不积累埋单了。

    根据那次面试,我这里有两个总结点,最近会形成研究:javascript中的this;javascript中的冒泡机制

    其实关于这两个东西,我其实早有兴趣研究,也早该研究,省略一万字......反正最后没有研究。

    说回主题、说回正题

    面试过程中,提出的一道题比较有意思,完了我一直想试试,这里提出来大家研究:

    这是在当当上截的图,我要完成的功能就是这个。

    鼠标滑动到某个星上就将几个高亮显示。

    最简单与最戳相差不远

    碰到这类题,我一般使用神器jquery,但是我们做前端开发的,若是没有一定涵养,第一次的方法必定是最容易实现的,往往也是最戳的:

    话不多说,先上代码:

    鼠标划上选中
     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4     <title></title>
     5     <style type="text/css">
     6         body { background: #dfdfdf;}
     7         ul, li { margin: 0; padding: 0}
     8         li { list-style: none;}
     9         #comment_star li { background: url("s1.jpg") no-repeat -29px 0; display: inline-block; text-indent: -999px; width: 26px; height: 26px;}
    10         #comment_star li.star_selcted { background-position: 0 0; }
    11     </style>
    12     <script src="http://www.cnblogs.com/jquery-1.7.1.js" type="text/javascript"></script>
    13     <script type="text/javascript">
    14         $(document).ready(function () {
    15             $('#comment_star li').mouseenter(function (e) {
    16                 var el = $(this);
    17                 el.addClass('star_selcted');
    18 
    19             }).mouseleave(function (e) {
    20                 var el = $(this);
    21                 el.removeClass('star_selcted');
    22             });
    23         });
    24     </script>
    25 </head>
    26 <body>
    27     <ul id="comment_star">
    28         <li star="1">1</li>
    29         <li star="2">2</li>
    30         <li star="3">3</li>
    31         <li star="4">4</li>
    32         <li star="5">5</li>
    33     </ul>
    34 </body>
    35 </html>

    功能一鼠标划上变显示选中

    思路:给每个li添加事件,改变其class影响背景变化:

    于是乎我们完成了功能的第一步,现在我们要将鼠标划上的前面几个都给选中,这不好办呢。。。于是退一步又都加上id吧!

    用到的图片:

    丑陋的完成功能
     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4     <title></title>
     5     <style type="text/css">
     6         body { background: #dfdfdf;}
     7         ul, li { margin: 0; padding: 0}
     8         li { list-style: none;}
     9         #comment_star li { background: url("s1.jpg") no-repeat -29px 0; display: inline-block; text-indent: -999px; width: 26px; height: 26px;}
    10         #comment_star li.star_selcted { background-position: 0 0; }
    11     </style>
    12     <script src="http://www.cnblogs.com/jquery-1.7.1.js" type="text/javascript"></script>
    13     <script type="text/javascript">
    14         $(document).ready(function () {
    15             $('#comment_star li').mouseenter(function (e) {
    16                 var el = $(this);
    17                 var num = el.attr('star');
    18                 for (var i = 1; i <= parseInt(num); i++) {
    19                     $('#s' + i).addClass('star_selcted');
    20                 }
    21             }).mouseleave(function (e) {
    22                 var el = $(this);
    23                 var num = el.attr('star');
    24                 for (var i = 1; i <= parseInt(num); i++) {
    25                     $('#s' + i).removeClass('star_selcted');
    26                 }
    27             });
    28         });
    29     </script>
    30 </head>
    31 <body>
    32     <ul id="comment_star">
    33         <li star="1" id="s1">1</li>
    34         <li star="2" id="s2">2</li>
    35         <li star="3" id="s3">3</li>
    36         <li star="4" id="s4">4</li>
    37         <li star="5" id="s5">5</li>
    38     </ul>
    39 </body>
    40 </html>

    这个丑陋的代码,已经惨不忍赌,实现的效果尤使让我不想看:

    1 使用ul标签,其html的结构可缩减

    2 为每个li绑定事件,划上几次事件,离开几次事件。。。。

    3 多出了很多id......

    4 显示效果也没有做优化,用的qq截图,有点晃动

    但是戳的代码也有他的优化的方法:

     1 $('#comment_star').delegate('li', 'mouseenter', function (e) {
     2     var el = $(this);
     3     var num = el.attr('star');
     4     for (var i = 1; i <= parseInt(num); i++) {
     5         $('#s' + i).addClass('star_selcted');
     6     }
     7 }).delegate('li', 'mouseleave',function (e) {
     8     var el = $(this);
     9     var num = el.attr('star');
    10     for (var i = 1; i <= parseInt(num); i++) {
    11         $('#s' + i).removeClass('star_selcted');
    12     }
    13 });

    说是简单优化,其实也没什么说的,无非是把事件绑定到了ul上,所需操作依旧很多。

    如何优化?

    对该题优化的主旨为:

    零请求、无流量

    减少dom操作

    零请求无流量来说,这里做的很好了,但是dom操作来说,怎一坑爹可言,其实我最开始想到的方法之所以在我看来不好优化,

    因为他从开始就错了,有了一个错误的开始,一个错误的基础,要怎么优化都是徒劳,所以我们改变思路,改变dom结构

    改变背景图片:demo.gif,小生还是用ps搞的呢,居然还是有点不像。。。

    改变dom结构

    我的思路是使用两个div处理,因为是边写边发,所以我也不知道行不行得通,我们首先来看看使用一个div平铺会怎样?

     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4     <title></title>
     5     <style type="text/css">
     6         body { background: #dfdfdf; }
     7         .star { background: url("demo.gif") repeat 0 0; width: 150px; height: 26px; }
     8         #star { }
     9         #s_star { background-position: 0 -30px;  }
    10     </style>
    11     <script src="http://www.cnblogs.com/jquery-1.7.1.js" type="text/javascript"></script>
    12     <script type="text/javascript">
    13         $(document).ready(function () {
    14  
    15         });
    16     </script>
    17 </head>
    18 <body>
    19     <div id="star" class="star">
    20     </div>
    21     <div id="s_star" class="star">
    22     </div>
    23 </body>
    24 </html>

    形成了一下图形

     

    现在我们来做一件坏事,看看可不可以将两个div重合:

    1 body { background: #dfdfdf; }
    2 .star { position: relative;}
    3 .star div { background: url("demo.gif") repeat 0 0;  150px; height: 26px; }
    4 #s_star { background-position: 0 -30px; position: absolute; left: 0; top: 0; }

    若是改变其中一个宽带的话......

     

    于是我感觉我好像离我要的效果近了。于是我加了一点代码,设置个断点来看看:

    $(document).ready(function () {
        $('.star').mouseenter(function (e) {
                    
            var s = '';
        }).mouseleave(function (e) {
    
        });
    });

     

    我在想这里两个属性是否对我有用?我是否可以根据他们设置div的宽度呢?

     1 $(document).ready(function () {
     2     $('.star').mouseenter(function (e) {
     3         var el = $(this);
     4         var x = e.clientX;
     5         var left = el.offset().left;
     6         var w = x - left
     7 
     8         var s = '';
     9     }).mouseleave(function (e) {
    10 
    11     });
    12 });

    我这样的话是不是获得鼠标相对于元素坐标的位置了呢?然后根据该属性设置绝对定位元素宽度试试:

    即将成功的代码
     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4     <title></title>
     5     <style type="text/css">
     6         body { background: #dfdfdf; }
     7         .star { position: relative;}
     8         .star div { background: url("demo.gif") repeat 0 0; width: 150px; height: 26px; }
     9         #s_star { background-position: 0 -30px; position: absolute; left: 0; top: 0; width: 0; }
    10         
    11     </style>
    12     <script src="http://www.cnblogs.com/jquery-1.7.1.js" type="text/javascript"></script>
    13     <script type="text/javascript">
    14         $(document).ready(function () {
    15             $('.star').mousemove(function (e) {
    16                 var el = $(this);
    17                 var x = e.clientX;
    18                 var left = el.offset().left;
    19                 var w = x - left
    20                 $('#s_star').css('width', w + 'px');
    21                 var s = '';
    22             }).mouseleave(function (e) {
    23 
    24             });
    25         });
    26     </script>
    27 </head>
    28 <body>
    29     <div class="star">
    30         <div id="star">
    31         </div>
    32         <div id="s_star">
    33         </div>
    34     </div>
    35     
    36 </body>
    37 </html>

     我们看到我鼠标指哪里,绝对定位宽度就到哪里,于是我们离胜利就只差一步了!!!判断宽度:

     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4     <title></title>
     5     <style type="text/css">
     6         body { background: #dfdfdf; }
     7         .star { position: relative; width: 150px;}
     8         .star div { background: url("demo.gif") repeat 0 0; width: 150px; height: 26px; }
     9         #s_star { background-position: 0 -30px; position: absolute; left: 0; top: 0; width: 0; }
    10         
    11     </style>
    12     <script src="http://www.cnblogs.com/jquery-1.7.1.js" type="text/javascript"></script>
    13     <script type="text/javascript">
    14         $(document).ready(function () {
    15             $('.star').mousemove(function (e) {
    16                 var el = $(this);
    17                 var x = e.clientX;
    18                 var left = el.offset().left;
    19                 var w = x - left;
    20                 var tmp = w % 30 - 30;
    21                 w = w - tmp;
    22                 $('#s_star').css('width', w + 'px');
    23                 var s = '';
    24             }).mouseleave(function (e) {
    25                 $('#s_star').css('width', '0px');
    26             });
    27         });
    28     </script>
    29 </head>
    30 <body>
    31     <div class="star">
    32         <div id="star">
    33         </div>
    34         <div id="s_star">
    35         </div>
    36     </div>
    37 </body>
    38 </html>

    现在我们就发现,他完全按照我的套路出牌了啦!!!优化结束!!!

    这样的代码我就可以结束了,我感觉基本达到我的要求了!

    当当的做法

     闭门造车结束,我们来看看当当是怎么做的呢?

    我们先截个图看看,我大概知道是什么回事了,于是我们来模拟一番:

    当当的背景图:

    我们发现他是一张整图,然后我也试试实现以下代码:

     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4     <title></title>
     5     <style type="text/css">
     6         body { background: #dfdfdf; }
     7         #star { background: url("dang.jpg") repeat 0 0; width: 335px; height: 26px; }
     8     </style>
     9     <script src="http://www.cnblogs.com/jquery-1.7.1.js" type="text/javascript"></script>
    10     <script type="text/javascript">
    11         $(document).ready(function () {
    12            
    13         });
    14     </script>
    15 </head>
    16 <body>
    17     <div id="star">
    18     </div>
    19 </body>
    20 </html>

    毫无修饰的情况下是这个样子,那么我们来简单调整下下:

     #star { background: url("dang.jpg") repeat -140px 0;  135px; height: 26px; }

    于是基本还原,现在来加上样式控制,当当写了几个css,我这里就东施效颦一番,直接不写css了:

    看我实现的代码
     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4     <title></title>
     5     <style type="text/css">
     6         body { background: #dfdfdf;  }
     7         #star { background: url("dang.jpg") no-repeat -140px 0; width: 135px; height: 26px; }
     8     </style>
     9     <script src="http://www.cnblogs.com/jquery-1.7.1.js" type="text/javascript"></script>
    10     <script type="text/javascript">
    11         $(document).ready(function () {
    12             $('#star').mousemove(function (e) {
    13                 var el = $(this);
    14                 var x = e.clientX;
    15                 var left = el.offset().left;
    16                 var w = x - left;
    17                 w = -140 + w;
    18                 el.css('background-position', w + 'px 0');
    19                 var s = '';
    20             }).mouseleave(function (e) {
    21                 var el = $(this);
    22                 el.css('background-position', '-140px 0');
    23             });
    24         });
    25     </script>
    26 </head>
    27 <body>
    28     <div id="star">
    29     </div>
    30 </body>
    31 </html>

    你看着,他会跟着鼠标走动,那么我们功能就已经实现一半了。

     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4     <title></title>
     5     <style type="text/css">
     6         body { background: #dfdfdf;  }
     7         #star { background: url("dang.jpg") no-repeat -140px 0; width: 140px; height: 26px; }
     8     </style>
     9     <script src="http://www.cnblogs.com/jquery-1.7.1.js" type="text/javascript"></script>
    10     <script type="text/javascript">
    11         $(document).ready(function () {
    12             $('#star').mousemove(function (e) {
    13                 var el = $(this);
    14                 var x = e.clientX;
    15                 var left = el.offset().left;
    16                 var w = x - left;
    17                 w = -140 + w;
    18                 if (w < 0) w = -1 * w;
    19                 w = parseInt(w / 28) * 28;
    20                 el.css('background-position', '-' + w + 'px 0');
    21                 var s = '';
    22             }).mouseleave(function (e) {
    23                 var el = $(this);
    24                 el.css('background-position', '-140px 0');
    25             });
    26         });
    27     </script>
    28 </head>
    29 <body>
    30     <div id="star">
    31     </div>
    32 </body>
    33 </html>

    于是我可耻的认为自己实现了当当的功能了。。。。。

    至于当当实现的方法,和我实现的方法,各位同学可以研究下,我可耻的认为估计当当的好吧。。。。

    结语

    有时候我在想我的js功底如何才能进步,如何才能成为高手,阅读jquery源码虽说是一个方式,当更应该平时多思考多动手的说,

    看看各大网站实现方案,与自己所想的实现方案,就可以看到差距了。

    而且我们平时面试的时候也不要小看那些面试题,其实他都是有针对性的,可以归纳为一个知识点做研究,

    我认为这也是一个进步的方向,最后期待各位拿出自己的解决方案哟。

     如果你觉得这篇文章还不错,请帮忙点击一下推荐,谢谢!

  • 相关阅读:
    [Ljava.lang.String; cannot be cast to java.lang.String 报错的原因
    ajaxfileupload多文件上传
    如何设置 html 中 select 标签不可编辑、只读
    docker
    nvm use 指定版本后无效 win7
    win7禁用Adnimistrator账号登录
    win10安装tomcat9
    webstorm命令行无法使用node-gyp进行编译
    tomcat7.0安装笔记
    win10 java1.7安装笔记
  • 原文地址:https://www.cnblogs.com/yexiaochai/p/3033910.html
Copyright © 2011-2022 走看看