Создание приложения c OpenLayers без использования jQuery.UI

В предыдущем своем посте я описал, как создать виджет jQuery.UI как приложение, работающее с OpenLayers. Но как быть, если вы не используете компоненты jQuery.UI в своем приложении? Выхода два: подключить только ядро jQuery.UI (с фабрикой виджетов) или обойтись без этой библиотеки вовсе.

Эти же самые принципы можно применять для любого другого вашего приложения JS. Называются шаблоны так: «Модуль» и «Конструктор».

Часть 1. Создание виджета при помощи jQuery UI и ASP.NET MVC.
Часть 2. Создание приложения при помощи jQuery без jQuery UI.

Шаблоны JavaScript

Шаблон модуль вы наверняка встречали часто, если пользуетесь jQuery. Переменная $ инициализируется объектом jQuery. Такой вид шаблона называют «шаблон модуль с импортом переменных».

(function ($) {
})(jQuery);

Шаблон конструктор — один из оптимальных способов создания объекта определенного типа в JS. Не забываем, что функция в JS это тоже объект.

var Cat = function(name) {
  this.name = name;
   
    this.hello = function() {
       return this.name + 'say mewow.';
    }
}

// Usage:
var cat1 = new Cat("Simon");
console.log(cat1.hello());

Создаем приложение

Чтобы не порождать глобальные переменные, наше приложение будет расширением объекта jQuery. Для передачи и хранения параметров воспользуемся функцией jquery.extend(). Инициализацию объекта OpenLayers возьмем из первой части статей (см выше). Файл с нашим приложением назовем jquery.openMap.debug.js

/*!
 * OpenMap application
 * Based on jQuery and OpenLayers
 */
 
(function ($, OpenLayers) {
 
  $.fn.openMap = function (options) {

     var options = $.extend({
            name: 'openmap',
            imgPath: '/images/',
            center: {
                lon: 37.62428, // y
                lat: 55.75304, // x
                zoom: 9
            }
     }, options);
        
        // private options
      var po = {
          num: 0,
         el: null,
            map: null,
            mapnik: null,
            vlayer: null,
            controls: {
                toolbar: null,
                mouseposition: null,
              navigation: null,
               zoom: null
            }
     }
       
        // create layout
        po.el = $('<div/>').attr('id', options.name + '-map-generic-' + (po.num += 1))
            .css({
                width: '100%',
                height: '100%'
            });
        $(this).append(po.el);
     
        // setup OpenLayers
     OpenLayers.ImgPath = options.imgPath;
        var args = {
            theme: null,
            projection: new OpenLayers.Projection("EPSG:900913"), // Spherical Mercator Projection
            displayProjection: new OpenLayers.Projection("EPSG:4326"), // WGS 1984
            units: "m",
            numZoomLevels: 18,
            maxResolution: 156543.0339,
            maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508)
        }
        po.map = new OpenLayers.Map(po.el.attr('id'), args);
        po.mapnik = new OpenLayers.Layer.OSM('OSM');
        po.vlayer = new OpenLayers.Layer.Vector("Vector");
        po.map.addLayers([po.mapnik, po.vlayer]);

     po.controls.navigation = new OpenLayers.Control.Navigation();
       po.controls.zoom = new OpenLayers.Control.Zoom();
        po.controls.toolbar = new OpenLayers.Control.EditingToolbar(po.vlayer);
        po.controls.mouseposition = new OpenLayers.Control.MousePosition();

        $.each(po.controls, function (key, value) {
            po.map.addControl(value);
        });

        po.map.setCenter(new OpenLayers.LonLat(options.center.lon, options.center.lat) // Center of the map
            .transform(po.map.displayProjection, po.map.projection),
            options.center.zoom); // zoom level
    }
 
})(jQuery, OpenLayers);

Прошел уже год с тех пор, как автор (т.е. я) похерил оригинальный текст статьи на одном из бесплатных хостингов. Сейчас я бы сделал это так (вы не найдете этот код в исходниках статьи).

/*!
 * OpenMap application
 * Based on jQuery and OpenLayers
 */
 
(function ($, OpenLayers) {
   //ecma5 strict mode
 "use strict"

    // private options for all objects
  var privateOptions = {
      name: 'openmap'
     // todo: implement options
  }

   // ol args the same for all objects
 var olArgs = {
          theme: null
     // todo: implement openlayers args
  }

   // objects constructor
  var OpenMap = function (el,options) {
       // this object will be different for each application
       // and can't be accessible from new methods
     var po = {
          // todo: implement private variables
        }

       // this function will be called before you create OL
        var createLayout = function() {
         // create layout
            this.el = $('<div/>').attr('id', this.options.name + '-map-generic-' + (po.num += 1))
         .css({
              width: '100%',
              height: '100%'
          });
         $(this.parentEl).append(this.el);
       }

       // extend default options without overriding
        this.options = $.extend({}, privateOptions, options);

       // parent DOM element
       this.parentEl = el;
     this.el = null;

     // this method will be executed just after app has been created
     var create = function () {
          createLayout.apply(this, []);
           // todo: initialize openlayers object
       }

       create.apply(this, []);
 }

   // jquery extension
 $.fn.openMap = function (options) {
     return new OpenMap(this,options); // create object and assign dom element
   }
})(jQuery, OpenLayers);

Страница HTML для нашего приложения. Используем библиотеку Modernizr и HTML5 Boilerplate. Вместо толстой библиотеки OpenLayers используем light-версию (вы можете ее скомпоновать с контролами и минифицировать для продакшн-версии) с необходимыми контролами.

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <title>jQuery OpenLayers application</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width">

        <!-- Place favicon.ico and apple-touch-icon.png in the root directory -->

      <link rel="stylesheet" href="css/ol/style.css">
       <link rel="stylesheet" href="css/main.css">
       <style type="text/css">
       * {margin:0;padding:0}
      html, body {height:100%;}
       </style>
        <script src="js/vendor/modernizr-2.6.2.min.js"></script>
    </head>
    <body>
        <!--[if lt IE 7]>
            <p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google Chrome Frame</a> to improve your experience.</p>
        <![endif]-->

        <div id="mapwrapper" style="width:100%;height:100%"></div>

        <script src="js/vendor/jquery-1.8.2.min.js"></script>
      <script src="js/vendor/OpenLayers/OpenLayers.light.debug.js"></script>
      <script src="js/vendor/OpenLayers/Handler/Point.js"></script>
       <script src="js/vendor/OpenLayers/Handler/Path.js"></script>
        <script src="js/vendor/OpenLayers/Handler/Polygon.js"></script>
     <script src="js/vendor/OpenLayers/Control/EditingToolbar.js"></script>
      <script src="js/vendor/OpenLayers/Control/DrawFeature.js"></script>
     <script src="js/vendor/OpenLayers/Control/MousePosition.js"></script>
       
        <script src="js/jquery.openMap.debug.js"></script>
        <!--<script src="js/jquery.openMap.min.js"></script>-->
     <script type="text/javascript">
       jQuery(document).ready(function ($) {
           $('#mapwrapper').openMap({
              imgPath: 'img/ol/'
          });
     });
     </script>
    </body>
</html>

В данном примере я использовал библиотеку OpenLayers v2.12 (данная версия имеет достаточно аккуратные контролы навигации, поэтому дополнительные стили использовать нет необходимости). Посмотреть результат можно на странице github http://towa48.github.io/jquery-openlayers-app/

Лицензия

Статья, а так же связанные с ней файлы и исходный код доступны по лицензии Apache License 2.0

Исходный код

Исходный код можно посмотреть на github https://github.com/towa48/jquery-openlayers-app/