Добавление всплывающего окна на карту

В этой статье объясняется, как добавить всплывающее окно в точку на карте.

Изучение кода

Следующий код добавляет функцию точки с свойствами namedescription на карту с помощью слоя символов. Экземпляр класса Popup создан, но не отображается. События мыши добавляются на слой символов для активации открытия и закрытия всплывающего окна. При наведении указателя мыши свойство всплывающего окна position обновляется с указанием позиции маркера, а параметр content обновляется с помощью HTML-кода, который заключает в оболочку name и description свойства функции Point, на которую наведен указатель мыши. Затем всплывающее окно отображается на карте с помощью его open функции.

//Define an HTML template for a custom popup content laypout.
var popupTemplate = '<div class="customInfobox"><div class="name">{name}</div>{description}</div>';

//Create a data source and add it to the map.
var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);

dataSource.add(new atlas.data.Feature(new atlas.data.Point([-122.1333, 47.63]), {
  name: 'Microsoft Building 41', 
  description: '15571 NE 31st St, Redmond, WA 98052'
}));

//Create a layer to render point data.
var symbolLayer = new atlas.layer.SymbolLayer(dataSource);

//Add the polygon and line the symbol layer to the map.
map.layers.add(symbolLayer);

//Create a popup but leave it closed so we can update it and display it later.
popup = new atlas.Popup({
  pixelOffset: [0, -18],
  closeButton: false
});

//Add a hover event to the symbol layer.
map.events.add('mouseover', symbolLayer, function (e) {
  //Make sure that the point exists.
  if (e.shapes && e.shapes.length > 0) {
    var content, coordinate;
    var properties = e.shapes[0].getProperties();
    content = popupTemplate.replace(/{name}/g, properties.name).replace(/{description}/g, properties.description);
    coordinate = e.shapes[0].getCoordinates();

    popup.setOptions({
      //Update the content of the popup.
      content: content,

      //Update the popup's position with the symbol's coordinate.
      position: coordinate

    });
    //Open the popup.
    popup.open(map);
  }
});

map.events.add('mouseleave', symbolLayer, function (){
  popup.close();
});

Повторное использование всплывающего окна с несколькими точками

В некоторых случаях лучшим подходом является создание одного всплывающего окна и его повторное использование. Например, у вас может быть большое количество точек и требуется одновременно отображать только одно всплывающее окно. Путем повторного использования всплывающего текста, число элементов DOM, созданных приложением, значительно снизится, обеспечивая более высокую производительность. В следующем примере создаются 3-точечные функции. Если выбрать любой из них, всплывающее окно отображается с содержимым для этой точки функции.

Полный функциональный пример, показывающий, как создать одно всплывающее окно и повторно использовать его, а не создавать всплывающее окно для каждой функции точки, см. в статье "Повторное использование всплывающих окон с несколькими закреплениями" в azure Карты Samples. Исходный код для этого примера см. в разделе "Повторное использование всплывающего окна с несколькими пин-кодами".

A screenshot of map with three blue pins.

Настройка всплывающего окна

По умолчанию всплывающее окно имеет белый фон, стрелку указателя внизу и кнопку Закрыть в правом верхнем углу. В следующем примере цвет фона изменяется на черный с помощью fillColor параметра всплывающего окна. Кнопка Закрыть удаляется путем присвоения CloseButton параметру значения false. HTML-содержимое всплывающего окна использует отступ от 10 пикселей от края всплывающего окна. Текст становится белым, поэтому он хорошо отображается на черном фоне.

Полный функциональный пример, показывающий, как настроить внешний вид всплывающего окна, см. в статье "Настройка всплывающего окна" в azure Карты Samples. Исходный код для этого примера см. в разделе "Настройка исходного кода всплывающего окна".

A screenshot of map with a custom popup in the center of the map with the caption 'hello world'.

Добавить всплывающие шаблоны для сопоставления

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

Примечание.

По умолчанию все содержимое, которое отображается, использует шаблон всплывающего окна, изолированный внутри iframe в качестве функции безопасности. Однако существуют определенные ограничения:

  • Отключены все функции скриптов, форм, блокировки указателя и верхней панели навигации. При щелчке ссылки могут открываться в новой вкладке.
  • Более старые браузеры, которые не поддерживают параметр srcdoc в iframe, смогут визуализировать лишь небольшой объем содержимого.

Если вы доверяете данным, загружаемым во всплывающие окна, и потенциально хотите, чтобы эти загружаемые во всплывающие окна скрипты могли получить доступ к приложению, вы можете отключить эту настройку, присвоив параметру sandboxContent popup templates значение false.

Строковый шаблон

Шаблон строки заменяет заполнители значениями свойств компонента. Свойствам компонента не обязательно присваивать значение типа String. Например, value1 содержит целое число. Затем эти значения передаются в свойство Content объекта popupTemplate.

numberFormatПараметр задает формат отображаемого числа. numberFormat Если этот параметр не указан, код использует формат даты даты всплывающих окон. numberFormatПараметр форматирует числа с помощью функции Number.toLocaleString. Для форматирования больших чисел рекомендуется использовать numberFormat параметр с функциями из NumberFormat. Format. Например, следующий фрагмент кода используется maximumFractionDigits для ограничения количества цифр дроби до двух.

Примечание.

Существует только один способ, в котором шаблон строки может отображать изображения. Сначала строковый шаблон должен содержать тег Image. Значение, передаваемое в тег Image, должно быть URL-адресом изображения. Затем шаблон строки должен иметь значение isImage true в HyperLinkFormatOptions. isImageПараметр указывает, что гиперссылка предназначена для изображения, и Гиперссылка будет загружена в тег Image. При щелчке гиперссылки откроется изображение.

var templateOptions = {
  content: 'This template uses a string template with placeholders.<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array value [2] = {arrayValue/2}',
  numberFormat: {
    maximumFractionDigits: 2
  }
};

var feature = new atlas.data.Feature(new atlas.data.Point([0, 0]), {
    title: 'Template 1 - String template',
    value1: 1.2345678,
    value2: {
        subValue: 'Pizza'
    },
    arrayValue: [3, 4, 5, 6]
});

var popup = new atlas.Popup({
  content: atlas.PopupTemplate.applyTemplate(feature.properties, templateOptions),
  position: feature.geometry.coordinates
});

PropertyInfo, шаблон

Шаблон PropertyInfo отображает доступные свойства компонента. Параметр label указывает текст для отображения пользователю. Если label это не указано, отображается гиперссылка. Если гиперссылка является изображением, отображается значение, назначенное тегу ALT. Указывает dateFormat формат даты и, если формат даты не указан, то дата отображается в виде строки. hyperlinkFormatПараметр отображает ссылки, которые можно щелкать, так же как и email при отображении просматриваемых адресов электронной почты.

Перед тем как шаблон PropertyInfo отобразит свойства для конечного пользователя, он рекурсивно проверяет, что для этой функции действительно определены свойства. Он также игнорирует отображение свойств Style и Title. Например, он не отображает color, size, anchorи strokeOpacityvisibility. Таким образом, после завершения проверки пути свойства в серверной части шаблон PropertyInfo отображает содержимое в табличном формате.

var templateOptions = {
  content: [
    {
        propertyPath: 'createDate',
        label: 'Created Date'
    },
    {
        propertyPath: 'dateNumber',
        label: 'Formatted date from number',
        dateFormat: {
          weekday: 'long',
          year: 'numeric',
          month: 'long',
          day: 'numeric',
          timeZone: 'UTC',
          timeZoneName: 'short'
        }
    },
    {
        propertyPath: 'url',
        label: 'Code samples',
        hideLabel: true,
        hyperlinkFormat: {
          lable: 'Go to code samples!',
          target: '_blank'
        }
    },
    {
        propertyPath: 'email',
        label: 'Email us',
        hideLabel: true,
        hyperlinkFormat: {
          target: '_blank',
          scheme: 'mailto:'
        }
    }
  ]
};

var feature = new atlas.data.Feature(new atlas.data.Point([0, 0]), {
    title: 'Template 2 - PropertyInfo',
    createDate: new Date(),
    dateNumber: 1569880860542,
    url: 'https://samples.azuremaps.com/',
    email: 'info@microsoft.com'
}),

var popup = new atlas.Popup({
  content: atlas.PopupTemplate.applyTemplate(feature.properties, templateOptions),
  position: feature.geometry.coordinates
});

Несколько шаблонов содержимого

Функция также может отображать содержимое с помощью сочетания шаблона String и шаблона PropertyInfo. В этом случае шаблон строки подготавливает значения заполнителей на белом фоне. И шаблон PropertyInfo визуализирует изображение с полной шириной внутри таблицы. Свойства в этом образце похожи на свойства, описанные в предыдущих примерах.

var templateOptions = {
  content: [
    'This template has two pieces of content; a string template with placeholders and a array of property info which renders a full width image.<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array value [2] = {arrayValue/2}',
    [{
      propertyPath: 'imageLink',
      label: 'Image',
      hideImageLabel: true,
      hyperlinkFormat: {
        isImage: true
      }
    }]
  ],
  numberFormat: {
    maximumFractionDigits: 2
  }
};

var feature = new atlas.data.Feature(new atlas.data.Point([0, 0]), {
    title: 'Template 3 - Multiple content template',
    value1: 1.2345678,
    value2: {
    subValue: 'Pizza'
    },
    arrayValue: [3, 4, 5, 6],
    imageLink: 'https://samples.azuremaps.com/images/Pike_Market.jpg'
});

var popup = new atlas.Popup({
  content: atlas.PopupTemplate.applyTemplate(feature.properties, templateOptions),
  position: feature.geometry.coordinates
});

Точки без определенного шаблона

Если шаблон всплывающего окна не определен как строковый шаблон, шаблон PropertyInfo или сочетание обоих параметров, то используются параметры по умолчанию. Когда title Свойства и description являются единственными назначенными свойствами, в шаблоне всплывающего окна отображается белый фон, кнопка закрытия в правом верхнем углу. А на небольших и средних экранах в нижней части отображается стрелка. Параметры по умолчанию отображают внутри таблицы все свойства, кроме title и description. Даже при возврате к значениям по умолчанию шаблон Popup по-прежнему может управляться программно. Например, пользователи могут отключить обнаружение гиперссылок, и параметры по умолчанию будут применяться к другим свойствам.

После выполнения можно выбрать точки на карте, чтобы увидеть всплывающее окно. На карте есть точка для каждого из следующих шаблонов всплывающих окон: шаблон String, шаблон PropertyInfo и несколько шаблонов контента. Также есть три пункта, демонстрирующие отрисовку шаблонов с использованием параметров по умолчанию.

function InitMap()
{
  var map = new atlas.Map('myMap', {
      zoom: 2,
      view: "Auto",

    //Add authentication details for connecting to Azure Maps.
      authOptions: {
          authType: 'subscriptionKey',
          subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
      }
  });

  //Wait until the map resources are ready.
  map.events.add('ready', function() {
    //Create a data source and add it to the map.
    var datasource = new atlas.source.DataSource();
    map.sources.add(datasource);

    //Add sample data.
    datasource.add([
      new atlas.data.Feature(new atlas.data.Point([-20, 20]), {
        title: 'No template - title/description',
        description: 'This point doesn\'t have a template defined, fallback to title and description properties.'
      }),

      new atlas.data.Feature(new atlas.data.Point([20, 20]), {
        title: 'No template - property table',
        message: 'This point doesn\'t have a template defined, fallback to title and table of properties.',
        randomValue: 10,
        url: 'https://samples.azuremaps.com/',
        imageLink: 'https://samples.azuremaps.com/images/Pike_Market.jpg',
        email: 'info@microsoft.com'
      }),

      new atlas.data.Feature(new atlas.data.Point([40, 0]), {
        title: 'No template - hyperlink detection disabled',
        message: 'This point doesn\'t have a template defined, fallback to title and table of properties.',
        randomValue: 10,
        url: 'https://samples.azuremaps.com/',
        email: 'info@microsoft.com',
        popupTemplate: {
          detectHyperlinks: false
        }
      }),

      new atlas.data.Feature(new atlas.data.Point([-20, -20]), {
        title: 'Template 1 - String template',
        value1: 1.2345678,
        value2: {
          subValue: 'Pizza'
        },
        arrayValue: [3, 4, 5, 6],
        popupTemplate: {
          content: 'This template uses a string template with placeholders.<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array value [2] = {arrayValue/2}',
          numberFormat: {
            maximumFractionDigits: 2
          }
        }
      }),

      new atlas.data.Feature(new atlas.data.Point([20, -20]), {
        title: 'Template 2 - PropertyInfo',
        createDate: new Date(),
        dateNumber: 1569880860542,
        url: 'https://samples.azuremaps.com/',
        email: 'info@microsoft.com',
        popupTemplate: {
          content: [{
            propertyPath: 'createDate',
            label: 'Created Date'
          },
                    {
                      propertyPath: 'dateNumber',
                      label: 'Formatted date from number',
                      dateFormat: {
                        weekday: 'long',
                        year: 'numeric',
                        month: 'long',
                        day: 'numeric',
                        timeZone: 'UTC',
                        timeZoneName: 'short'
                      }
                    },
                    {
                      propertyPath: 'url',
                      label: 'Code samples',
                      hideLabel: true,
                      hyperlinkFormat: {
                        lable: 'Go to code samples!',
                        target: '_blank'
                      }
                    },
                    {
                      propertyPath: 'email',
                      label: 'Email us',
                      hideLabel: true,
                      hyperlinkFormat: {
                        target: '_blank',
                        scheme: 'mailto:'
                      }
                    }
                    ]
        }
      }),

      new atlas.data.Feature(new atlas.data.Point([0, 0]), {
        title: 'Template 3 - Multiple content template',
        value1: 1.2345678,
        value2: {
          subValue: 'Pizza'
        },
        arrayValue: [3, 4, 5, 6],
        imageLink: 'https://samples.azuremaps.com/images/Pike_Market.jpg',
        popupTemplate: {
          content: [
            'This template has two pieces of content; a string template with placeholders and a array of property info which renders a full width image.<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array value [2] = {arrayValue/2}',
            [{
              propertyPath: 'imageLink',
              label: 'Image',
              hideImageLabel: true,
              hyperlinkFormat: {
                isImage: true
              }
            }]
          ],
          numberFormat: {
            maximumFractionDigits: 2
          }
        }
      }),
    ]);

    //Create a layer that defines how to render the points on the map.
    var layer = new atlas.layer.BubbleLayer(datasource);
    map.layers.add(layer);

    //Create a popup but leave it closed so we can update it and display it later.
    popup = new atlas.Popup();

    //Add a click event to the layer.
    map.events.add('click', layer, showPopup);
  });

  function showPopup(e) {
    if (e.shapes && e.shapes.length > 0) {
      var properties = e.shapes[0].getProperties();

      popup.setOptions({
        //Update the content of the popup.
        content: atlas.PopupTemplate.applyTemplate(properties, properties.popupTemplate),

        //Update the position of the popup with the pins coordinate.
        position: e.shapes[0].getCoordinates()
      });

      //Open the popup.
      popup.open(map);
    }
  }
}

A screenshot of map with six blue dots.

Повторное использование шаблона всплывающего окна

Аналогично повторному использованию всплывающего окна, можно повторно использовать шаблоны всплывающих окон. Этот подход удобен, если для нескольких точек требуется одновременно отобразить только один шаблон всплывающего окна. Повторное использование шаблонов всплывающих окон сокращает количество элементов DOM, созданных приложением, повышая производительность приложений. В следующем примере используется один и тот же шаблон всплывающего окна для трех точек. Если выбрать любой из них, всплывающее окно отображается с содержимым для этой точки функции.

Полный функциональный пример, показывающий горячее использование одного всплывающего шаблона с несколькими функциями, которые совместно используют общий набор полей свойств, см. в статье "Повторное использование шаблона всплывающего окна" в azure Карты Samples. Исходный код для этого примера см. в разделе "Повторное использование исходного кода шаблона всплывающего окна".

A screenshot of a map showing Seattle with three blue pins to demonstrating how to reuse popup templates.

Всплывающие окна можно открывать, закрывать и перетаскивать. Класс Popup предоставляет события, помогающие разработчикам реагировать на эти события. В следующем примере показано, какие события срабатывают, когда пользователь открывает, закрывает или перетаскивает всплывающее окно.

Полный функциональный пример, показывающий, как добавлять события в всплывающие окна, см. в разделе "События всплывающих окон" в примерах Карты Azure. Исходный код для этого примера см . в исходном коде событий всплывающих окон.

A screenshot of a map of the world with a popup in the center and a list of events in the upper left that are highlighted when the user opens, closes, or drags the popup.

Следующие шаги

Дополнительные сведения о классах и методах, которые используются в этой статье:

Полные примеры кода см. в следующих превосходных статьях: