PageSourceSearch

https://mjcc.ru/wp-content/themes/mjcc/js/geolocation-button.js

js mjcc.ru collected 2026-10-02 07:16:48 UTC 10,484 bytes, 254 lines download raw bytes

1/**
2 * Класс кнопки определения местоположения пользователя.
3 * с помощью Geolocation API.
4 * @see http://www.w3.org/TR/geolocation-API/
5 * @class
6 * @name GeolocationButton
7 * @param {Object} params Данные для кнопки и параметры к Geolocation API.
8 * @param {Object} options Опции кнопки.
9 */
10function GeolocationButton(params, options) {
11    GeolocationButton.superclass.constructor.call(this, params, options);
12
13    // Расширяем опции по умолчанию теми, что передали в конструкторе.
14    this._options = ymaps.util.extend({
15        // Не центрировать карту.
16        noCentering: false,
17        // Не ставить метку.
18        noPlacemark: false,
19        // Не показывать точность определения местоположения.
20        noAccuracy: false,
21        // Режим получения наиболее точных данных.
22        enableHighAccuracy: true,
23        // Максимальное время ожидания ответа (в миллисекундах).
24        timeout: 10000,
25        // Максимальное время жизни полученных данных (в миллисекундах).
26        maximumAge: 1000
27    }, params.geolocationOptions);
28}
29
30ymaps.ready(function () {
31    ymaps.util.augment(GeolocationButton, ymaps.control.Button, {
32        /**
33         * Метод будет вызван при добавлении кнопки на карту.
34         * @function
35         * @name GeolocationButton.onAddToMap
36         * @param {ymaps.Map} map Карта на которую добавляется кнопка.
37         */
38        onAddToMap: function () {
39            GeolocationButton.superclass.onAddToMap.apply(this, arguments);
40
41            ymaps.option.presetStorage.add('geolocation#icon', {
42                iconImageHref: 'man.png',
43                iconImageSize: [27, 26],
44                iconImageOffset: [-10, -24]
45            });
46
47            this.hint = new GeolocationButtonHint(this);
48            // Обрабатываем клик на кнопке.
49            this.events.add('click', this._onBtnClick, this);
50        },
51        /**
52         * Метод будет вызван при удалении кнопки с карты.
53         * @function
54         * @name GeolocationButton.onRemoveFromMap
55         * @param {ymaps.Map} map Карта с которой удаляется кнопка.
56         */
57        onRemoveFromMap: function () {
58            this.events.remove('click', this._onBtnClick, this);
59            this.hint = null;
60            ymaps.option.presetStorage.remove('geolocation#icon');
61
62            GeolocationButton.superclass.onRemoveFromMap.apply(this, arguments);
63        },
64        /**
65         * Обработчик клика на кнопке.
66         * @function
67         * @private
68         * @name GeolocationButton._onBtnClick
69         * @param {ymaps.Event} e Объект события.
70         */
71        _onBtnClick: function (e) {
72            // Меняем иконку кнопки на прелоадер.
73            this.toggleIconImage('loader.gif');
74
75            if(navigator.geolocation) {
76                // Запрашиваем текущие координаты устройства.
77                navigator.geolocation.getCurrentPosition(
78                    ymaps.util.bind(this._onGeolocationSuccess, this),
79                    ymaps.util.bind(this._onGeolocationError, this),
80                    this._options
81                );
82            }
83            else {
84                this.handleGeolocationError('Ваш броузер не поддерживает GeolocationAPI.');
85            }
86        },
87
88        /**
89         * Обработчик успешного завершения геолокации.
90         * @function
91         * @private
92         * @name GeolocationButton._onGeolocationSuccess
93         * @param {Object} position Объект, описывающий текущее местоположение.
94         */
95        _onGeolocationSuccess: function (position) {
96            this.handleGeolocationResult(position);
97            // Меняем иконку кнопки обратно
98            this.toggleIconImage('wifi.png');
99        },
100        /**
101         * Обработчик ошибки геолокации.
102         * @function
103         * @name GeolocationButton._onGeolocationError
104         * @param {Object} error Описание причины ошибки.
105         */
106        _onGeolocationError: function (error) {
107            this.handleGeolocationError('Точное местоположение определить не удалось.');
108            // Меняем иконку кнопки обратно.
109            this.toggleIconImage('wifi.png');
110
111            if(console) {
112                console.warn('GeolocationError: ' + GeolocationButton.ERRORS[error.code - 1]);
113            }
114        },
115        /**
116         * Обработка ошибки геолокации.
117         * @function
118         * @name GeolocationButton.handleGeolocationError
119         * @param {Object|String} err Описание ошибки.
120         */
121        handleGeolocationError: function (err) {
122            this.hint
123                .show(err.toString())
124                .hide(2000);
125        },
126        /**
127         * Меняет иконку кнопки.
128         * @function
129         * @name GeolocationButton.toggleIconImage
130         * @param {String} image Путь до изображения.
131         */
132        toggleIconImage: function (image) {
133            this.data.set('image', image);
134        },
135        /**
136         * Обработка результата геолокации.
137         * @function
138         * @name GeolocationButton.handleGeolocationResult
139         * @param {Object} position Результат геолокации.
140         */
141        handleGeolocationResult: function (position) {
142            var location = [position.coords.latitude, position.coords.longitude],
143                accuracy = position.coords.accuracy,
144                map = this.getMap(),
145                options = this._options,
146                placemark = this._placemark,
147                circle = this._circle;
148
149            // Смена центра карты (если нужно)
150            if(!options.noCentering) {
151                map.setCenter(location, 15, {
152                    checkZoomRange: true
153                });
154            }
155
156            // Установка метки по координатам местоположения (если нужно).
157            if(!options.noPlacemark) {
158                // Удаляем старую метку.
159                if(placemark) {
160                    map.geoObjects.remove(placemark);
161                }
162                this._placemark = placemark = new ymaps.Placemark(location, {}, { preset: 'geolocation#icon' });
163                map.geoObjects.add(placemark);
164                // Показываем адрес местоположения в хинте метки.
165                this.getLocationInfo(placemark);
166            }
167
168            // Показываем точность определения местоположения (если нужно).
169            if(!options.noAccuracy) {
170                // Удаляем старую точность.
171                if(circle) {
172                    map.geoObjects.remove(circle);
173                }
174                this._circle = circle = new ymaps.Circle([location, accuracy], {}, { opacity: 0.5 });
175                map.geoObjects.add(circle);
176            }
177        },
178        /**
179         * Получение адреса по координатам метки.
180         * @function
181         * @name GeolocationButton.getLocationInfo
182         * @param {ymaps.Placemark} point Метка для которой ищем адрес.
183         */
184        getLocationInfo: function (point) {
185            ymaps.geocode(point.geometry.getCoordinates())
186                .then(function (res) {
187                    var result = res.geoObjects.get(0);
188
189                    if(result) {
190                        point.properties.set('hintContent', result.properties.get('name'));
191                    }
192                });
193        }
194    });
195});
196
197/**
198 * Человекопонятное описание кодов ошибок.
199 * @static
200 */
201GeolocationButton.ERRORS = [
202    'permission denied',
203    'position unavailable',
204    'timeout'
205];
206
207/**
208 * Класс хинта кнопки геолокации, будем использовать для отображения ошибок.
209 * @class
210 * @name GeolocationButtonHint
211 * @param {GeolocationButton} button Экземпляр класса кнопки.
212 */
213function GeolocationButtonHint(button) {
214    this._button = button;
215    this._map = button.getMap();
216    this._offset = { left: 35, top: -18 };
217}
218/**
219 * Отображает хинт справа от кнопки.
220 * @function
221 * @name GeolocationButtonHint.show
222 * @param {String} text
223 * @returns {GeolocationButtonHint}
224 */
225GeolocationButtonHint.prototype.show = function (text) {
226    var map = this._map,
227        offset = this._offset,
228        buttonPagePixels = this._button.getLayout().getElement().getBoundingClientRect(),
229        pagePixels = [buttonPagePixels.left + offset.left, buttonPagePixels.top + offset.top],
230        globalPixels = map.converter.pageToGlobal(pagePixels),
231        position = map.options.get('projection').fromGlobalPixels(globalPixels, map.getZoom());
232
233    this._hint = map.hint.show(position, text);
234
235    return this;
236};
237/**
238 * Прячет хинт с нужной задержкой.
239 * @function
240 * @name GeolocationButtonHint.hide
241 * @param {Number} timeout Задержка в миллисекундах.
242 * @returns {GeolocationButtonHint}
243 */
244GeolocationButtonHint.prototype.hide = function (timeout) {
245    var hint = this._hint;
246
247    if(hint) {
248        setTimeout(function () {
249            hint.hide();
250        }, timeout);
251    }
252
253    return this;
254};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.