首页 > 网站 > WEB开发 > 正文

一个轮显插件的尝试、思考和扩展

2024-04-27 14:06:48
字体:
来源:转载
供稿:网友

一个轮显插件的尝试、思考和扩展

写在前面 自己的一点想法

"解决一个问题,最重要的收获并不是得到的答案。而是在寻找答案的过程中,学到的其它东西和见识的延伸。"

---《反正我从中学到不少东西》


”我敬你是条汉子!“

---《论如何回答女朋友问为什么对她那么好》


希望能够把文章大致扫一遍,里面有一些有趣的demo哦......哒


效果见页面顶部 或者如下:

          //---------------初始化轮显的方法-----------------------          $("#modelSlider").slider({            imgs: [  //图片的地址                "http://images.cnblogs.com/cnblogs_com/lianmin/713650/o_0f8738e9cfbb9485.png",                "http://images.cnblogs.com/cnblogs_com/lianmin/713650/o_89e657a08f9f13f6.png",                "http://images.cnblogs.com/cnblogs_com/lianmin/713650/o_884e69c2eb02316b.png",                "http://images.cnblogs.com/cnblogs_com/lianmin/713650/o_462506e0ed7b0c25.png",                "http://images.cnblogs.com/cnblogs_com/lianmin/713650/o_e5859ff3e6487575.png",                "http://images.cnblogs.com/cnblogs_com/lianmin/713650/o_f07bd295f4cdbd7a.png"            ],            urls: [  //点击图片跳转到的地址,也可以如下放一段js                'javascript:makeDialog("轮显提示或者地址","第1个图",function(){},3)',                'Javascript:makeDialog("轮显提示或者地址","第2个图",function(){},3)',                'javascript:makeDialog("轮显提示或者地址","第3个图",function(){},3)',                'javascript:makeDialog("轮显提示或者地址","第4个图",function(){},3)',                'javascript:makeDialog("轮显提示或者地址","第5个图",function(){},3)',                'javascript:makeDialog("轮显提示或者地址","第6个图",function(){},3)'            ],            scale: 5 / 2,   //图片宽高比            border: false,   //是否显示分界线            showBar: true,    //是否可以人工切换            x: 4,      //横向格子数            y: 3       //纵向格子数        });        //---------------控制轮显的方法-----------------------        $("#modelSlider").slider("begin");  //开始            执行某个方法        $("#modelSlider").slider("stop");    //停止        $("#modelSlider").slider("choseImg",3); //切换到索引为3的项      执行某个方法,传参        $("#modelSlider").slider("resize",{border:true,showBar:false}); //对初始化的属性进行修改             //-----------试试把上面这4行依次放到控制台执行一下?------

一、照着效果分析原理

最初是在一个叫《琉璃神社》的地方看到:http://hacg.club/。观察了很多次,觉得重点在这里:格子内的效果切换。于是就扒开看看喽...

观察了整个轮显很久之后,我初步得出以下几个想法。
  • 总效果 => 格子特效 + 效果产生顺序
  • 格子 => 2个div + 通过背景图切换
  • 通过背景图切换 || 效果产生顺序 => 可以用jQuery的队列处理Σ( ?д?))
  • 具体的逻辑算法 => 边写边想吧,写完重构
  • ......

二、搭建jQuery插件结构

我觉得应该写成插件方式,毕竟要多处用。以下是我写插件一般的格式,欢迎拍砖:

    // jQuery 插件的一般写法,自执行匿名方法    // 好处是这样的:1.避免其它插件也用了$做关键字;2.避免插件内部方法污染全局    // 实际工作中我一个js文件也许会写大几十个function,,,没办法,需求是一点一点加    (function ($) {        function Slider(option) {            //深拷贝,修改每个对象的属性只能通过对象实例,避免初始化时候外部引用对象的影响            this.opt = $.extend(true, {}, option);        }        $.fn.slider = function (option) {            var defaults = {  //默认设置                // 独立写出来,也许将来就用得到呢,也说不定...            };            //最终配置            var opt = $.extend({}, defaults, option);            //jQuery对象是一个伪数组对象,可能有多个元素            return $.each(this, function (index, ele) {                // code...                var slider = new Slider(opt);                $(ele).data("slider", slider);            });        };    })(jQuery);

总结:

  • 最基本的面向对象思想,写个类吧,在类中实现所有功能.
  • 对jQuery.fn进行扩展,可以用 $.fn.method = function ,或者 $.fn.extend({}) .
  • jQuery对象是一个伪数组对象,里面可能含有多个元素,需要针对每一个元素实例化一个对象进行缓存.
  • 说到data方法,js对象的 $({}).data ,是把数据放到对象本身上,而元素的 data 方法,是把数据放到 $.cache 中 。所以如何跨框架使用easyui等报错的解决方式,是需要用所属iframe内的jQuery对象,否则取不到。
  • 将所有代码放到匿名自执行方法中.

三、对将要用到的几个主要方法方法进行扩展

1.肯定要拼接html的,"<div id='"+theId+"' >....... 这种写法简直弱爆了,以前也经常这么写,但是某天就突然扩展了,,,果然多读读别人的文章对自己有好处.

    //扩展 string.format    String.PRototype.format = function () {        var args = arguments;        var reg = //{(/d+)/}/g;        return this.replace(reg, function (g0, g1) {            return args[+g1];        });    };    //用法:    "hello {0},your age is {1},so {0}'s age is {1}".format("tom",12);    //"hello tom,your age is 12,so tom's age is 12"

说明:

  • 对String原型进行扩展: String.prototype.methodName=function...
  • 正则表达式: //{(/d+)/}/g ;取"{0}"这种格式的占位符,并对里面的数字放入子组
  • js 的 replace 方法有一种重载, string.format(regex , function(group0【匹配项】,group1【子组第一个】...){ //code... }) ;对于每次匹配到的一个占位符,都从参数相应的位置取得替换项。

2.图片预加载

    (function ($) {  // 图片预加载        $.preLoad = function (urlArr) {            $.each(urlArr, function (index, url) {                var img = document.createElement("img");                img.src = url;            });        }    })(jQuery);    //上来就加载大量图片会占用大量带宽,影响用户体验    //但是如果轮显这里不提前加载,只在显示当前图片的时候去下载当前图片,对于一般网速的用户来说,可能不太好看    //根据实际情况使用吧...哒?

3.jQuery队列封装

关于jQuery队列的一点认识:

众所周知,使用jQuery给元素添加一连串的动画效果,元素并不会将动画同时执行,而是按照添加的顺序,依次在上一个动画结束之后才开始下一个动画。

我了解的情况就是,jQuery使用了一种叫做“队列”(queue)的方式将动画效果依次加进去,在上一个队列中的动画执行完毕,通过deferred通知下一个动画执行。

    var ele = $("#id"); //某个jQuery对象    //为jQuery对象的叫“queueName”的队列上面添加处理事件    ele.queue("queueName", function (next) {        //your code...  do something        next(); //next() 是执行下一个队列中要处理的事件,如果没有next队列就无法依次处理    });    //延时    ele.delay(1000, "queueName");    //执行队列    ele.dequeue("queueName");

这里要说一下的是,jQuery的动画默认是把处理事件放在了叫“fx”的队列中。因此,我进行了以下简单的封装:

    $.fn.will = function (callback, type) {        //这里的this,表示jQuery对象        this.queue(type || "fx", function (next) {  // fx 表示默认的队列            //这里的this,是原生的对象            callback && typeof callback == "function" && callback.call($(this)); //使用call,方便回调函数使用this            next();        });        return this; //返回this,方便进行链式调用    }    //试试在控制台这么用    var ele = $({});    for (var i = 0; i < 10; i++) {        ele.will(function () {            console.log(+new Date);        }).delay(1000);    }

使用队列,可以直观清晰,方便地将异步操作表示出来。就像 Thread.Sleep(1000) 那样明了。

关于Deferred我就不赘述了,本文没有直接使用到,自己也只是知其然而不知其所以然,仅仅会用。

队列的作用,就是将轮显中的格子,一个一个进行处理,避免了大量的setTimeout,使用callback的形式进行替换。

四、缓动

先看例子,没有效果图吸引不了人


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表