前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >响应式卡片抽奖插件 CardShow

响应式卡片抽奖插件 CardShow

作者头像
叙帝利
发布2018-01-17 16:00:52
2.7K0
发布2018-01-17 16:00:52
举报
文章被收录于专栏:前端新视界前端新视界

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;
        }

    };

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

洗牌算法

 洗牌算法的原始方法由 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 事件

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

本文持续更新~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-12-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • jQuery 插件的编写
  • Modernizr 的使用
  • 相邻不重复随机数
  • 洗牌算法
  • 如何获取 transform 的值
  • Transitionend 事件
  • Chrome 中的 onresize 事件
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档