1

Topic: How correctly to connect a Yandex-card and the Google-card?

I need to use on one page both cards.
Separately all works, together it is impossible.
In the end of page I specify so:

<script src = "jquery.min.js"> </script>
<script async src = "https://api-maps.yandex.ru/2.1/?lang=ru_RU"> </script>
<script async src = "https://maps.googleapis.com/maps/api/js?key=...&callback=initMap"> </script>
<script defer src = "maps.js"> </script>

In a script maps.js the necessary code, and also initialization (in function initMap both cards are initialized) is specified.
For a Yandex-cards such code is used:

ymaps.ready (initMap);

For the Google-cards enough specified in parameters callback=initMap.
Tried to make so:

$(document).ready (function () {
ymaps.ready (initMap);
});

But so a Yandex-card does not work, at the moment of event ready the script is not loaded yet.

2

Re: How correctly to connect a Yandex-card and the Google-card?

<script src = "jquery.min.js"> </script>
<script async src = "https://api-maps.yandex.ru/2.1/?lang=ru_RU"> </script>
<script async src = "https://maps.googleapis.com/maps/api/js?key=...&callback=initMap"> </script>
<script defer src = "maps.js"> </script>

a manual on  to cards?

3

Re: How correctly to connect a Yandex-card and the Google-card?

Alibek B.;
https://tech.yandex.ru/maps/jsapi/
https://developers.google.com/maps/docu … ipt/?hl=ru

4

Re: How correctly to connect a Yandex-card and the Google-card?

Alibek B.;
That it to avoid.
Write the code of creation of cards in one output agent.

5

Re: How correctly to connect a Yandex-card and the Google-card?

And when it is necessary to do it?
Function initMap just also is such output agent in whom both cards are initialized.
If initMap to cause on event ready a Yandex-card does not work - probably by the time of creation DOM scripts are not initialized yet.
And if to cause ymaps.ready (initMap) cards Yandex work, but cards Google do not work, is visible because of asynchronous loading of scripts.

6

Re: How correctly to connect a Yandex-card and the Google-card?

Areostar;
Thanks for links!

7

Re: How correctly to connect a Yandex-card and the Google-card?

In the beginning I had one container for all cards, in a script I at switching of cards cleared it and anew initialized. But in such method there were some difficulties. Therefore I made separate containers for each card and I switch their visibility a script:

<div id = "map-frame-google" class = "hidden" style = "width: 100 %; height: 450px;"> </div>
<div id = "map-frame-yandex" class = "hidden" style = "width: 100 %; height: 450px;"> </div>

As I removed asynchronous loading:

<script src = "https://code.jquery.com/jquery-3.2.1.min.js"> </script>
<script src = "https://api-maps.yandex.ru/2.1/?lang=ru_RU"> </script>
<script src = "https://maps.googleapis.com/maps/api/js?key=key"> </script>
<script src = "maps.js"> </script>

The file maps.js looks so (all superfluous removed):

var maps = {google:null, yandex:null};
function initMap () {
var $mode = <the current mode, google or yandex> is clarified;
$(' [id | = "map-frame"] ').addClass (' hidden ');
$(' #map-frame - ' + $ mode).removeClass (' hidden ');
switch ($mode)
{
case ' google ':
initMapGoogle ();
break;
case ' yandex ':
ymaps.ready (initMapYandex);
break;
}
}
function initMapGoogle () {
return;//now initialization of cards Google is disconnected
if (! maps.google) {
maps.google = google.maps. Map (document.getElementById (' map-frame-google '), {center: {lat:20, lng:30}, zoom: 10});
setMapGoogle (' village Kukuevo ');
}
}
function initMapYandex () {
if (! maps.yandex) {
maps.yandex = new ymaps. Map (' map-frame-yandex ', {center: [20, 30], zoom: 10});
setMapYandex (' village Kukuevo ');
}
}
function setMap (source) {
var $mode = <the current mode, google or yandex> is clarified;
switch ($mode)
{
case ' google ':
setMapGoogle (source);
break;
case ' yandex ':
setMapYandex (source);
break;
}
}
function setMapGoogle (source) {
}
function setMapYandex (source) {
maps.yandex.geoObjects.removeAll ();
maps.yandex.geoObjects.add (maps [' yandex-base ']);
var multiRoute = new ymaps.multiRouter. MultiRoute ({referencePoints: [source, ' Moscow ']}, {boundsAutoApply:true});
maps.yandex.geoObjects.add (multiRoute);
multiRoute.events.once (' update ', function () {
var routes = multiRoute.getRoutes ();
for (var i = 0, l = routes.getLength (); i <l; i ++) {
var route = routes.get (i);
if (! route.properties.get (' blocked ')) {
multiRoute.setActiveRoute (route);
route.balloon.open ();
break;
}
}
});
}
$(' #map-citylist a ').on (' click ', function (event) {
event.preventDefault ();
setMap ($ (this).text ());
});
$(document).ready (function () {
initMap ();
});

In such Yandex-card variants work normally - are successfully initialized and route creation works.
But as soon as I remove a stub-return from function initMapGoogle as I receive an error jQuery. Deferred exception.
If to change the order of connection of scripts (in the beginning maps.js, then Card Google) and to add in a connected script of the Google-cards parameter callback=initMap I receive other error: Uncaught TypeError: this.setValues is not a function.
Do not prompt how to make correctly?

8

Re: How correctly to connect a Yandex-card and the Google-card?

Alibek B.;
I think at you somewhere type variables map or other are doubled. Problems should not be.

9

Re: How correctly to connect a Yandex-card and the Google-card?

Yes, maps it is used somewhere in the code  cards.
Renamed maps in maplist, also added new at card creation (new google.maps. Map). And still removed an option map for a marker.
Now errors in the console are not present, but on a card there is an image, there is only a gray background and logo Google.
Because of what such can be?
In adjustments of key API I specified the site address on which these cards are used.
And just in case I generally removed these restrictions, but did not help.

10

Re: How correctly to connect a Yandex-card and the Google-card?

Somehow strange the Google-card conducts themselves.
On the mobile device the card is drawn, truth long.
And a desktop instead of a card the gray screen. But as soon as I include the panel of the developer, on a card the image is drawn. Truth a position not such what I specify in an initialization script, but near to this place.
When I did an embeddable card, problems were not. On JS I passed to accelerate  a route at change of a point of departure (at usage of an embeddable card iframe booted anew), but something at all does not work.

11

Re: How correctly to connect a Yandex-card and the Google-card?

Alibek B.;
Can  it is curve.

12

Re: How correctly to connect a Yandex-card and the Google-card?

There is such list:

cities = [
{' Moscow ': [55.751574, 37.573856]};
...
];

On the basis of this list I add on a card falling out the list:

items = cities.map (function (item, index, list) {
key = Object.keys (item) [0];
obj = new ymaps.control. ListBoxItem ({data: {content: key, center: item [key]}});
return obj;
});
var lst = new ymaps.control. ListBox ({data: {content:' a city '}, items:items});

But for some reason in obj there is a scalar (value), instead of object.
Though such code works normally:

items = [
new ymaps.control. ListBoxItem ({data: {content: ' Moscow ', center: [55.751574, 37.573856]}});
...
];

As it is necessary to use correctly ymaps.control. ListBoxItem?

13

Re: How correctly to connect a Yandex-card and the Google-card?

With Yandex understood.
With Google partially, it was necessary to add the trigger on resize (https://stackoverflow.com/questions/422 … ead-of-map).

14

Re: How correctly to connect a Yandex-card and the Google-card?

The trigger on resize partially helps, but not always.
Cards Google  if the container at the moment of initialization was not visible yet.
At switching of cards repeated initialization with a small time delay (400 msec) helps.
But at loading of page of it it is not enough, because the card is on a hidden bookmark and by the time of loading of page the container is not visible.
Prompt how to catch event when DIV becomes visible?
I found an example with IntersectionObserver, but it on many browsers does not work.
Any general-purpose decision which will consider including that parent container DIV with a card too can be hidden is necessary.

15

Re: How correctly to connect a Yandex-card and the Google-card?

Apparently, determination of the moment of visibility of an element on JS the task nontrivial.
The general-purpose method only in periodic inquiry on the timer.

16

Re: How correctly to connect a Yandex-card and the Google-card?

Made so:

var maplist = {google:null, yandex:null};
maplist.origins = [
{' Moscow ': [50, 30], type: ' capital ', area: ' the Russian Federation '};
...
];
function initMap () {
var $mode = $ (' #map-mode input:checked ').attr (' id ');
$mode = $mode.substr (9);
maplist.mode = $mode;
$(' [id | = "map-frame"] ').addClass (' hidden ');
$(' #map-frame - ' + $ mode).removeClass (' hidden ');
if (maplist [$mode]) maplist [' REFRESH - ' + $ mode] = true;
maplist [' active-frame '] = $ (' #map-frame - ' + maplist.mode);
var checkRedraw = function (mode, frame) {
if (frame.is (':visible ')) {
switch (mode)
{
case ' google ':
if (maplist.google) google.maps.event.trigger (maplist.google, ' resize ');
break;
case ' yandex ':
if (maplist.yandex) maplist.yandex.redraw ();
break;
}
} else {
setTimeout (checkRedraw (mode, frame), 250);
}
};
if (maplist [' refresh-google ']) checkRedraw (' google ', $ (' #map-frame-google '));
if (maplist [' refresh-yandex ']) checkRedraw (' yandex ', $ (' #map-frame-yandex '));
switch ($mode)
{
case ' google ':
maplist [' google-frame '] = $ (' #map-frame-google ');
var checkVisibility = function () {
var state = maplist [' google-frame '].is (':visible ');
if (state) {
initMapGoogle ();
} else {
setTimeout (checkVisibility, 250);
}
};
if (! maplist.google) checkVisibility ();
break;
case ' yandex ':
ymaps.ready (initMapYandex);
break;
}
}
function initMapGoogle () {
if (maplist.google) return;
var $center = new google.maps. LatLng (43.564393, 41.280583);
var $options = {zoom: 10, center: $center, mapTypeId: google.maps. MapTypeId. ROADMAP};
maplist.google = new google.maps. Map (document.getElementById (' map-frame-google '), $options);
searchMapGoogle (' village Kukuevo ');
}
function initMapYandex () {
if (maplist.yandex) return;
var ctlControls = [' searchControl ', ' geolocationControl ', ' typeSelector ', ' fullscreenControl ', ' zoomControl '];
maplist.yandex = new ymaps. Map (' map-frame-yandex ', {center: [43.564393, 41.280583], zoom: 10, controls: ctlControls});
var search = maplist.yandex.controls.get (' searchControl ');
search.options.set (' provider ', ' yandex#map ');
search.options.set (' kind ', ' locality ');
search.options.set (' noSelect ', false);
search.options.set (' noPlacemark ', true);
search.options.set (' noCentering ', true);
search.options.set (' placeholderContent ', ' settlement Search... ');
search.options.set (' suppressYandexSearch ', true);
search.options.set (' boundedBy ', maplist.yandex.getBounds ());
search.events.add (' resultselect ', function (e) {
var index = e.get (' index ');
var result = search.getResultsArray () [index];
search.hideResult ();
searchMapYandex (search.getRequestString (), result.geometry.getCoordinates ());
}, this);
var lstOrigins = maplist.origins.map (function (item, index, list) {
var obj = new ymaps.control. ListBoxItem ({options: {type: ' separator '}});
if (item) {
var key = Object.keys (item) [0];
var obj = {content: key, center: item [key]};
if (item.type) obj.content + = ' (' +item.type + ') ';
obj = new ymaps.control. ListBoxItem ({data: obj, options: {selectOnClick:false}});
}
return obj;
});
var ctlOrigins = new ymaps.control. ListBox ({data: {content:' a city '}, items:lstOrigins});
ctlOrigins.events.add (' click ', function (e) {
var item = e.get (' target ');
if (item! = ctlOrigins) {
searchMapYandex (item.data.get (' content '), item.data.get (' center '));
item.getParent ().collapse ();
}
});
maplist.yandex.controls.add (ctlOrigins);
searchMapYandex (' village Kukuevo ');
}
function searchMapGoogle (origin, position) {
var local;
if (! position)
{
for (var i = 0, l = maplist.origins.length; i <l; i ++) {
var item = maplist.origins [i];
if (! item) continue;
var name = Object.keys (item) [0];
if (name == origin)
{
position = item [name];
local = item;
if (! position)
{
if (! item.type) origin = item.type + ' ' + origin;
}
break;
}
}
}
}
function searchMapYandex (origin, position) {
var local;
if (! position)
{
for (var i = 0, l = maplist.origins.length; i <l; i ++) {
var item = maplist.origins [i];
if (! item) continue;
var name = Object.keys (item) [0];
if (name == origin)
{
position = item [name];
local = item;
if (! position)
{
if (! item.type) origin = item.type + ' ' + origin;
}
break;
}
}
}
maplist.yandex.geoObjects.removeAll ();
var multiRoute = new ymaps.multiRouter. MultiRoute ({referencePoints: [(position? position: origin), ' Moscow ']}, {boundsAutoApply:true});
maplist.yandex.geoObjects.add (multiRoute);
multiRoute.events.once (' update ', function () {
var routes = multiRoute.getRoutes ();
for (var i = 0, l = routes.getLength (); i <l; i ++) {
var route = routes.get (i);
if (! route.properties.get (' blocked ')) {
multiRoute.setActiveRoute (route);
route.balloon.open ();
break;
}
}
});
}
//Cards switch on pushing of radio-buttons
$(' #map-mode input ').on (' change ', function (event) {
initMap ();
});
$(window).resize (function () {
maplist [' refresh-google '] =! $ (' #map-frame-google ').is (':visible ')
maplist [' refresh-yandex '] =! $ (' #map-frame-yandex ').is (':visible ')
});
$(document).ready (function () {
initMap ();
});

How much I see, all works in all modes ( on the latent tab, long loading etc.). Besides loading of scripts now the asynchronous.
I will be grateful for councils about optimization and improving.