zoukankan      html  css  js  c++  java
  • (翻译)编写属于你的jQuery插件

    Writing Your Own jQuery Plugins

    原文地址:http://blog.teamtreehouse.com/writing-your-own-jquery-plugins

    jQuery是一个优秀的javascript库。它不但拥有良好的跨浏览器兼容性,容易学习掌握,还可以轻而易举的为你的网站添加有趣的交互。同时,大量的jQuery插件能够让你随心所欲的完成你想要完成的工作。

    然而在平常的工作中,并不是总能够找到可以完全满足需求的插件,或者你想要将一些常用的功能封装以便保证项目的可重用性。在这些情形下,编写自己的jQuery插件是一个很好的满足需求的手段。

    其实,编写jQuery插件并没有想像中难。这篇文章,我们将通过编写一个简单的插件,为其添加一些参数和事件回调,来向你完整的展示整个流程。

    准备工作

    像大多数编程指南的开篇一样,我们也以一个“Hello World”插件开始吧。在开始之前,先创建必要的文件并在HTML文档中引用它们。首先,在站点的js目录下新建插件文件jquery.hello-world.js。通常,jQuery插件的命名以“jquery.”开始。

    接下来,需要在HTML文件中链接插件文件及其依赖的jquery核心库。我们将以下两行放置在文档的底部,也即</body>标签之前。

    <script src="js/jquery-1.9.1.min.js"></script>
    <script src="js/jquery.hello-world.js"></script>

    jQuery插件的结构

    jQuery本身已经为插件开发提供了足够的支持。但我们依然需要遵循JavaScript开发的最佳实践,将所有的代码都囊括在一个本地作用域中。下面是一个常规的jQuery插件基础结构:

    (function($) {
        $.fn.helloWorld = function() {
    
            // Future home of "Hello, World!"
    
        }
    }(jQuery));

    让我们花一点时间来理解一下上述代码的含义。通过将所有代码包含在 (function() {}) 自执行代码块中,能够保证插件内部的所有变量不会污染到全局变量。毕竟,我们肯定不愿意看到编写的插件和页面中的其它JavaScript代码发生冲突。

    可能你已经注意到,我们定义插件的方式,就好像jQuery也位于其“无冲突”模式。再一次强调,我们需要避免插件与页面中其它JavaScript发生冲突,这也包括使用到的'$'符号。该符号很有可能被其它的JavaScript库使用。

    最后,$.fn这种写法是jQuery定义插件的方式。这里将其命名为helloWorld并将所有代码放置在该函数中。下面,让我们做一些真正有意义的工作。

    插件代码编写

    为了使插件的代码尽可能的简单,同时又能达到演示的目的,我们将要完成的功能是改变关联的元素的文本内容为“hello world”。这已经近乎于傻瓜式的操作了。

    (function($) {
    
        $.fn.helloWorld = function() {
    
            this.each( function() {
                $(this).text("Hello, World!");
            });
    
        }
    
    }(jQuery));

    当在jQuery选择器上调用上述插件时,关联的元素已经是一个jQuery对象,因此不再需要再用"$(this)"结构进行包装。然而,如果需要在一个循环中使用每一个匹配的元素,比如$.each(),则一般会使用$(this)对循环的元素进行包装。

    假如我们想要改变下面页面中所有的<h2>标题的文本:

    调用的方式你已经很熟悉了,就像这样:

    <script>
    $(document).ready( function() {
        $('h2').helloWorld();
    });
    </script>

    结果为:

    我们能做的远远不止如此。当上面的插件调用时,实际上完全被隔离在了它本身的作用域。也就是说,调用的作用链在插件内部被终止了。如果你试着以jQuery的链式写法调用其它操作时,是不会生效的。为了修复这个问题,需要确保返回每个DOM元素循环后的结果:

    (function($) {
    
        $.fn.helloWorld = function() {
    
            return this.each( function() {
                $(this).text("Hello, World!");
            });
    
        }
    
    }(jQuery));

    恭喜你,已经写出了你人生中的第一个jQuery插件!

    稍安勿躁,好戏在后头!

    现在你可能正沉浸在编写出自己的jQuery插件的喜悦中,这时候你的老大跑过来说,想要把现在的网站翻译成西班牙语。老天爷,现在该咋整?

    其实,可以简单的添加一个参数完成上述需求。重新审视上述插件的代码,我们可以替换其内部的硬编码文本内容为一个变量,在调用的时候传入该变量的值。

    (function($) {
    
        $.fn.helloWorld = function( customText ) {
    
            return this.each( function() {
                $(this).text( customText );
            });
    
        }
    
    }(jQuery));

    如你所见,在调用的时候可以传入任何想要传入的文本值。办公室的马德里先生已经将我们需要的东西翻译成了西班牙语,现在可以使用参数的方式调用该插件:

    <script>
    $(document).ready( function() {
        $('h2').helloWorld('¡Hola, mundo!');
    });
    </script>

    页面呈现如下:

    完全自由的控制

    可能你已经感觉到一点担忧,如果在调用插件的时候没有传入文本怎么办?显而易见,页面中匹配的元素的文本会被插件修改为空值,这可能不是我们预期的结果。另外,我们的老大已经跑过来要求添加一个变量,如果他再跑过来要求添加更多的可定制化的选项怎么办?不断的添加参数毕竟不是长远之计,一劳永逸的解决方法是通过options对象。

    我们已经知道具体的文本内容需要由外部传入,现在,老大又要求文本颜色和字体大小同样在调用时指定(好吧,我知道颜色和字体大小都可以通过jQuery内置的函数进行控制,这里仅仅是一个演示)。让我们为插件添加一个options参数对象,同时通过$.extend方法与默认的参数进行合并:

    (function($) {
    
        $.fn.helloWorld = function( options ) {
    
            // Establish our default settings
            var settings = $.extend({
                text         : 'Hello, World!',
                color        : null,
                fontStyle    : null
            }, options);
    
            return this.each( function() {
                // We'll get back to this in a moment
            });
    
        }
    
    }(jQuery));

    现在我们有了可供外部设置的选项。如果调用的时候缺少了待替换的文本,将会使用指定的默认值。另外,在配置参数中添加了"color"和"fontStyle"两个属性,默认值均为"null"。如果在CSS文件中已经定义了颜色值和字体大小,在插件调用时不需要再重复指定。当然,二者均可以在插件内部重写。代码如下:

    return this.each( function() {
        $(this).text( settings.text );
    
        if ( settings.color ) {
            $(this).css( 'color', settings.color );
        }
    
        if ( settings.fontStyle ) {
            $(this).css( 'font-style', settings.fontStyle );
        }
    });

    因为该插件的目的是替换文本。如果提供的文本值为空则没有任何意义,这也是在插件内部为其指定默认值的原因,当参数缺失时显示缺省值总比空白要好得多。另一方面,颜色值和字体风格则只需要提供一个可供重写的入口。

    这时候老大跑过来说想要将站点翻译为法语,另外还希望将文本颜色改为蓝色,字体调整为italic。幸运的是,我们的插件处理这些需求毫无压力:

    $('h2').helloWorld({
        text        : 'Salut, le monde!',
        color       : '#005dff',
        fontStyle   : 'italic'
    });

    你看,我们的插件已经拥有了一些由外部控制的参数。将来可以在不影响现有调用的基础上,非常容易的添加或去掉某个参数。这些都益于良好的可扩展性。

    但我们的老大带着另外一个需求再一次跑了过来:一旦插件按其预定的方式调用完毕,应该弹出一个对话框通知用户这个消息。为了达到这个目的,有两个选择:要么辞职,因为这个家伙明显无视最初的需求文档。要么不走这么极端的路线,为我们的插件添加处理回调函数的能力。

    回调函数是JavaScript函数的参数,同时它本身也是一个JavaScript函数。其并不是jQuery独有的特性。初看上去回调函数是一个复杂的概念,但实际它的使用非常简单。

    我们需要做的仅仅是在配置对象中附加一个额外的参数:

    // Establish our default settings
    var settings = $.extend({
        text         : 'Hello, World!',
        color        : null,
        fontStyle    : null,
        complete     : null
    }, options);

    现在,当插件调用完毕时,就该附加的“complete”参数生效了。为了调用该参数,首先需要确保其是一个真正的函数。幸运的是,jQuery已经内置了$.isFunction函数帮助我们完成这个检测:

    return this.each( function() {
        // Our plugin so far
    
        if ( $.isFunction( settings.complete ) ) {
            settings.complete.call( this );
        }
    });

    页面中调用如下:

    $('h2').helloWorld({
        text        : 'Salut, le monde!',
        color       : '#005dff',
        fontStyle   : 'italic',
        complete    : function() { alert( 'Done!' ) }
    });

    最终的效果,插件执行完毕后会触发回调函数:

    结语

    当你一遍又一遍的写着大量重复的JavaScript代码,自定义jQuery插件是一种很好摆脱这种泥沼的方式。通过自定义插件,你在保持自己代码DRY(dont repeat yourself)的同时,也确保了全局名称空间的独立和纯度。

    如果你想调试上述示例代码,可以在我的 GitHub 获取。

     

  • 相关阅读:
    Nodejs Express4.x学习笔记
    OSG学习 错误与心得
    Qt Visual Studio Add-in安装
    OSG安装配置
    钩子
    不要去追一匹马,用追马的时间种草
    intellij Idea 报jdk错误
    flex 安全沙箱问题
    webuploader
    文件上传下载
  • 原文地址:https://www.cnblogs.com/mcmurphy/p/3355676.html
Copyright © 2011-2022 走看看