【问题标题】:Jquery plugin using second instance's options使用第二个实例选项的 Jquery 插件
【发布时间】:2013-12-05 07:30:41
【问题描述】:

我编写了一个 Jquery Pagination 插件,它只适用于插件的一个实例。当我尝试使用两个实例时,第一个实例会忽略其给定的选项并使用第二个实例的选项。我知道这一点是因为这两个部分都从每页定义的项目开始,但是当您导航到分页中的另一个“页面”时,它会恢复到第二个实例的 itemsPerPage - 2

我的猜测是这个插件第二次被调用,它覆盖了$.pagination的选项,所以当任何一个分页进入新页面时,它都会使用覆盖的选项。

这是插件:

/* Jquery Pagination */
(function($){
    $.pagination = {
        defaultOptions : {
            itemsPerPage : 5,
            startPage : 1,
            showNextPrev : true,
            navigationPosition : 'before',
            paginationClass : 'pagination',
            paginationItemClass : 'paginationItem',
            paginationItemActiveClass : 'active',
            nextClass : 'next',
            nextText : 'Next',
            prevClass : 'prev',
            prevText : 'Prev',
        }
    }

    $.fn.extend({
        pagination : function(newOptions){
            var options = $.extend($.pagination.defaultOptions, newOptions),
                itemsToPaginate = $(this),
                itemsToPaginateContainer = itemsToPaginate.eq(0).parent(),
                paginationWrapper = "<div class='" + options.paginationClass + "'></div>",
                paginationControls = '',
                pagination,
                numberOfPages,

            showPage = function(goToPage){
                var page = (typeof goToPage === 'number') ? goToPage : goToPage.attr('href').replace('#page', ''),
                    itemRangeEnd = page * options.itemsPerPage
                    itemRangeStart = itemRangeEnd - options.itemsPerPage;

                $( '.' + options.paginationItemClass, pagination).removeClass(options.paginationItemActiveClass);
                if (typeof goToPage === 'number')
                    pagination.find('.' + options.paginationItemClass).eq(goToPage-1).addClass(options.paginationItemActiveClass);
                else
                    goToPage.addClass(options.paginationItemActiveClass);

                itemsToPaginate.hide().slice(itemRangeStart, itemRangeEnd).show();
            },

            createPagination = (function(){
                // Add pagination element to DOM
                switch(options.navigationPosition.toLowerCase()){
                    /*
                    // TODO: Create ability to insert pagination after or before & after
                    case 'both':
                        itemsToPaginateContainer.before(paginationWrapper);
                        itemsToPaginateContainer.after(paginationWrapper);
                        break;

                    case 'after':
                        itemsToPaginateContainer.after(paginationWrapper);
                        break;
                    */

                    default:
                        itemsToPaginateContainer.before(paginationWrapper);
                        break;
                }

                // Selecting pagination element
                pagination = itemsToPaginateContainer.siblings('.' + options.paginationClass);

                // Count how many pages to make
                numberOfPages = Math.ceil( itemsToPaginate.length / options.itemsPerPage );

                // Insert controls into pagination element
                if(options.showNextPrev) paginationControls += "<a href='#' class='" + options.prevClass + "'>" + options.prevText + "</a>";
                for (var i = 1; i <= numberOfPages; i++) {
                    paginationControls += "<a href='#page" + i + "' class='" + options.paginationItemClass + "'>" + i + "</a>";
                }
                if(options.showNextPrev) paginationControls += "<a href='#' class='" + options.nextClass + "'>" + options.nextText + "</a>";
                (numberOfPages !== 1) ? pagination.html(paginationControls) : pagination.remove() ;
            }()),

            bindUIEvents = (function(){
                pagination.find('.' + options.paginationItemClass + ':not(.' + options.nextClass + '):not(.' + options.prevClass + ')').on('click', function(e){
                    e.preventDefault();
                    showPage( $(this) );
                });

                pagination.find('.' + options.prevClass).on('click', function(){
                    var prevPageIdx = pagination.find('.' + options.paginationItemActiveClass).index() - 1;
                    // console.log(prevPageIdx);
                    if(prevPageIdx < 1)
                        showPage(numberOfPages);
                    else
                        showPage(prevPageIdx);
                });

                pagination.find('.' + options.nextClass).on('click', function(){
                    var nextPageIdx = pagination.find('.' + options.paginationItemActiveClass).index() + 1;
                    if(nextPageIdx > numberOfPages)
                        showPage(1);
                    else
                        showPage(nextPageIdx);
                });
            }());

            showPage(options.startPage);
            return this;
        }
    });
})(jQuery);

JSFiddle

知道为什么这个插件的每个实例不只使用自己的选项吗?我需要如何构建一个插件来封装和保护他们自己的选项?谢谢!

【问题讨论】:

    标签: javascript jquery jquery-plugins pagination


    【解决方案1】:

    改变

    var options = $.extend($.pagination.defaultOptions, newOptions),
    

    var options = $.extend({}, $.pagination.defaultOptions, newOptions),
    

    Demo

    原因是您在使用语法 jQuery.extend( target [, object1 ] [, objectN ] 时将目标作为 defaultOption 提供

    【讨论】:

    • 哇。我不敢相信这就是全部。我将查找使用$.extend() 的两种方式之间的确切区别,并在此处发布我的发现。感谢您的帮助!
    • @FillipPeyton 欢迎您。请参阅我的答案更新中的语法并链接到它。
    • 现在对我来说很有意义。我将新选项扩展到$.pagination.defaultOptions 的引用,而不是一个新的对象字面量。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多