TechBlogSD - Все для WordPress и WEB разработки
WEB и WordPress инструкции, новости, обзоры тем и плагинов

jQuery – Lazy Load для Google Maps API

2 686

Для бизнес-ресурсов довольно часто используется интерактивная карта на сайте. В большинстве случаев клиенты хотят добавить карту Google , потому что это то, что используют многие люди. Проблема в том, что такая карта загружает много JavaScript, шрифтов расположенных на стороннем Google сервере и изображений.

Эти карты часто помещаются внизу страницы. Множество людей, вероятно, никогда не увидит карту. Таким образом, карта будет просто появляться в “водопаде” загружающихся ресурсов страницы и замедлять её загрузку.

LazyLoad здесь придёт на помощь, так как будет показывая карту только если она становится видимой при прокрутке (скроле) вниз. Для этого варианта браузеры могут использовать API IntersectionObserver . Для браузеров, которые не поддерживают этот API, вы можете загрузить Polyfill IntersectionObserver W3C.

Для достижения ленивой загрузки вам придется загружать API Карт Google с помощью JavaScript, а не напрямую из HTML. Для этого я буду использовать Loadament Group loadJS.

Ниже приведен код для реализации ленивой загрузки карты. Чтобы увидеть как это работает в действительности обратите внимание на фейс CodePen в конце страницы.

Конечно, вы также можете использовать эту технику с другими картами, например, с Leaflet и OpenStreetMap или Yandex картами.

При загрузке API Карт Google вам необходимо установить обратный вызов, который доступен на вашей веб-странице. В моем примере это:

google_maps_init

В этой функции вы определяете все настройки для своей карты. Она будет вызываться после завершения загрузки API. Вы также должны предоставить ключ API Карт Google в данном блоке:

google_maps_lazyload("API KEY")

Для запуска IntersectionObserver вы должны использовать observer.observe(element). Как только карта начнет загружаться, вы можете прекратить наблюдение с помощью:

observer.unobserve(element)

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

Полностью весь используемый и необходимый код HTML, CSS, jQuery:

<style><br><br> div#map {<br> min-width: 100%;<br> min-height: 450px;<br>}<br><br></style><br><br><div id="map"><br> <div id="marker">Текст отображаемый в Title при клике на маркер</div><br></div><br><script><br>// Google Maps API Lazy Load AFTERSCRIPTS<br>// START<br>// ===============================================<br>// 1 START loadJS<br>// ===============================================<br><br>/*! loadJS: load a JS file asynchronously. [c]2014 @scottjehl, Filament Group, Inc. (Based on http://goo.gl/REQGQ by Paul Irish). Licensed MIT */<br>(function( w ){<br> var loadJS = function( src, cb ){<br> "use strict";<br> var ref = w.document.getElementsByTagName( "script" )[ 0 ];<br> var script = w.document.createElement( "script" );<br> script.src = src;<br> script.async = true;<br> ref.parentNode.insertBefore( script, ref );<br> if (cb && typeof(cb) === "function") {<br> script.onload = cb;<br> }<br> return script;<br> };<br> // commonjs<br> if( typeof module !== "undefined" ){<br> module.exports = loadJS;<br> }<br> else {<br> w.loadJS = loadJS;<br> }<br>}( typeof global !== "undefined" ? global : this ));<br><br>// ===============================================<br>// 2 START IntersectionObserver<br>// ===============================================<br><br> /* W3C Intersection Observer Polyfill https://github.com/w3c/IntersectionObserver */<br>(function(e,f){function m(a){this.time=a.time;this.target=a.target;this.rootBounds=a.rootBounds;this.boundingClientRect=a.boundingClientRect;this.intersectionRect=a.intersectionRect||l();this.isIntersecting=!!a.intersectionRect;a=this.boundingClientRect;a=a.width*a.height;var b=this.intersectionRect,b=b.width*b.height;this.intersectionRatio=a?b/a:this.isIntersecting?1:0}function c(a,b){b=b||{};if("function"!=typeof a)throw Error("callback must be a function");if(b.root&&1!=b.root.nodeType)throw Error("root must be an Element");<br>this._checkForIntersections=u(this._checkForIntersections.bind(this),this.THROTTLE_TIMEOUT);this._callback=a;this._observationTargets=[];this._queuedEntries=[];this._rootMarginValues=this._parseRootMargin(b.rootMargin);this.thresholds=this._initThresholds(b.threshold);this.root=b.root||null;this.rootMargin=this._rootMarginValues.map(function(a){return a.value+a.unit}).join(" ")}function u(a,b){var d=null;return function(){d||(d=setTimeout(function(){a();d=null},b))}}function q(a,b,d,c){"function"==<br>typeof a.addEventListener?a.addEventListener(b,d,c||!1):"function"==typeof a.attachEvent&&a.attachEvent("on"+b,d)}function r(a,b,d,c){"function"==typeof a.removeEventListener?a.removeEventListener(b,d,c||!1):"function"==typeof a.detatchEvent&&a.detatchEvent("on"+b,d)}function n(a){try{var b=a.getBoundingClientRect()}catch(d){}if(!b)return l();b.width&&b.height||(b={top:b.top,right:b.right,bottom:b.bottom,left:b.left,width:b.right-b.left,height:b.bottom-b.top});return b}function l(){return{top:0,bottom:0,<br>left:0,right:0,width:0,height:0}}function t(a,b){for(;b;){if(b==a)return!0;b=p(b)}return!1}function p(a){return(a=a.parentNode)&&11==a.nodeType&&a.host?a.host:a}if("IntersectionObserver"in e&&"IntersectionObserverEntry"in e&&"intersectionRatio"in e.IntersectionObserverEntry.prototype)"isIntersecting"in e.IntersectionObserverEntry.prototype||Object.defineProperty(e.IntersectionObserverEntry.prototype,"isIntersecting",{get:function(){return 0<this.intersectionRatio}});else{var g=[];c.prototype.THROTTLE_TIMEOUT=<br>100;c.prototype.POLL_INTERVAL=null;c.prototype.USE_MUTATION_OBSERVER=!0;c.prototype.observe=function(a){if(!this._observationTargets.some(function(b){return b.element==a})){if(!a||1!=a.nodeType)throw Error("target must be an Element");this._registerInstance();this._observationTargets.push({element:a,entry:null});this._monitorIntersections();this._checkForIntersections()}};c.prototype.unobserve=function(a){this._observationTargets=this._observationTargets.filter(function(b){return b.element!=a});this._observationTargets.length||<br>(this._unmonitorIntersections(),this._unregisterInstance())};c.prototype.disconnect=function(){this._observationTargets=[];this._unmonitorIntersections();this._unregisterInstance()};c.prototype.takeRecords=function(){var a=this._queuedEntries.slice();this._queuedEntries=[];return a};c.prototype._initThresholds=function(a){a=a||[0];Array.isArray(a)||(a=[a]);return a.sort().filter(function(a,d,c){if("number"!=typeof a||isNaN(a)||0>a||1<a)throw Error("threshold must be a number between 0 and 1 inclusively");<br>return a!==c[d-1]})};c.prototype._parseRootMargin=function(a){a=(a||"0px").split(/s+/).map(function(a){a=/^(-?d*.?d+)(px|%)$/.exec(a);if(!a)throw Error("rootMargin must be specified in pixels or percent");return{value:parseFloat(a[1]),unit:a[2]}});a[1]=a[1]||a[0];a[2]=a[2]||a[0];a[3]=a[3]||a[1];return a};c.prototype._monitorIntersections=function(){this._monitoringIntersections||(this._monitoringIntersections=!0,this.POLL_INTERVAL?this._monitoringInterval=setInterval(this._checkForIntersections,<br>this.POLL_INTERVAL):(q(e,"resize",this._checkForIntersections,!0),q(f,"scroll",this._checkForIntersections,!0),this.USE_MUTATION_OBSERVER&&"MutationObserver"in e&&(this._domObserver=new MutationObserver(this._checkForIntersections),this._domObserver.observe(f,{attributes:!0,childList:!0,characterData:!0,subtree:!0}))))};c.prototype._unmonitorIntersections=function(){this._monitoringIntersections&&(this._monitoringIntersections=!1,clearInterval(this._monitoringInterval),this._monitoringInterval=null,<br>r(e,"resize",this._checkForIntersections,!0),r(f,"scroll",this._checkForIntersections,!0),this._domObserver&&(this._domObserver.disconnect(),this._domObserver=null))};c.prototype._checkForIntersections=function(){var a=this._rootIsInDom(),b=a?this._getRootRect():l();this._observationTargets.forEach(function(d){var c=d.element,h=n(c),f=this._rootContainsTarget(c),k=d.entry,g=a&&f&&this._computeTargetAndRootIntersection(c,b);d=d.entry=new m({time:e.performance&&performance.now&&performance.now(),target:c,<br>boundingClientRect:h,rootBounds:b,intersectionRect:g});k?a&&f?this._hasCrossedThreshold(k,d)&&this._queuedEntries.push(d):k&&k.isIntersecting&&this._queuedEntries.push(d):this._queuedEntries.push(d)},this);this._queuedEntries.length&&this._callback(this.takeRecords(),this)};c.prototype._computeTargetAndRootIntersection=function(a,b){if("none"!=e.getComputedStyle(a).display){var d=n(a);a=p(a);for(var c=!1;!c;){var h=null,g=1==a.nodeType?e.getComputedStyle(a):{};if("none"==g.display)return;a==this.root||<br>a==f?(c=!0,h=b):a!=f.body&&a!=f.documentElement&&"visible"!=g.overflow&&(h=n(a));if(h){var g=Math.max(h.top,d.top),k=Math.min(h.bottom,d.bottom),l=Math.max(h.left,d.left),d=Math.min(h.right,d.right),h=d-l,m=k-g,d=0<=h&&0<=m&&{top:g,bottom:k,left:l,right:d,width:h,height:m};if(!d)break}a=p(a)}return d}};c.prototype._getRootRect=function(){if(this.root)var a=n(this.root);else{a=f.documentElement;var b=f.body;a={top:0,left:0,right:a.clientWidth||b.clientWidth,width:a.clientWidth||b.clientWidth,bottom:a.clientHeight||<br>b.clientHeight,height:a.clientHeight||b.clientHeight}}return this._expandRectByRootMargin(a)};c.prototype._expandRectByRootMargin=function(a){var b=this._rootMarginValues.map(function(b,c){return"px"==b.unit?b.value:b.value*(c%2?a.width:a.height)/100}),b={top:a.top-b[0],right:a.right+b[1],bottom:a.bottom+b[2],left:a.left-b[3]};b.width=b.right-b.left;b.height=b.bottom-b.top;return b};c.prototype._hasCrossedThreshold=function(a,b){a=a&&a.isIntersecting?a.intersectionRatio||0:-1;b=b.isIntersecting?b.intersectionRatio||<br>0:-1;if(a!==b)for(var c=0;c<this.thresholds.length;c++){var e=this.thresholds[c];if(e==a||e==b||e<a!==e<b)return!0}};c.prototype._rootIsInDom=function(){return!this.root||t(f,this.root)};c.prototype._rootContainsTarget=function(a){return t(this.root||f,a)};c.prototype._registerInstance=function(){0>g.indexOf(this)&&g.push(this)};c.prototype._unregisterInstance=function(){var a=g.indexOf(this);-1!=a&&g.splice(a,1)};e.IntersectionObserver=c;e.IntersectionObserverEntry=m}})(window,document);<br><br>// Google Maps API Lazy Load SDStudio ;)<br>// START<br>// ================================================<br>function google_maps_init() {<br> 'use strict'<br><br> var roemerberg = {lat: 47.835168, lng: 35.127182}<br> var markerElement = document.getElementById('marker')<br> var mapElement = document.getElementById('map')<br> var map = new google.maps.Map(mapElement, {<br> zoom: 15,<br> center: roemerberg,<br> markers: [] })<br><br> // Google Maps Icon Marker <br><br> var markerIcon = {<br> url:'/wp-content/uploads/2018/10/2_marker.png',<br> scaledSize: new google.maps.Size(43, 59),<br> origin: new google.maps.Point(0, 0),<br> }<br> var marker = new google.maps.Marker({<br> position: roemerberg,<br> map: map,<br> icon: markerIcon,<br> animation: google.maps.Animation.DROP<br> })<br><br> map.markers.push(marker);<br> var infowindow = new google.maps.InfoWindow({<br> content: markerElement.innerHTML<br> })<br> google.maps.event.addListener(marker, 'click', function () {<br> infowindow.open(map, marker);<br> })<br> markerElement.style.opacity = 1<br>}<br><br>function google_maps_lazyload(api_key) {<br> 'use strict'<br><br> if (api_key) {<br> var options = {<br> rootMargin: '100px',<br> threshold: 0<br> }<br><br> var observer = new IntersectionObserver(<br> function(entries, self) {<br> // Intersecting with Edge workaround https://calendar.perfplanet.com/2017/progressive-image-loading-using-intersection-observer-and-sqip/#comment-102838<br> var isIntersecting = typeof entries[0].isIntersecting === 'boolean' ? entries[0].isIntersecting : entries[0].intersectionRatio > 0<br> if (isIntersecting) {<br> var mapsJS = document.createElement('script')<br> mapsJS.src = 'https://maps.googleapis.com/maps/api/js?callback=google_maps_init&key=' + api_key<br> document.getElementsByTagName('head')[0].appendChild(mapsJS)<br> self.unobserve(map)<br> }<br> },<br> options<br> )<br><br> observer.observe(map)<br> }<br>}<br><br>google_maps_lazyload("ЗДЕСЬ_ВПИСЫВАЕМ_СВОЙ_API_КЛЮЧ") <br><br>// END<br>// Google Maps API Lazy Load SDStudio ;)<br>// ================================================<br><br></script>  

Пример отработки скрипта

[iframe src=https://codepen.io/dydaevskiy/embed/QJoxLX]   

Источник записи:

Leave A Reply

Этот веб-сайт использует файлы cookie для улучшения вашего опыта. Мы предполагаем, что вы согласны с этим, но вы можете отказаться, если хотите. ПринимаюПодробнее