http://jsfiddle.net/centurianii/s4J2H/1/

ужно создать плагин jQuery, который бы возвращал один экземпляр на идентификатор селектора. Плагин должен и будет использоваться только для элементов с идентификатором (невозможно использовать селектор, который соответствует многим элементам), поэтому он должен использоваться следующим образом:

$('#element-id').myPlugin(options);
Мне нужно иметь возможность иметь несколько закрытых методов для плагина, а также несколько открытых методов. Я могу добиться этого, но моя главная проблема заключается в том, что я хочу получать один и тот же экземпляр каждый раз, когда я вызываю $ ('# element-id'). MyPlugin ().И я хочу иметь некоторый код, который должен выполняться только при первой инициализации плагина для данного идентификатора (конструкции).options Параметр должен быть предоставлен в первый раз, для конструкции, после этого я не хочу, чтобы конструкция выполнялась, чтобы я мог получить доступ к плагину так же, как $ ('# element-id'). myPlugin ()Плагин должен иметь возможность работать с несколькими элементами (обычно до 2) на одной странице (но каждому из них потребуется собственная конфигурация, опять же - они будут инициализированы по ID, а не по общему выбору класса, например).Приведенный выше синтаксис только для примера - я открыт для любых предложений о том, как добиться этого шаблона

У меня довольно большой опыт работы с другими языками, но я плохо знаю javascript, и я действительно не понимаю, как это сделать правильно.

РЕДАКТИРОВАТЬ

Чтобы уточнить - этот плагин представляет собой обертку API GoogleMaps v3 (помощник), чтобы помочь мне избавиться от дублирования кода, так как я использую карты Google во многих местах, обычно с маркерами. Это текущая библиотека (удалено много кода, осталось увидеть только самые важные методы):

;(function($) {
    /**
     * csGoogleMapsHelper set function.
     * @param options map settings for the google maps helper. Available options are as follows:
     * - mapTypeId: constant, http://code.google.com/apis/maps/documentation/javascript/reference.html#MapTypeId
     * - mapTypeControlPosition: constant, http://code.google.com/apis/maps/documentation/javascript/reference.html#ControlPosition
     * - mapTypeControlStyle: constant, http://code.google.com/apis/maps/documentation/javascript/reference.html#MapTypeControlStyle
     * - mapCenterLatitude: decimal, -180 to +180 latitude of the map initial center
     * - mapCenterLongitude: decimal, -90 to +90 latitude of the map initial center
     * - mapDefaultZoomLevel: integer, map zoom level
     * 
     * - clusterEnabled: bool
     * - clusterMaxZoom: integer, beyond this zoom level there will be no clustering
     */
    $.fn.csGoogleMapsHelper = function(options) {
        var id = $(this).attr('id');
        var settings = $.extend(true, $.fn.csGoogleMapsHelper.defaults, options);

        $.fn.csGoogleMapsHelper.settings[id] = settings;

        var mapOptions = {
            mapTypeId: settings.mapTypeId,
            center: new google.maps.LatLng(settings.mapCenterLatitude, settings.mapCenterLongitude),
            zoom: settings.mapDefaultZoomLevel,
            mapTypeControlOptions: {
                position: settings.mapTypeControlPosition,
                style: settings.mapTypeControlStyle
            }
        };

        $.fn.csGoogleMapsHelper.map[id] = new google.maps.Map(document.getElementById(id), mapOptions);
    };

    /**
     * 
     * 
     * @param options settings object for the marker, available settings:
     * 
     * - VenueID: int
     * - VenueLatitude: decimal
     * - VenueLongitude: decimal
     * - VenueMapIconImg: optional, url to icon img
     * - VenueMapIconWidth: int, icon img width in pixels
     * - VenueMapIconHeight: int, icon img height in pixels
     * 
     * - title: string, marker title
     * - draggable: bool
     * 
     */
    $.fn.csGoogleMapsHelper.createMarker = function(id, options, pushToMarkersArray) {
        var settings = $.fn.csGoogleMapsHelper.settings[id];

        markerOptions = {
                map:  $.fn.csGoogleMapsHelper.map[id],
                position: options.position || new google.maps.LatLng(options.VenueLatitude, options.VenueLongitude),
                title: options.title,
                VenueID: options.VenueID,
                draggable: options.draggable
        };

        if (options.VenueMapIconImg)
            markerOptions.icon = new google.maps.MarkerImage(options.VenueMapIconImg, new google.maps.Size(options.VenueMapIconWidth, options.VenueMapIconHeight));

        var marker = new google.maps.Marker(markerOptions);
        // lets have the VenueID as marker property
        if (!marker.VenueID)
            marker.VenueID = null;

        google.maps.event.addListener(marker, 'click', function() {
             $.fn.csGoogleMapsHelper.loadMarkerInfoWindowContent(id, this);
        });

        if (pushToMarkersArray) {
            // let's collect the markers as array in order to be loop them and set event handlers and other common stuff
             $.fn.csGoogleMapsHelper.markers.push(marker);
        }

        return marker;
    };

    // this loads the marker info window content with ajax
    $.fn.csGoogleMapsHelper.loadMarkerInfoWindowContent = function(id, marker) {
        var settings = $.fn.csGoogleMapsHelper.settings[id];
        var infoWindowContent = null;

        if (!marker.infoWindow) {
            $.ajax({
                async: false, 
                type: 'GET', 
                url: settings.mapMarkersInfoWindowAjaxUrl, 
                data: { 'VenueID': marker.VenueID },
                success: function(data) {
                    var infoWindowContent = data;
                    infoWindowOptions = { content: infoWindowContent };
                    marker.infoWindow = new google.maps.InfoWindow(infoWindowOptions);
                }
            });
        }

        // close the existing opened info window on the map (if such)
        if ($.fn.csGoogleMapsHelper.infoWindow)
            $.fn.csGoogleMapsHelper.infoWindow.close();

        if (marker.infoWindow) {
            $.fn.csGoogleMapsHelper.infoWindow = marker.infoWindow;
            marker.infoWindow.open(marker.map, marker);
        }
    };

    $.fn.csGoogleMapsHelper.finalize = function(id) {
        var settings = $.fn.csGoogleMapsHelper.settings[id];
        if (settings.clusterEnabled) {
            var clusterOptions = {
                cluster: true,
                maxZoom: settings.clusterMaxZoom
            };

            $.fn.csGoogleMapsHelper.showClustered(id, clusterOptions);

            var venue = $.fn.csGoogleMapsHelper.findMarkerByVenueId(settings.selectedVenueId);
            if (venue) {
                google.maps.event.trigger(venue, 'click');
            }
        }

        $.fn.csGoogleMapsHelper.setVenueEvents(id);
    };

    // set the common click event to all the venues
    $.fn.csGoogleMapsHelper.setVenueEvents = function(id) {
        for (var i in $.fn.csGoogleMapsHelper.markers) {
            google.maps.event.addListener($.fn.csGoogleMapsHelper.markers[i], 'click', function(event){
                $.fn.csGoogleMapsHelper.setVenueInput(id, this);
            });
        }
    };

    // show the clustering (grouping of markers)
    $.fn.csGoogleMapsHelper.showClustered = function(id, options) {
        // show clustered
        var clustered = new MarkerClusterer($.fn.csGoogleMapsHelper.map[id], $.fn.csGoogleMapsHelper.markers, options);
        return clustered;
    };

    $.fn.csGoogleMapsHelper.settings = {};
    $.fn.csGoogleMapsHelper.map = {};
    $.fn.csGoogleMapsHelper.infoWindow = null;
    $.fn.csGoogleMapsHelper.markers = [];
})(jQuery);

Его использование выглядит следующим образом (на самом деле не совсем так, потому что есть PHP-оболочка для автоматизации всего одним вызовом, но в основном):

$js = "$('#$id').csGoogleMapsHelper($jsOptions);\n";

if ($this->venues !== null) {
    foreach ($this->venues as $row) {
        $data = GoogleMapsHelper::getVenueMarkerOptionsJs($row);
        $js .= "$.fn.csGoogleMapsHelper.createMarker('$id', $data, true);\n";
    }
}

$js .= "$.fn.csGoogleMapsHelper.finalize('$id');\n";
echo $js;

Проблемы вышеупомянутой реализации состоят в том, что я не люблю хранить хэш-карту для «настроек» и «карт»

$id идентификатор элемента DIV, где карта инициализирована. Он используется в качестве ключа в .map, а в .settings есть карты, где я храню настройки и экземпляр GoogleMaps MapObject для каждого инициализированного такого GoogleMaps на странице.$jsOptions а также$data из кода PHP являются объектами JSON.

Теперь мне нужно иметь возможность создать экземпляр GoogleMapsHelper, который содержит свои собственные настройки и объект карты GoogleMaps, чтобы после его инициализации на определенном элементе (по его идентификатору) я мог повторно использовать этот экземпляр. Но если я инициализирую его для N элементов на странице, каждый из них должен иметь собственную конфигурацию, объект карты и т. Д.

Я не настаиваю на том, что это реализовано как плагин jQuery! Я настаиваю на том, что он гибкий и расширяемый, потому что я буду использовать его в большом проекте с более чем дюжиной запланированных в настоящее время различных экранов, где он будет использоваться, поэтому через несколько месяцев изменение его интерфейса использования станет кошмаром для рефакторинга всего проекта.

Я добавлю награду за это.

Ответы на вопрос(7)

Ваш ответ на вопрос