• 响应式卡片抽奖插件 CardShow


    GitHub: https://github.com/nzbin/CardShow/

    Demo: https://nzbin.github.io/CardShow/

    前言

    这个小项目(卡片秀)是一个卡片抽奖特效插件,用开源项目这样的词语让我多少有些羞愧,毕竟作为一个涉世未深的小伙子,用项目的标准衡量还有很大差距。不过该案例采用 jQuery 插件方式编写,提供配置参数并且做了浏览器兼容优化,整体而言作为一个小项目也不为过。目前正在持续更新。

    当然,博主写这篇文章不是为了炫耀这个 Demo,而是交流 jQuery 插件的编写以及这一项目中遇到的各种问题。现在的插件还有很多 bug 以及不完善的地方包括一些代码的冗余,后期会进行更细致的拆分组装等。

    首先说一下这个项目的起因,博主最近接到了公司安排的一个抽奖页面,因为时间仓促以及其它原因,最后简单实现了功能并且添加了一些动画效果。但是最初看到设计图以卡片形式展示用户数据的时候,我就想到了能否做的稍微炫酷一点,随后便一直在构思。比如卡片的飞出、随机排列、自动及手动抽取以及翻转显示等效果。事实证明,把想法变现实会遇到很多的问题。大家可以点击 CardShow 查看自动抽卡的效果。目前的效果基本实现了我当初的构思。卡片的抽取效果主要分为自动抽手动抽两种。后期会添加卡片拖动的功能。我希望大家能够下载源码修改参数来查看效果,并提出宝贵意见,以便博主可以及时作出修改,大家的支持就是我前进的最大动力。

    以下是我在写插件时遇到的问题以及解决的问题,大概包括 jQuery 插件编写、modernizr 使用、css3 动画、transitionend 事件、洗牌算法、相邻不重复随机数、获取 transform 的值、call() 的深入理解、setTimeout 的堵塞等等,每一块拿出来都可以单独写一篇文章,这篇文章只是简单介绍,之后也会就某一部分做深入探讨。

    jQuery 插件的编写

    话说很多事情看着简单,做起来很难。如果不理解原生 js 的对象、函数、原型、作用域以及 jQuery 的核心思想及方法,想写一个插件可能真的非常困难。对于 jQuery 插件的编写我就不多说了,网上一搜很多,比我写的好的更多,我只贴一下自己写的插件的结构。对于代码的结构我思考了很久也研究了很久,最后借鉴了一些案例,感觉以下结构更清晰,更简洁,更易懂。

    ;(function(window, $) {
    
      // 插件主体
      $.plugin = function(el,options){
        
      }
      // 默认配置
      $.plugin.defaults = {
        
      }
      // 原型方法
      $.plugin.prototype = {
        
      }
     // 设置 jQuery 插件
      $.fn.plugin = function(options) {
    
        return instance;
    
      }
    
    })(window, jQuery);

    Modernizr 的使用

    modernizr 也算是一个老牌的浏览器兼容方案了,相信大家也早已使用或者早有耳闻。之前虽然早就知道这个小东西,应该是接触 bootstrap 时了解的,但一直未有机会使用,直到现在写插件才发现,用它检测 css3 的属性并做兼容方案真的是爽歪歪。网上关于 modernizr 的文章并不多,这是官网文档:https://modernizr.com/docs ,已经说得很详细,我之后会翻译该文。

    相邻不重复随机数

    解决这个问题多少让我有一些成就感,虽然还不是很完美。这个问题简单说就是:写一个函数,使其可以持续输出随机数,而相邻位置的随机数不相同。对于这个问题我没有搜索到答案,搜到最多的是产生不重复的随机数。这完全是两个问题,这个问题看起来不难,无非定义对比变量,但问题就在于怎么对比,怎么写函数。之前看到有人说“算法就像窗户纸”,现在深有体会。解决这个问题多少有些运气的成分,想了很久,最后随手一写,竟然成功了。可能这个问题本身真的不难。我建议大家先不要展开代码,自己写一个函数,用 setInterval 持续输出随机数,能否做到相邻不重复。也希望大家给我一个更完美的方案,欢迎留言。

        // 产生相邻不重复的随机数,n 为随机数个数
        // 定义比较变量,能否将其封装在函数内?
        var b = 0;
    
        function random(n) {
            var a = Math.floor(Math.random() * n);
    
            if (a == b) {
                return random(n); 
            } else {
                b = a;
                return b;
            }
    
        };
    View Code

     该问题已经得到解决,具体请参考相邻不重复随机数的生成及优化

    洗牌算法

     洗牌算法的原始方法由 Ronald FisherFrank Yates 提出,网上可以搜到很多,以下是常见的 JS 方法:

    // 数组随机变换函数
        function shuffleArr(array) {
            var m = array.length,
                t, i;
            // While there remain elements to shuffle…
            while (m) {
                // Pick a remaining element…
                i = Math.floor(Math.random() * m--);
                // And swap it with the current element.
                t = array[m];
                array[m] = array[i];
                array[i] = t;
            }
            return array;
        }; 

    如何获取 transform 的值

    因为动画以 transition 为主,所以要持续操作元素的 transform 的值。但是 transform 是一个复合值,取出特定数值有一定困难。我的解决办法简单粗暴。我在控制台打印 transform 的值得时候发现是一个 matrix 的东西。关于 transform 的矩阵知识大家自行搜索。其实就是一个字符串,只要 split() 方法取出特定值即可。但是这里面有个浏览器兼容的问题。众所周知,transform2d 是 3X3 矩阵,而 transform3d 是 4X4 矩阵,如果使用 transform3d 属性而没有给出第三个值,在火狐及谷歌浏览器会输出 3X3 矩阵,而在 IE 及 Edge 输出 4X4 矩阵。

    Transitionend 事件

    transitionend 事件是在 transition 动画结束之后执行的函数。说到 transitionend 事件,我有很多感想。首先大家可以看一下我的 github 中的两个关于慕课网仿写 https://github.com/codrops/ScatteredPolaroidsGallery 的 DEMO,当卡片翻转过来,然后直接移动卡片,这时卡片是边移动边翻转,效果不理想。当初学这个 DEMO 的时候就研究了很久,没找到答案,直到现在也没做修改。直到写此插件才发现一切优化都要基于 transitionend 事件。

    Chrome 中的 onresize 事件

    关于该问题的详情及解决方法请参考 这篇文章 !

    本文持续更新~

  • 相关阅读:
    将CMD内的显示内容输出到txt文件
    上传项目到Github
    利用百度地图API,在浏览器中找到自己的位置
    操作系统相关知识
    字符串的全排列
    二维数组做函数参数、指向指针的指针做函数参数
    strstr函数与strcmp函数
    华为机试题——数组排序,且奇数存在奇数位置,偶数存在偶数位置
    单链表的建立,插入,显示,查找删除以及反转
    《深入了解 Linq to SQL》之对象的标识 —— 麦叔叔呕心呖血之作
  • 原文地址:https://www.cnblogs.com/nzbin/p/6085720.html
Copyright © 2020-2023  润新知