卡片抽奖插件 CardShow

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

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

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

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

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

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

1. jQuery 插件的编写

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

复制代码
;(function(window, $) {

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

    return instance;

  }

})(window, jQuery);
复制代码

2. modernizr 的使用

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

3. 相邻不重复随机数

解决这个问题多少让我有一些成就感,虽然还不是很完美。这至关于问:写一个函数,使其能够产生相邻不重复的随机数?对于这个问题我没有搜索到答案,搜到最多的是产生不重复的随机数。这彻底是两个问题,这个问题看起来不难,无非定义对比变量,但问题就在于怎么对比,怎么写函数。以前看到有人说“算法就像窗户纸”,如今深有体会。解决这个问题多少有些运气的成分,想了好久,最后随手一写,居然成功了。可能这个问题自己真的不难。我建议你们先不要展开代码,本身写一个函数,用 setInterval 持续输出随机数,可否作到相邻不重复。也但愿你们给我一个更完美的方案,欢迎留言。浏览器

 View Code

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

4.洗牌算法

 洗牌算法的原始方法由 Ronald Fisher 和 Frank 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;
    }; 
复制代码

5.获取 transform 的值

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

6. transitionend 事件

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

7.Chrome 中的 onresize 事件

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

本文持续更新~

相关文章
相关标签/搜索