Jquery plugin using second instance's options

不打扰是莪最后的温柔 提交于 2019-12-24 14:40:59

问题


I have written a Jquery Pagination plugin that works great with just one instance of the plugin. When I try to use two instances, the first instance ignores its given options and uses the second instance's options. I know this because the two sections both start out with the defined items per page, but when you navigate to another 'page' in the pagination, it reverts to the second instance's itemsPerPage - 2.

My guess is the second time this plugin is called, it is overwriting $.pagination's options, so when either pagination goes to a new page, it uses the overwritten options.

Here's the plugin:

/* 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

Any idea why each instance of this plugin doesn't just use its own options? How would I need to structure a plugin to encapsulate and protect their own options? Thanks!


回答1:


Change

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

To

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

Demo

Reason is you are providing the target as defaultOption while using the syntax jQuery.extend( target [, object1 ] [, objectN ]



来源:https://stackoverflow.com/questions/20110634/jquery-plugin-using-second-instances-options

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!