• 一次上机面试题带来的感悟【学习的感觉、学习的方法】


    前言


    最近团队面临解散,上面感觉想把我们一刀切,当天心里就很郁闷,于是想到了换工作,哎不想换现在也不行了。。。。

    当时联系到一个我认为不错的大哥,他给了我一道题,我一看,感觉有点水平,大概和HTML5有关系,但是我工作中一直想学但没机会学习,现在也只能硬着头皮做做了。

     访问地址我给关了,今早一来,磁盘空间都要挂了,图片“应有尽有”,好吧,伟大的程序员不差...

    这是一道面试题


    此次考察题目:

    1. 用户可以选择1个或多个图片进行上传,支持拖拽文件上传和弹出文件选择窗口2种方式;

    2. 用户可以看见上传的过程,清楚每个文件上传的进度;

    3. 上传后,用户可以选择不同的图片进行裁剪;

    4. 裁剪选择区域的时候,用户可以查看到裁剪后的效果图;

    5. 测试能够通过最新版的IE/FF/CHROME

     

    我实现的功能:

    1、选择1或者多个图片上传

    2、拖曳上传

    3、上传状态显示/上传进度条

    4、裁剪图片、预览图片、保存裁剪后的图片

    基本所有功能皆以完成;

     

     

     

    注意事项:

    此次题目共花去我两天左右时间,加上平时工作时中午时间,约12小时。

    而且这道题需要不只是前端方面的知识,过程中我使用了较熟悉的.net技术,作为服务器端语言,所以本地若需运行需要.net程序运行环境(安装vs2010即可),若无环境,需要给我一定时间上服务器部署以作为演示;

     

    兼容性:

    该程序中使用的很多东西都是HTML5里面的,所以兼容性只能做到最新浏览器兼容,我这里对以下浏览器做过测试:

    测试过的浏览器firefoxchrome

    应该支持的浏览器IE10

     

    对于不支持的浏览器:

    虽然功能差点,但也能进行操作(渐进增强),

    不支持功能:

    1、多图片上传

    2、拖曳上传

    3、上传状态

     

    不足:

    1、该功能要做好,个人认为需要至少1周时间,所以我暂时只能做到这个样子;

    2、项目中代码未封装、未优化,若有必要,后面点我会封装优化一下; 

    题目评价


    不知道各位大哥是怎么看的,但是就我这水平的小鱼一看,认为该题确实有点水平,就我的知识面来看,在html5出现之前,这就是一坨铁,我所想到的就只有flash可以做。。。

    不然就是后端程序相当恶心的配合,最后会得到四个字“费力不讨好”(我知道是5字了。。)

    但就该题而言能做起、并且能做好,没有一定水准还真不行。。。。有点自夸的嫌疑了(别喷我承认我查了资料好不)。。。

    功能截图


    程序主要代码


    View Code
      1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      2 
      3 <html xmlns="http://www.w3.org/1999/xhtml">
      4 <head>
      5     <title></title>
      6     <style type="text/css">
      7     body, ol, ul, h1, h2, h3, h4, h5, h6, p, th, td, dl, dd, form, fieldset, legend, input, textarea, select { margin: 0; padding: 0; }
      8     body { background: none repeat scroll 0 0  #D1D1D1; font: 14px "宋体","Arial Narrow",HELVETICA; }
      9     h1, h2, h3, h4, h5, h6 { font-weight: bold; font-size: 14px; }
     10     .over_h{ overflow: hidden;}
     11     .clear { clear: both;}
     12     
     13     .image_list { width: 250px; position: fixed; top: 0; bottom: 0; right: 0;  overflow-x: hidden; overflow-y: scroll; }
     14     .up_image { margin-right: 260px; height: 200px;}
     15     .img_tailor {  min-height: 200px; margin: 10px 260px 0 0;}
     16                  
     17     .box { border: 1px solid #E0E0E0; background: white; }
     18     .box .title { background: #336699; padding: 10px; color: White;  }
     19     
     20     .up_img { border: 1px dashed #DDDDDD; width: 140px; height: 140px;  margin: 10px; float: left; cursor: pointer; text-align: center; }
     21     .up_img img{ vertical-align: middle; }
     22     .up_img a { position: relative; overflow: hidden; display: inline-block; color: #005197; margin-top: 15px; }
     23     .up_img input { position: absolute; right: 0; top: 0; height: 100px; opacity: 0; filter: alpha(opacity=0); cursor:pointer;}
     24      
     25      
     26     .pre_img {  margin: 10px 10px 10px 170px; border: 1px dashed #DDDDDD; height: 140px; overflow-x: hidden; overflow-y: scroll; }
     27     .dragAreaOver{ border-color: Red; }
     28     
     29     .image_upload{ margin: 5px; border: 1px solid #E0E0E0; text-align: center; padding: 5px; display: inline-block; position: relative; }
     30     .image_upload img{ max-height: 115px; max-width: 115px; }
     31     .image_upload .rate { position: absolute; top: 6px; left: 6px; padding: 0 5px; color: White; background: black; border-radius: 5px;  filter:alpha(opacity=70); -moz-opacity:0.7; -khtml-opacity: 0.7; opacity: 0.7; }
     32    .image_upload .delete { background: url("images/del.png") no-repeat scroll 0 0 transparent; cursor: pointer; height: 16px; position: absolute; right: -6px; top: -6px; width: 16px;}
     33   
     34   .img_list { margin: 10px; }
     35   .img_list li { text-align: center; list-style: none;}
     36   .img_list li:hover { background-color: #E8F2FD; }
     37   .img_list li img{ max-height: 160px; max-width: 160px; padding: 5px;  border: 1px solid #E0E0E0; cursor: pointer; }
     38  
     39     .img_container{ margin: 10px auto; border: 1px solid #E0E0E0; overflow: hidden; width: 300px; display: none; }
     40     .img { float: left; position: relative;}
     41     
     42     .tailor_border {  width: 120px; height: 120px; position: absolute; background: black; filter:alpha(opacity=40); -moz-opacity:0.4; -khtml-opacity: 0.4; opacity: 0.4;}
     43    
     44    .pre_container { position:absolute;  top: 260px; right:270px; border: 1px solid #E0E0E0; width: 200px; height: 350px; text-align: center; display: none; } 
     45    .pre_container h3 { padding: 5px; border-bottom: 1px solid #E0E0E0;}
     46    .pre_view { border: 1px solid #E0E0E0; width: 120px; height: 120px; margin: 10px auto; padding: 5px; overflow: hidden; position: relative; }
     47     .save_view { margin: 10px auto;  }
     48     .save_view img{ border: 1px solid #E0E0E0; padding: 5px;  }
     49    .pre_view_img { position: absolute; }
     50    
     51     </style>
     52 </head>
     53 <body>
     54     <div class="box up_image">
     55         <h3 class="title">
     56             上传图片</h3>
     57         <div class="main over_h">
     58             <div class="up_img" id="up_img" title="上传图片">
     59                 <iframe id="if_upload" name="if_upload" style="display: none;" ></iframe>
     60                 <form id="uploadForm" target="if_upload" action="fileUpload.ashx?t=iframe" method="post" enctype="multipart/form-data">
     61                 <a class="fl"><img src="images/upload.jpg" alt=""/><input id="files" type="file" size="4" name="file[]" multiple /></a>
     62 
     63                 </form>
     64             </div>
     65             <div class="pre_img" id="pre_img">
     66             </div>
     67         </div>
     68     </div>
     69     <div class="box image_list">
     70         <h3 class="title">
     71             图片列表</h3>
     72         <div class="main">
     73             <ul id="img_list" class="img_list">
     74             </ul>
     75         </div>
     76     </div>
     77     <div class="box img_tailor">
     78         <h3 class="title">
     79             图片剪切</h3>
     80         <div class="main">
     81             <div class="img_container" id="img_container">
     82                 <div id="img" class="img">
     83                     <div class="tailor_border" id="tailor_border">
     84                     </div>
     85                     <img alt="" id="tailor_pic">
     86                 </div>
     87             </div>
     88             <div class="pre_container" id="pre_container">
     89                 <h3>预览</h3>
     90                 <div id="pre_view" class="pre_view">
     91                     <div id="pre_view_img" class="pre_view_img">
     92                         <img alt="" id="pre_pic">
     93                      </div>
     94                 </div>
     95                 <button type="button" id="save">
     96                     保存</button>
     97                 <div id="save_view" class="save_view">
     98                 </div>
     99             </div>
    100 
    101         </div>
    102         
    103 <script src="js/jquery-1.7.1.js" type="text/javascript"></script>
    104 <script type="text/javascript">
    105 
    106     //处理低版本浏览器上传问题
    107     function iframe_ipload(src) {
    108         var j_img_list = $('#img_list'),
    109             j_pre_img = $('#pre_img');
    110 
    111         var up = $('<div class="image_upload" ></div>');
    112         var img = $('<img src="' + src + '" alt="" >');
    113         var rate = $('<div class="rate">100%</div>');
    114         up.append(img);
    115         up.append(rate);
    116         j_pre_img.append(up);
    117 
    118         var li = $('<li></li>');
    119         var _i = $('<img title="裁剪图片" src="' + src + '" alt="">');
    120         showImg(_i);
    121         li.append(_i);
    122         j_img_list.append(li);
    123 
    124        // upload(files[k], k);
    125 
    126     }
    127     function showImg(el) {
    128         var j_img_container = $('#img_container'),
    129         j_pre_container = $('#pre_container'),
    130         j_tailor_pic = $('#tailor_pic'),
    131         j_img = $('#img'),
    132         j_pre_pic = $('#pre_pic');
    133 
    134         el.click(function () {
    135             j_pre_container.show();
    136             j_img_container.show();
    137             j_pre_pic.attr('src', el.attr('src'));
    138             j_tailor_pic.attr('src', el.attr('src'));
    139             initWidthByImg(j_img, j_img_container);
    140         });
    141     }
    142     //通用方法
    143     function initWidthByImg(img, img_container) {
    144         setTimeout(function () {
    145             img_container.css('width', img.width());
    146         }, 50)
    147         
    148     }
    149 
    150     $(document).ready(function () {
    151         var j_up_img = $('#up_img'),
    152         j_pre_img = $('#pre_img'),
    153         j_img_list = $('#img_list'),
    154         j_tailor = $('#tailor_border'),
    155         j_img_container = $('#img_container'),
    156         j_img = $('#img'),
    157         j_pre_view_img = $('#pre_view_img'),
    158         j_save = $('#save'),
    159         j_save_view = $('#save_view'),
    160         j_pre_container = $('#pre_container'),
    161         j_tailor_pic = $('#tailor_pic'),
    162         j_pre_pic = $('#pre_pic'),
    163         j_uploadForm = $('#uploadForm');
    164 
    165         j_file = $('#files');
    166 
    167         //需要上传的文件
    168         var files = null;
    169 
    170         //判断是否支持高级特性,经测试若是不支持filereader与file
    171         var is_support = true;
    172         if (typeof FileReader === 'undefined') is_support = false;
    173 
    174         //当点击图片时,触发上传事件
    175         j_file.change(function () {
    176             initDom();
    177             if (is_support) {
    178                 var file = j_file.get(0);
    179                 if (!file.files[0]) is_support = false;
    180                 //支持高级功能的浏览器
    181                 files = file.files;
    182                 if (files) {
    183                     preView(files);
    184                 }
    185             } else {
    186                 //不支持的话采用传统方式,渐进增强,支持IE7,8
    187                 j_uploadForm.submit();
    188             }
    189         });
    190 
    191         if (is_support) {
    192             //拖放上传图片
    193             var dragArea = j_up_img.get(0);
    194             /************拖放相关************/
    195             j_up_img.bind('dragover', function (e) {
    196                 $(this).addClass('dragAreaOver');
    197                 e.stopPropagation();
    198                 e.preventDefault();
    199             });
    200             j_up_img.bind('dragleave', function (e) {
    201 
    202                 $(this).removeClass('dragAreaOver');
    203                 e.stopPropagation();
    204                 e.preventDefault();
    205             });
    206             dragArea.addEventListener("drop", function (e) {
    207                 files = e.target.files || e.dataTransfer.files;
    208                 initDom();
    209                 preView(files);
    210                 e.stopPropagation();
    211                 e.preventDefault();
    212 
    213             }, false);
    214         }
    215         /************剪切相关************/
    216         //开始剪切时,初始化宽度
    217 
    218 
    219         dragFunc(j_tailor, j_tailor, j_img_container, function (e) {
    220             j_pre_view_img.css('left', '-' + j_tailor.css('left'));
    221             j_pre_view_img.css('top', '-' + j_tailor.css('top'));
    222 
    223         });
    224 
    225         j_save.click(function () {
    226             var offset = j_tailor.offset(),
    227                 o = j_img.offset();
    228             var pic_src = j_pre_pic.attr('src');
    229             pic_src = 'temp' + pic_src.substr(pic_src.lastIndexOf('/'));
    230 
    231             $.get('scissors.axd', {
    232                 action: 'GenerateBitmap',
    233                 src: pic_src,
    234                 zoom: 1,
    235                 x: (offset.left - o.left) * (-1),
    236                 y: (offset.top - o.top) * (-1),
    237                 //                    x: -50,
    238                 //y: -50,
    239                  j_tailor.width(),
    240                 height: j_tailor.height(),
    241                 t: Math.random()
    242             }, function (data) {
    243                 if (data && typeof data == 'string') {
    244                     data = eval('(' + data + ')');
    245                 }
    246                 var src = data.src;
    247                 j_save_view.html('<img src="' + src + '" alt="" />');
    248             });
    249 
    250         });
    251 
    252 
    253 
    254         function initDom() {
    255             j_pre_img.html('');
    256             //j_img_list.html('');
    257         }
    258 
    259         function preView(files) {
    260             for (var k = 0, len = files.length; k < len; k++) {
    261                 var file = files[k];
    262                 var reader = new FileReader();
    263                 reader.readAsDataURL(file);
    264                 (function (k) {
    265                     reader.onloadend = function (e) {
    266                         if (reader.error) {
    267                             alert(reader.error);
    268                         } else {
    269                             var up = $('<div class="image_upload" id="up_' + k + '"></div>');
    270                             var img = $('<img src="' + this.result + '" alt="" id="img_' + k + '">');
    271                             var rate = $('<div class="rate" id="rate_' + k + '">0%</div>');
    272                             up.append(img);
    273                             up.append(rate);
    274                             j_pre_img.append(up);
    275                             upload(files[k], k);
    276 
    277                         }
    278                     };
    279                 })(k);
    280             } //for
    281         }
    282 
    283         function upload(file, k) {
    284             var up = $('#up_' + k);
    285             var img = $('#img_' + k);
    286             var rate = $('#rate_' + k);
    287             var del = $('#del_' + k);
    288             var fd = new FormData();
    289             fd.append('upload', file);
    290             var xhr = new XMLHttpRequest();
    291             xhr.upload.addEventListener('progress', function (e) {
    292                 var percentComplete = Math.round((e.loaded) * 100 / e.total);
    293                 rate.html(percentComplete.toString() + '%');
    294             }, false);
    295             // 文件上传成功或是失败
    296             xhr.onreadystatechange = function (e) {
    297                 if (xhr.readyState == 4) {
    298                     if (xhr.status == 200) {
    299                         rate.html('100%');
    300                         var url = xhr.responseText;
    301                         var li = $('<li></li>');
    302                         var _i = $('<img title="裁剪图片" src="' + url + '" alt="">');
    303                         showImg(_i);
    304                         li.append(_i);
    305                         j_img_list.append(li);
    306 
    307                     }
    308                 }
    309             };
    310             xhr.open("POST", "fileUpload.ashx");
    311             //发送        
    312             xhr.send(fd);
    313         }
    314 
    315         function dragFunc(dragDiv, dragBody, parent, func_up) {
    316             if (dragDiv[0] && dragBody[0]) {
    317                 var dragAble = false;
    318                 var x1 = 0;
    319                 var y1 = 0;
    320                 var l = 0;
    321                 var t = 0;
    322                 var p_t = 0;
    323                 var p_l = 0;
    324                 var init_position = '';
    325 
    326                 var divOffset = dragBody.offset();
    327                 dragDiv.mousedown(function (e) {
    328                     var ss = this;
    329                     //                    var rootId = 
    330                     init_position = dragBody.css("position");
    331                     dragBody.css("position", "absolute");
    332                     dragDiv.css("cursor", "move");
    333                     dragAble = true;
    334                     // 当前鼠标距离div边框的距离
    335                     // 当前鼠标坐标,减去div相对左边的像素
    336                     l = parseInt(dragBody.css("left")) ? parseInt(dragBody.css("left")) : 0;
    337                     t = parseInt(dragBody.css("top")) ? parseInt(dragBody.css("top")) : 0;
    338 
    339                     if (parent && parent[0]) {
    340                         p_l = parent.offset().left;
    341                         p_t = parent.offset().top;
    342                     }
    343 
    344                     x1 = e.clientX - l - p_l;
    345                     y1 = e.clientY - t - p_t;
    346                     x1 = x1 > 0 ? x1 : 0;
    347                     y1 = y1 > 0 ? y1 : 0;
    348                     this.setCapture && this.setCapture();
    349                 });
    350                 dragDiv.mousemove(function (e) {
    351                     if (!dragAble)
    352                         return;
    353                     // 当前div左边的坐标
    354                     // 当前鼠标坐标,减去鼠标拖动量
    355                     var x2 = 0;
    356                     var y2 = 0;
    357                     //需要考虑滚动条问题!!!
    358                     var top = $(document).scrollTop() ? $(document).scrollTop() - 40 : 0;
    359                     var left = $(document).scrollLeft() ? $(document).scrollLeft() - 40 : 0;
    360                     x2 = e.clientX - x1 + left - p_l;
    361                     y2 = e.clientY - y1 + top - p_t;
    362                     x2 = x2 > 0 ? x2 : 0;
    363                     y2 = y2 > 0 ? y2 : 0;
    364 
    365                     //当鼠标值较大时需要处理
    366                     if (e.clientX > 600) {
    367                         $('#pre_container').css('left', '10px');
    368                         $('#pre_container').css('right', '');
    369                     } else {
    370                         $('#pre_container').css('left', '');
    371                         $('#pre_container').css('right', '270px');
    372                     }
    373 
    374                     if (Math.abs(l - x2) > 10 || Math.abs(t - y2) > 10) {
    375                         dragBody.css("left", x2 + "px");
    376                         dragBody.css("top", y2 + "px");
    377                     }
    378                     if (func_up && typeof func_up == 'function') {
    379                         func_up(e);
    380                     }
    381                 });
    382                 dragDiv.mouseup(function (event) {
    383                     if (!dragAble)
    384                         return;
    385                     dragAble = false;
    386                     dragBody.css("position", init_position);
    387                     if (dragBody.css("position") == 'fixed') {
    388                         var t = parseInt(dragBody.css('top'));
    389                         var st = $(document).scrollTop() ? $(document).scrollTop() : 0;
    390                         dragBody.css('top', (t - st) + 'px');
    391                     }
    392                     // dragDiv.css("position", "relative");
    393                     this.releaseCapture && this.releaseCapture();
    394 
    395                 });
    396             }
    397         }
    398     });
    399 
    400 </script>
    401 </body>
    402 </html>

    感悟


    写之前,本来感觉好多话要说,但是最后发现自己就一个标题党。。。

    感悟这个东西你说之前感觉很多很多,但真的要写的时候却发现什么也没有了。

    由此我想到了另外一件事情,曾经很多很要好的兄弟,平时非常思念,但真的拿起电话、见面时反而没什么话可说。。。。

    哎,其实我想说在这段时间的业余时间中,总在看书学习,却没有动力,没有效果,很搞笑的是这次面试题却带给了我不一样的感觉;

    我真的就以此接触了一直想学习而没有学习的HTML5的东西,我突然可以两天晚上开开心心的编码,甚至晚上睡觉时候也会思考,

    我仿佛回到了大学和同学一起做项目的时光,没有多余的想法,就是想学东西,就是想做好而已。。。。

    就在这个过程中,我觉得我找到了我丢失已久的“安静”,因为我心不静已经很久了,为了工资为了提升,却忘了刚刚出校门所思所想了。。。

    调用曾经高手们的一句话:

    如果能够只为挥剑而挥剑,或许就能更接近我所追求的境界,但又谈何容易呢?

  • 相关阅读:
    五种常见的 PHP 设计模式(收藏)
    写年度工作总结
    关于window.open和window.showdialog返回值的问题
    50个令人叹为观止的JavaScript应用站点[转]
    10大免费FLV播放器下载[转]
    6个去掉图片上的文字的技巧实用简单
    mysql命令大全(转)
    10款替代Windows Media Player的播放器
    Editplus FTP远程访问Ubuntu
    C++ 元编程 Meta Programming
  • 原文地址:https://www.cnblogs.com/yexiaochai/p/3014404.html
Copyright © 2020-2023  润新知