как по клику обновить все метки, а выбранной дать другие параметры, сбросив предыдущий выбор
Я по клику отправляю запрос на сервер, в ответе получаю пункты выдачи заказов через курьерские службы. Дальше я эти пункты расставляю по карте, а под картой у меня список всех пунктов. Но суть не в этом.
По клику на метку я меняю у неё иконку. Всего у меня 4 службы, для каждой по 2 иконки (активна/неактивна). Если я выбираю первую метку, иконка меняется. Когда я кликаю на другую метку, иконка у первой не меняется обратно. Визуально получается на карте две пункта с иконками в состоянии active.
как мне по клику менять у предыдущей метки состоянии иконки до клика?
var pointsElement = $("#points").empty().show();
$(".btn-search-delivery").on("click", function() {
var pointsElement = $("#points").empty();
$.ajax({
type: "POST",
url: "https://site.ru/subscribe/delivery-methods",
data: {
"subscribe_form[category_id]": "13",
"subscribe_form[first_catalog_id]": "76022",
"subscribe_form[count_in_package]": "2",
"subscribe_form[address_post_index]": "156000",
"subscribe_form[address_country]": "Россия",
"subscribe_form[address_region]": "Московская",
"subscribe_form[address_city]": "Москва",
"subscribe_form[payment_method]": "1"
},
dataType: "json",
success: function(data) {
var myMapAll = null;
var clusterer = new ymaps.Clusterer({
preset: 'islands#blueDotIcon',
groupByCoordinates: false,
clusterDisableClickZoom: false,
gridSize: 40
});
var geoObjects = [];
/** ymaps.ready function() **/
ymaps.ready(function() {
/** массив меток в списке **/
$.each(data.pickupPoints, function(key, entry) {
pointsElement.append($('<div class="col-12" id="pickup-item-' + entry.id + '"><label id="label' + entry.id + '" for="input' + entry.id + '" class="label-pickup-method"><input type="radio" name="pickup-method" id="input' + entry.id + '" value="' + entry.id + '"><div class="content-box"><div class="dot"></div><div class="title-box"><div class="title">' + entry.name + '<span class="price">' + entry.cost + ' ₽</span></div><div class="subtitle">' + entry.address + '</div></div><div class="select-box" data-dismiss="modal"><div class="select" aria-hidden="true">Выбрать</div></div></div></label></div>'))
})
/** ./массив меток в списке **/
/** обработчик кликов по меткам в списке **/
$(".pickup-method-box input[name=pickup-method]").change(function() {
$(".label-pickup-method").removeClass("selected");
$(this).parent().addClass("selected")
})
/** ./обработчик кликов по меткам в списке **/
$("#map").empty();
let geo_lat = $("input[name='subscribe_form[data_geo_lat]']").val()
let geo_lon = $("input[name='subscribe_form[data_geo_lon]']").val()
/** карта **/
myMapAll = new ymaps.Map('map', {
center: [geo_lat, geo_lon],
zoom: 13
}, {
searchControlProvider: 'yandex#search'
});
/** ./карта **/
/** массив меток на карте **/
$.each(data.pickupPoints, function(i, v) {
var placemark = new ymaps.Placemark([v.latitude, v.longitude], {
hintContent: v.name + " • " + v.address,
id: v.id,
deliveryServiceId: v.deliveryServiceId
}, {
iconLayout: 'default#image',
iconLayoutColor: '#004FC5',
iconImageHref: 'http://127.0.0.1:5500/img/modal/delivery/ya-' + v.deliveryServiceId + '.png',
iconImageSize: [40, 40],
iconImageOffset: [-20, -20]
});
placemark.events.add('click', clickOnPlacemark);
geoObjects[i] = placemark;
clusterer.add(geoObjects);
myMapAll.geoObjects.add(clusterer);
})
/** ./массив меток на карте **/
/** function clickOnPlacemark **/
function clickOnPlacemark(e) {
var target = e.get('target');
var placemark = e.get('target');
var id = placemark.properties.get('id');
var deliveryServiceId = placemark.properties.get('deliveryServiceId');
placemark.options.set({
iconImageHref: 'http://127.0.0.1:5500/img/modal/delivery/ya-' + deliveryServiceId + '-pickup.png',
iconImageSize: [40, 58],
iconImageOffset: [-20, -38]
})
myMapAll.panTo(target.geometry.getCoordinates(), {useMapMargin: true});
$("input[name=pickup-method]:checked").prop('checked', false);
$(".label-pickup-method").removeClass("selected");
$("#input" + id).prop('checked', true);
$("#label" + id).addClass("selected");
var $container = $('.pickup-method-box-wrap');
var $scrollTo = $('#pickup-item-' + id);
$container.animate({
scrollTop: $scrollTo.offset().top - $container.offset().top + $container.scrollTop()
})
}
/** ./function clickOnPlacemark **/
})
/** ./ymaps.ready function() **/
}
})
})
Ответы (1 шт):
Описанную задачу можно решить с использованием менеджера объектов (https://tech.yandex.ru/maps/jsapi/doc/2.1/ref/reference/ObjectManager-docpage/ ).
Вот пример с тремя менеджерами (для каждого типа меток): https://jsfiddle.net/naivv/5dvf6ag2/
Также можно посмотреть на коллекции геообъектов (https://tech.yandex.ru/maps/jsapi/doc/2.1/ref/reference/GeoObjectCollection-docpage/ ), вот пример в песочнице: https://tech.yandex.ru/maps/jsbox/2.1/geo_object_collection
ymaps.ready(init);
function init() {
var myMap = new ymaps.Map('map', {
center: [55.76, 37.64],
zoom: 10
}, {
searchControlProvider: 'yandex#search'
}),
// https://tech.yandex.ru/maps/jsapi/doc/2.1/ref/reference/ObjectManager-docpage/
greenObjectManager = new ymaps.ObjectManager({
// Чтобы метки начали кластеризоваться, выставляем опцию.
clusterize: true,
// ObjectManager принимает те же опции, что и кластеризатор.
gridSize: 32,
//clusterDisableClickZoom: true
}),
greenObjPreset = 'islands#greenIcon', // стиль метки по умолчанию
blueObjectManager = new ymaps.ObjectManager({
// Чтобы метки начали кластеризоваться, выставляем опцию.
clusterize: true,
// ObjectManager принимает те же опции, что и кластеризатор.
gridSize: 32,
//clusterDisableClickZoom: true
}),
blueObjPreset = 'islands#blueIcon', // стиль метки по умолчанию
blackObjectManager = new ymaps.ObjectManager({
// Чтобы метки начали кластеризоваться, выставляем опцию.
clusterize: true,
// ObjectManager принимает те же опции, что и кластеризатор.
gridSize: 32,
//clusterDisableClickZoom: true
}),
blackObjPreset = 'islands#blackIcon', // стиль метки по умолчанию
selectedObjId, // id выделенного в данный момент объекта
redObjPreset = 'islands#redDotIcon'; // стиль выделенной метки
// Чтобы задать опции одиночным объектам и кластерам,
// обратимся к дочерним коллекциям ObjectManager.
greenObjectManager.objects.options.set({
preset: greenObjPreset,
hasBalloon: false // в данном примере мне балун не нужен
});
greenObjectManager.clusters.options.set('preset', 'islands#greenClusterIcons');
myMap.geoObjects.add(greenObjectManager);
blueObjectManager.objects.options.set({
preset: blueObjPreset,
hasBalloon: false // в данном примере мне балун не нужен
});
blueObjectManager.clusters.options.set('preset', 'islands#blueClusterIcons');
myMap.geoObjects.add(blueObjectManager);
blackObjectManager.objects.options.set({
preset: blackObjPreset,
hasBalloon: false // в данном примере мне балун не нужен
});
blackObjectManager.clusters.options.set('preset', 'islands#blackClusterIcons');
myMap.geoObjects.add(blackObjectManager);
// https://tech.yandex.ru/maps/jsapi/doc/2.1/ref/reference/objectManager.ObjectCollection-docpage/
// Обработка события, возникающего при щелчке
// левой кнопкой мыши на объекте
greenObjectManager.objects.events.add('click', function(e) {
//var target = e.get('target');
var objectId = e.get('objectId');
// ранее выделенной метке назначаем стиль по умолчанию
if (selectedObjId) {
greenObjectManager.objects.setObjectOptions(selectedObjId, {
preset: greenObjPreset
});
blueObjectManager.objects.setObjectOptions(selectedObjId, {
preset: blueObjPreset
});
blackObjectManager.objects.setObjectOptions(selectedObjId, {
preset: blackObjPreset
});
}
// подсвечиваем вновь выделенную метку
greenObjectManager.objects.setObjectOptions(objectId, {
preset: redObjPreset
});
selectedObjId = objectId;
});
blueObjectManager.objects.events.add('click', function(e) {
var objectId = e.get('objectId');
// ранее выделенной метке назначаем стиль по умолчанию
if (selectedObjId) {
greenObjectManager.objects.setObjectOptions(selectedObjId, {
preset: greenObjPreset
});
blueObjectManager.objects.setObjectOptions(selectedObjId, {
preset: blueObjPreset
});
blackObjectManager.objects.setObjectOptions(selectedObjId, {
preset: blackObjPreset
});
}
// подсвечиваем вновь выделенную метку
blueObjectManager.objects.setObjectOptions(objectId, {
preset: redObjPreset
});
selectedObjId = objectId;
});
blackObjectManager.objects.events.add('click', function(e) {
var objectId = e.get('objectId');
// ранее выделенной метке назначаем стиль по умолчанию
if (selectedObjId) {
greenObjectManager.objects.setObjectOptions(selectedObjId, {
preset: greenObjPreset
});
blueObjectManager.objects.setObjectOptions(selectedObjId, {
preset: blueObjPreset
});
blackObjectManager.objects.setObjectOptions(selectedObjId, {
preset: blackObjPreset
});
}
// подсвечиваем вновь выделенную метку
blackObjectManager.objects.setObjectOptions(objectId, {
preset: redObjPreset
});
selectedObjId = objectId;
});
$.ajax({
url: "https://api.myjson.com/bins/77e60"
}).done(function(data) {
greenObjectManager.add(data);
});
$.ajax({
url: "https://api.myjson.com/bins/125xmg"
}).done(function(data) {
blueObjectManager.add(data);
});
$.ajax({
url: "https://api.myjson.com/bins/12rd88"
}).done(function(data) {
blackObjectManager.add(data);
});
}
// https://tech.yandex.ru/maps/jsbox/2.1/geo_object_collection
<!DOCTYPE html>
<html>
<head>
<title>Оптимальное добавление множества меток</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!--
Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
-->
<script src="https://api-maps.yandex.ru/2.1/?lang=ru-RU&apikey=<ваш API-ключ>" type="text/javascript"></script>
<script src="https://yandex.st/jquery/2.2.3/jquery.min.js" type="text/javascript"></script>
<style>
html,
body,
#map {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
a {
color: #04b;
/* Цвет ссылки */
text-decoration: none;
/* Убираем подчеркивание у ссылок */
}
a:visited {
color: #04b;
/* Цвет посещённой ссылки */
}
a:hover {
color: #f50000;
/* Цвет ссылки при наведении на нее курсора мыши */
}
</style>
</head>
<body>
<div id="map"></div>
</body>
</html>