Самозапускающаяся функция прерывается при повторном запуске

#javascript #html

#javascript #HTML

Вопрос:

У меня есть два HTML-блока, которые должны быть преобразованы в iframe элементы. Один предназначен для мобильных устройств, а другой — нет. Мобильный элемент скрыт для рабочего стола через класс screen-desktop-hidden .

У меня есть функция самозапуска, которая при загрузке страницы запускает создание iframe, получая атрибуты из блоков HTML и заменяя их iframe элементами. Однако они прерываются, когда оба элемента запускаются самозапускающейся функцией.

 import 'main';

(function() {
  'use strict';

  /**
   * Google Static Map
   */
  (element => {
    // Selected element is passed to this self-instantiating function
    if (element) {
      console.dir(element.attributes.class.value)
      window.addEventListener('load', () => {
        let iframe = document.createElement('iframe');

        iframe.setAttribute('src', element.dataset.googleStaticMap);
        iframe.setAttribute('class', element.attributes.class.value);
        iframe.setAttribute('width', element.attributes.width.value);
        iframe.setAttribute('height', element.attributes.height.value);
        iframe.setAttribute('frameborder',
                              element.attributes.frameborder.value);

        element.replaceWith(iframe);
      });
    }
  })(document.querySelector('[data-js="google-static-map"]'));
})();
  

Обратите внимание, что селектор запроса передается [data-js="google-static-map"] в качестве параметра. Они поступают из двух блоков, которые, как я предполагаю, являются источником ошибки. Значит, это должно быть уникальным?

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

   <section>
      <div data-js="google-static-map"
           data-google-static-map="https://www.google.com/maps/embed/v1/place?amp;center={{ post.address.lat}},{{ post.address.lng }}amp;q={{ post.address.address|url_encode }}amp;key={{ function('constant', 'GOOGLE_MAPS_EMBED') }}amp;zoom=15"
           class="block bg-blue-light border border-grey-light print:hidden screen-desktop:hidden"
           width="100%"
           height="300" 
           frameborder="0"></div>
    </section>
    
    {{ cspr_iframes_nonce }}
    
    <section class="wrap screen-desktop:layout-sidebar-gutter">
      <aside class="hidden screen-desktop:block">
         <div data-js="google-static-map"
              data-google-static-map="https://www.google.com/maps/embed/v1/place?amp;center={{ post.address.lat}},{{ post.address.lng }}amp;q={{ post.address.address|url_encode }}amp;key={{ function('constant', 'GOOGLE_MAPS_EMBED') }}amp;zoom=15" class="block bg-blue-light border border-grey-light print:hidden"
              width="100%"
              height="496"
              frameborder="0"></div>
  

Обратите внимание, что оба div элемента имеют data-js="google-static-map" атрибут data, который используется самозапускающейся функцией для запуска создания элемента iframe. Означает ли это, что атрибут data-js должен быть уникальным? Как я могу добиться запуска функции самостоятельного вызова для обоих div элементов?

Комментарии:

1. Как это прерывается? Вы получаете ошибку? Вы получаете что-то, чего не ожидаете?

2. document.querySelector('[data-js="google-static-map"]') вы всегда получите только первое совпадение с CSS-селектором. Если вы хотите что-то сделать с обоими , вы должны использовать document.querySelectorAll(...) вместо этого. Но, конечно, вашей функции тогда придется иметь дело с коллекцией узлов DOM.

3. @VLAZ он просто не показывает карту, если я прокомментирую один из двух разделов, карта будет показана.

Ответ №1:

Что-то подобное может сработать для вас:

 (function() {
  'use strict';
  (collection => {
    // collection of selected elements is passed to this immediately invoked function
    for (let i=0;i<collection.length;i  ){
      let element=collection[i];
      console.dir(element.attributes.class.value)
      window.addEventListener('load', () => {
        let iframe = document.createElement('iframe');

        iframe.setAttribute('src', element.dataset.googleStaticMap);
        iframe.setAttribute('class', element.attributes.class.value);
        iframe.setAttribute('width', element.attributes.width.value);
        iframe.setAttribute('height', element.attributes.height.value);
        iframe.setAttribute('frameborder',
                              element.attributes.frameborder.value);

        element.replaceWith(iframe);
      });
    }
  })(document.querySelectorAll('[data-js="google-static-map"]'));
})();  

Это, конечно, все еще неполно, поскольку нет HTML-разметки для работы.