Ответы пользователя по тегу JavaScript
  • Openweather из JSON в HTML как лучше сделать?

    дату не обязательно брать из .dt она есть в текстовом виде в .dt_txt

    Даллее, есть два варианта, развернуть объект в:
    {"2019-12-22":[{"dt":1577048400,"main":{"temp":-21.94,"feels_like":-26.97,"temp_min":-22.46,"temp_max":-21.94,"pressure":1018,"sea_level":1018,"grnd_level":1013,"humidity":99,"temp_kf":0.52},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03n"}],"clouds":{"all":34},"wind":{"speed":1.97,"deg":139},"sys":{"pod":"n"},"dt_txt":"2019-12-22 21:00:00"}],
    ...}

    где ключи - это даты.
    и работать уже по датам...

    развернуть можно тем же map'ом

    let wd = {};
    data.list.map(e => {
    	let dt = e.dt_txt.split(" ")[0];
      if(typeof(wd[dt])!="undefined") {
      	wd[dt].push(e);
      } else {
      	wd[dt] = [];
      }
    });
    console.log(JSON.stringify(wd));


    либо ввести переменную "состояния" в которой хранить текущую дату и последовательно проходя по объекту сверять дату записи с датой в переменной, если они != то запоминать новую дату, добавлять перед выводом записи, вывод табличной строки с датой.

    как-то так:

    let iconUrl="";
    
    let wdate = ""; // переменная состояния
    function forecastTemplate (localData) {
    				let s = "";
            if (localData.dt_txt.split(" ")[0] != wdate) {
            	wdate = localData.dt_txt.split(" ")[0];
              s += `
              <tr><td colspan=2>${wdate}</td>
              `;
            }
            s += `
               <tr>
                    <td>
                        <div class="flex">
                            <div>
                                <span>${localData.dt_txt.split(" ")[1]}<span>
                            </div>
                            <div>
                                <img src="${iconUrl}${localData.weather[0].icon}@2x.png">
                            </div>
                        </div>
                    </td>
                    <td>
                        <div class="flex">
                            <div>
                                <span class="temp">${localData.main.temp}&#8451</span>
                            </div>
                            <div>
                                <span class="description">${localData.weather[0].description}</span>
                            </div>
                        </div>
                        <div class="flex">
                            <div>
                                <span>wind: ${localData.wind.speed} m/s,</span>
                            </div>
                            <div>
                                <span>clouds: ${localData.clouds.all}%,</span>
                            </div>
                            <div>
                                <span>pressure: ${localData.main.pressure} hPa</span>
                            </div>
                        </div>
                    </td>
               </tr>`
            return s
        }
    
    let html = "";
    document.body.innerHTML = `<table>${data.list.map(forecastTemplate).join("")}</table>`;


    См. на jsfiddle:


    PS: состояние-дату, можно хранить в свойстве вашего объекта updateUI
    Ответ написан
  • Как при прохождение цикла по объекту узнать, является ли свойством объекта другой объект?

    Можно ли дойдя с помощью цикла до свойства hosts понять, что оно является объектом?


    typeof()

    console.log(typeof({}));
    // object


    for (var key in data) {
      if(typeof(data[key]) == "object") {
        console.log (key + " is object");
      }
    }



    Просто мне необходимо в этом случае, добавлять в тело цикла(или условия) после самого объекта(в данном случае data), или .объект или [свойство].


    вообще не понял о чем вы говорите...

    Кстати, с помощью какого метода, я смогу это всё добавлять? Мне нужно добавить либо data.hosts либо data[свойство]


    добавлять ЧТО и добавлять КУДА??

    и записи data.hosts либо data["hosts"] равнозначны.

    добавить в data.hosts еще один элемент?

    см. JavaScript: Как добавить новый элемент в объект?

    data["hosts"][2] = {name: 'web3'}

    но тут возникает неудобство с определением следующего номера ключа, т.к. это НЕ массив!
    с массивом было бы проще.

    data["hosts"][data["hosts"].length] = {name: 'web3'}
    // или
    data["hosts"].push( {name: 'web3'} );


    Upd:

    По мотивам комментариев:
    Решение.... рекурсивная функция
    const data = {
      user: 'ubuntu',
      hosts: {
        0: {
          name: 'web1',
        },
        1: {
          name: 'web2',
          null: 3,
        },
      },
    };
    
    // классически на if
    function getIn(obj, parr) {
      if(typeof(obj[parr[0]]) == "undefined") {
        return null;
      } else {
        if(typeof(obj[parr[0]]) == "object") {
          if(parr.length > 1) {
            return getIn(obj[parr[0]], parr.slice(1))
          } else {
            return obj[parr[0]]
          }
        } else {
          return obj[parr[0]];
        }
      }
    }
    
    
    // защита от дурака (когда некорректные параметры) + switch case
    function getIn(obj, parr) {
      if (
        typeof(obj) != "object" ||
        typeof(parr) != "object" ||
        parr.length == "undefined" ||
        parr.length == 0
      ) return null;
      switch (typeof(obj[parr[0]])) {
        case "undefined":
          return null;
        case "object":
          return (parr.length > 1)? getIn(obj[parr[0]], parr.slice(1)):obj[parr[0]]
        default:
          return obj[parr[0]];
      }
    }
    
    // еще короче 
    function getIn(obj, parr){
      return !(
        typeof(obj) != "object" ||
        typeof(parr) != "object" ||
        parr.length == "undefined" ||
        parr.length == 0
      )?
        typeof(obj[parr[0]]) == "object" ?
          (parr.length > 1)?
            getIn(obj[parr[0]], parr.slice(1)):obj[parr[0]] :
             obj[parr[0]] ?
              obj[parr[0]]: null:
              null
    }
    
    // и стрелочной функцией
    const getIn = (obj, parr) => !(
        typeof(obj) != "object" ||
        typeof(parr) != "object" ||
        parr.length == "undefined" ||
        parr.length == 0
      )?
        typeof(obj[parr[0]]) == "object" ?
          (parr.length > 1)? getIn(obj[parr[0]], parr.slice(1)):obj[parr[0]] :
           obj[parr[0]] ? obj[parr[0]]:null :
        null;


    UPD2:

    Решение без рекурсивного вызова
    function getIn(obj, parr) {
      let o = obj;
      for(let i=0; i< parr.length; i++) {
        o = o[parr[i]];
        if(typeof(o)=="undefined") return null;
      }
      return o;
    }
    Ответ написан
  • Как сложить старое и новое значение в одном input?

    <input type="text" id="number" value="100">
    document.getElementById("number").onblur = function(){
    	this.value = parseInt(this.defaultValue) + parseInt(this.value);
      this.defaultValue = this.value;
    }


    PS: при потере фокуса происходит перерасчет значения и запись обратно и в defaultValue

    Ответ написан
  • Как обработать массивы?

    const al   = "АБВГДЕЁЖЗИКЛМНОПРСТУФХЦЧШЩЫЬЭЮЯ "; // Алфавит
    let key1 = "ПЕРВЫЙ"; // первый ключ
    let key2 = "БУКВА"; // второй ключ
    let open_str = "ЭТО СТРОКА ОТКРЫТОГО ИСХОДНОГО ТЕКСТА"; // кодируемый текст
    
    // т.к. в алфавите нет букв Й и Ъ, то производим соответствующую замену:
    key1 = key1.replace("Й","И").replace("Ъ","Ь");
    key2 = key2.replace("Й","И").replace("Ъ","Ь");
    open_str = open_str.replace("Й","И").replace("Ъ","Ь");
    
    // кодируем текст
    let encoded_str = ([...open_str]).map( (e,i) => al[(al.indexOf(e) + al.indexOf(key1[i%key1.length]) + al.indexOf(key2[i%key2.length])) % 32] ).join("");
    
    console.log(encoded_str);


    PS:
    к строке по сути можно обращаться как к массиву - str[index]
    про .map смотрим здесь - https://developer.mozilla.org/en-US/docs/Web/JavaS...
    если вам надо прям вот на МАССИВАХ, то просто сделайте соответствующие переменные "массивами"
    строку в массив можно разбить так str.split("") или [...str]

    по скрипту
    al - строка / массив букв алфавита
    al.indexOf(char) - получаем индекс буквы в алфавите
    по выбору символа из ключа - т.к. ключ у нас заитерирован, то берем остаток от деления индекса кодируемого символа на длину ключа , это и будет символ из ключа - key1[i%key1.length], далее получаем его код по алфавиту - al.indexOf(key1[i%key1.length])

    и у вас много ошибок в таблице, например в третьей строке - конечный символ не И, а З
    и т.д.

    Ответ написан
  • Какая нужна регулярка чтобы проверка проходила на номера одного оператора?

    Вот еще вариант, проверяет номер написанный в любом формате со скобками вокруг кода и без с пробелами и с тире и с + в начале и без

    var str = '90553334849';
    alert(/^\+?9[ -]?\(?05[58]\)?[ -]?\d{3}[ -]?\d{2}[ -]?\d{2}$/.test(str));


    UPD:
    вот проверка (одной регуляркой в одну строку) по массиву кодов

    var str = '9(055)3334849';
    var allow = ['055','058'];
    alert((new RegExp('^\\+?9[ -]?\\(?('+allow.join('|')+')\\)?[ -]?\\d{3}[ -]?\\d{2}[ -]?\\d{2}$')).test(str));


    UPD3:
    Почитайте: https://developer.mozilla.org/en-US/docs/Web/JavaS...
    в разделе "Special characters in regular expressions." расписаны все спецсимволы, которые используются в регулярных выражениях.
    про конструктор new RegExp там тоже есть...

    кокретно в последнем примере:
    т.к. регулярку нам надо создавать "динамически", то используется конструктор new RegExp , который из строки создает и возвращает регулярку и уже у нее вызывается метод .test()
    про строку - в строке спецсимволы \ необходимо экранировать (предварять) символом \
    в строку регулярки мы вставляем все коды из массива allow склеенные через символ |
    регулярка вида (одно|второе|третье) читается как одно ИЛИ второе ИЛИ третье
    в данном случае массив склеивается и реглярка читается как 055 или 058

    ну, как-то так... )
    Ответ написан
  • Как правильно вывести объект в html?

    Во-первых, вы непонятно излагаете свои мысли:
    и как сравнить значение, если например 0 - соотв. этому .item добавляем класс

    значит ли это что класс необходимо выставлять элементу в котором значение равно искомому, в данном случае 0 ?

    Во-вторых, вы неправильно берете количество/значение из str
    посмотрите как вы ее заполняете... в ней будет
    0: 1,
    1: 4,
    2: 2,
    3: 4,
    4: 4,
    5: 2,


    после разбивки split'ом
    str.split(', ')[i]
    в count вы присваете ПАРУ значение: количество !
    и это сравниваете с 0 ???
    эту пару необходимо еще раз разбить и взять либо ЗНАЧЕНИЕ, либо КОЛИЧЕСТВО, смотря что вам надо??

    ну и
    если например 0
    то почему у вас стоит условие < 0 ???

    for (let i = 0; i < item.length; i++) {
    	let pair = str.split(', ')[i];
      if (pair.split(': ')[0] == 0) {
        item[i].classList.add('zero');
      }
      item[i].textContent = pair;
    }


    PS: а если количество элементов в массиве изменится??
    может стоит добавлять элементы динамически?
    см. Node.appendChild()

    UPDATE:


    UPDATE 2:
    с добавлением класса:
    Ответ написан
  • Как обновлять таймер по клику?

    странная логика заложена у вас.

    1. контейнер для таймер можно/нужно добавить в нужное место в HTML, а не добавлять каждый раз по клику, либо добавлять его по условию (что он еще не создан).

    2. вы безусловно добавляете элементы, а потом лишнее удаляете, зачем?

    3. зачем-то создали специально объект, хотя можно просто работать с массивом и удалять его элементы, массив это тот же объект.
    const items = [];
    items["one"]=1;
    items["two"]=1;
    if(items["one"]) console.log("Есть"); else console.log("Нет");
    delete items["one"];
    if(items["one"]) console.log("Есть"); else console.log("Нет");
    
    // либо
    items["one"]=0;
    if(items["one"]) console.log("Есть"); else console.log("Нет");


    4.
    Мне нужно сделать так, что если человек постоянно кликает по кнопке, то обновлять таймер

    у вас собственно вообще нет обработки повторного клика на туже кнопку, вместо этого у вас
    удаление излишне созданного контейнера, т.к. он выше добавляется безусловно:
    if (index > 0) {
              $(this).remove();
           }

    и возврат из обработчика если есть элемент (т.е. ранее был клик):
    if (items[name]) return;

    5. для возобновления таймера, вам надо написать обработчик повторного нажатия а не выходить из обработчика по условию
    if (items[name]) return;

    т.е. так:
    if (items[name]) {
    // остановка анимации таймера и запуск заново
    } else {
    // код первого запуска таймера.
    }


    остановка анимации, см. метод .stop

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

    как-то так.

    UPDATE:

    Ответ написан
  • Как автоматически задать высоту фрейма?

    Про Размеры и прокрутка страницы
    Про Общение между окнами

    Политика «Одинакового источника» говорит, что:

    • если у нас есть ссылка на другой объект window, например, на всплывающее окно, созданное с помощью window.open или на window из и у этого окна тот же источник, то к нему будет полный доступ.
    • в противном случае, если у него другой источник, мы не сможем обращаться к его переменным, объекту document и так далее. Единственное исключение – объект location: его можно изменять (таким образом перенаправляя пользователя). Но нельзя читать location (нельзя узнать, где находится пользователь, чтобы не было никаких утечек информации).



    и есть решение по кроссдоменным iframe
    Автоматическая кросс-доменная установка высоты Iframe

    PS: но скрипты должны интегрироваться на обе стороны, на странице хосте и на странице в ифрейме.

    PPS:
    <iframe src="<?= $link ?>?partnerID=<?= $partnerID ?>" width="100%" height="100%" scroll="no" marginheight="0" frameborder="0" id="<?=$code?>" name="<?=$code?>"></iframe>

    если размеры известны, то их можно и задать в пикселях.
    Ответ написан
  • Как оптимизировать создание элемента?

    • В аттрибут src элемента script нельзя записывать массив!
    • Вы передаете два параметра (адреса), соответственно необходимо создать два элемента script и оба добавить в body


    как-то так:

    function loadScripts(arrScr) {
      arrScr.forEach((src) => {
        var scr = document.createElement('script');
        scr.src = src;
        document.body.appendChild(scr);
      })
    }
    
    if (window.location.href.indexOf('index') != -1) {
         loadScripts(['js/scripts.js', 'js/scripts2.js']);
    }
    Ответ написан
  • Можно ли в JQuery (или чистом JS) создать переменную, которая будет соответствовать DOM? То есть, если элемента больше нет в DOM, то и length равен 0?

    // Выдает 1, а должно 0.


    Не должно!
    Потому что .remove()
    Remove the set of matched elements from the DOM.
    т.е. удаляет набор соответствующих элементов из DOM

    что успешно и выполняется.
    но т.к. вы сделали ссылку на этот элемент
    let $elem_1 = $('.elem-2').prev();
    он продолжает существовать и будет удален когда исчезнет последняя ссылка на него.

    нужно удалить ссылку на объект, например так:
    $elem_1 = null;

    т.е. при удалении из DOM, удалять так же и ссылку из переменной:
    $('.elem-1').remove();
    $elem_1 = null;


    так же, если вы объявите саму переменную как свойство какого либо объекта, то ее можно удалить.
    если за функцией то достаточно это сделать без var или let/const, тогда эта переменная будет свойством window
    либо в функции как window.$elem_1
    см. delete

    т.е. в коде вы должны удалять не только из DOM методом .remove(), но и само свойство ("переменную").

    $(function() {
      window.$elem_1 = $('.elem-2').prev();
    
      delete window.$elem_1;
      $('.elem-1').remove();
    
      console.log(window.$elem_1.length);
      // TypeError: window.$elem_1 is undefined
    });


    PS: можно создать объект с соответствующими свойствами и методами и пользоваться методами этого объекта.

    например как-то так:

    $obj = {
    	$elem: null,
      set: function (el) {
      	this.$elem = el;
      },
      del: function() {
      	$(this.$elem).remove();
      	delete this.$elem;
      },
      isExists: function() {
      	return !!this.$elem;
      }
    }
    
    $obj.set( $('.elem-2').prev() );
    
    console.log($obj.isExists(), $obj.$elem.text());
    
    $obj.del();
    
    console.log($obj.isExists());


    объект можно переделать и хранить массив элементов, соответственно переделать и методы манипуляции.

    похожие механизмы реализованы например в React.js
    там есть свой виртуальный DOM с которым и производится манипуляция, которая в последствии переносится на реальный DOM методом render
    Ответ написан
  • Как в регулярном выражении исключить слова JS?

    Имхо, желательно делать проверку полнее, т.к. ну чисто теоретически такие слова могут быть в имени пользователя например, так же не делать инверсию результата, т.к. метод все же называется isInvalid

    isInvalid: function(input) {
      return /@(gmail|yahoo)\.[a-z]+$/.test(input.value.trim().toLowerCase());
    }


    PS: если проверка НА валидность, то поставить !
    Ответ написан
  • Можно ли это как то упростить?

    Ок, если вам не интересно просто подумать, то примерно так:

    function recountItem(el_summ, el_quantity, n_price, e) {
      action = e ? e.target.className.match(/\w+_+(\w+)/)[1] : '';
      n_quantity = parseInt(el_quantity.text());
      switch(action){
        case 'plus':
        case 'increment':
          n_quantity ++;
          break;
        case 'minus':
        case 'decrement':
          n_quantity = n_quantity > 1 ? n_quantity - 1 : n_quantity;
          break;
      }
      el_quantity.text(n_quantity);
      el_summ.text(n_quantity * n_price + ' грн.');
    };
    
    //order
    
    $('.order__block').each(function() {
      var $e = $(this),
          el_quantity = $e.find('.order__value'),
          el_summ = $e.find('.order__sum'),
          n_price = $e.find('.order__value').attr('data-number');
    
      $e.find('.order__plus').click(function(e) {
        recountItem(el_summ, el_quantity, n_price, e)
      });
    
      $e.find('.order__minus').click(function(e) {
        recountItem(el_summ, el_quantity, n_price, e)
      });
    
      recountItem(el_summ, el_quantity, n_price);
    });
    
    //single
    
    $('.single__row').each(function() {
      var $e = $(this),
          el_quantity = $e.find('.single__count'),
          el_summ = $e.find('.single__price'),
          n_price = $e.find('.single__count').attr('data-price');
    
      $e.find('.single__increment').click(function(e) {
        recountItem(el_summ, el_quantity, n_price, e)
      });
    
      $e.find('.single__decrement').click(function(e) {
        recountItem(el_summ, el_quantity, n_price, e)
      });
    
      recountItem(el_summ, el_quantity, n_price);
    });
    
    //basket
    
    $('.basket__item').each(function() {
      var $e = $(this),
          el_quantity = $e.find('.basket__value> span'),
          el_summ = $e.find('.basket__sum'),
          n_price = $e.find('.basket__single').text();
    
      $e.find('.single__increment').click(function(e) {
        recountItem(el_summ, el_quantity, n_price, e);
        updateBasketTotalSum();
      });
    
      $e.find('.single__decrement').click(function(e) {
        recountItem(el_summ, el_quantity, n_price, e);
        updateBasketTotalSum();
      });
    
      recountItem(el_summ, el_quantity, n_price);
      updateBasketTotalSum();
    });
    
    function updateBasketTotalSum() {
      var sum = 0;
      $('.basket__sum').each(function() {
         sum += parseInt($(this).text());
       });
      $('.basket__count').text(sum + ' грн.');
    }
    
    $('.basket__close').on('click', function() {
      $(this).parent().parent().remove();
    });


    если нигде в синтаксисе не ошибся, то должно работать вроде как.

    PS: все повторяющиеся действия вынесены в ОДНУ функцию, тем более что у вас во все функции передавались ссылки на html элементы и действия абсолютно одинаковые. А action определяется по className элемента, который берется из event'а

    PPS: только какой профит с готового решения??
    Ответ написан
  • Как сделать импорт в js другой js в chrome extention?

    Вы это читали?
    https://developer.chrome.com/extensions/content_sc...

    Declaratively injected scripts are registered in the manifest under the "content_scripts" field. They can include JavaScript files, CSS files or both. All auto-run content scripts must specify match patterns.

    {
    "name": "My extension",
    ...
    "content_scripts": [
    {
    "matches": ["http://*.nytimes.com/*"],
    "css": ["myStyles.css"],
    "js": ["contentScript.js"]
    }
    ],
    ...
    }


    js array of strings Optional. The list of JavaScript files to be injected into matching pages. These are injected in the order they appear in this array.

    тоже самое и с секцией background
    https://developer.chrome.com/extensions/background...

    {
    "name": "Awesome Test Extension",
    ...
    "background": {
    "scripts": [
    "backgroundContextMenus.js",
    "backgroundOmniBox.js",
    "backgroundOauth.js"
    ],
    "persistent": false
    },
    ...
    }

    PS: в popup они вставляются через тег script как в обычном HTML файле.
    Ответ написан
  • Как на чистом js копировать html элемент со всеми его дочерними элементами?

    такое мне кажется все делают по разному, что правильно выбираете сами.
    варианты:
    1. блок с работами имеет фиксированную высоту с overflow: hidden
    при нажатии на кнопку высота блока увеличивается, блок с кнопкой скрывается.
    можно это дело анимировать, ну чтоб плавно высота увеличивалась.
    2. блок с работами состоит из нескольких блоков, по умолчанию показывается первый, при нажатии на кнопку появляется второй блок (меняем ему display), блок с кнопкой скрывается.
    3. добавлять элементы скриптом, через .appendChild(childElement) например:
    document.querySelector(".works__more__btn").addEventListener("click", function() {
      var elem = document.createElement("div");
      elem.setAttribute("class", "works__content__smallRow");
      elem.innerHTML = `
                    <img src="https://www.placehold.it/375x327/25" class="works__content__smallRow__item">
                    <img src="https://www.placehold.it/375x327/50" class="works__content__smallRow__item">
                    <img src="https://www.placehold.it/375x327/75" class="works__content__smallRow__item">
                    <img src="https://www.placehold.it/375x327/100" class="works__content__smallRow__item">
    `;
      document.querySelector(".works__content").appendChild(elem);
      document.querySelector(".works__more").style.display = "none";
    });


    как-то так...

    UPD:
    собственно копирование:

    вы правильно сделали cloneNode, но!!!
    см. Метод Node.cloneNode()
    если вы хотите копировать с дочерними элементами, то необходимо передать параметр "deep" = true

    Т.е. вот так:
    document.querySelector(".works__more__btn").addEventListener("click", function() {
      document.querySelector(".works__content").appendChild(document.querySelector(".works__content").cloneNode(true));
      document.querySelector(".works__more").style.display = "none";
    });
    Ответ написан
  • Почему не работает проверка при отправке формы?

    Дело в том что у вас проверка email выполняется только в том случае если не выполняется условие по имени:
    if ($('#name').val().length >= 3) {
          $(this).find('#name').css("border", "1px solid rgb(169, 169, 169)");
      } else if ($('#email').val().length > 10 && $('#email').val().search(pattern) == 0) {
        $(this).find('#email').css("border", "1px solid rgb(169, 169, 169)");
      }


    else if

    надо без else, тогда оба условия будут проверяться независимо.
    if ($('#name').val().length >= 3) {
        $(this).find('#name').css("border", "1px solid rgb(169, 169, 169)");
    }
    if ($('#email').val().length > 10 && $('#email').val().search(pattern) == 0) {
        $(this).find('#email').css("border", "1px solid rgb(169, 169, 169)");
    }


    и т.д.
    Ответ написан
  • Как выводить в одном модальном окне данные из разных карточек товара по клику на кнопку?

    Ну например переписывать содержимое карточки в модальное окно перед его отображением.
    как-то то так:
    btn.onclick = function() {
    modal.innerHTML = btn.innerHTML;
    modal.style.display = "flex";
    }
    Ответ написан
  • Как пробросить UTM-метку из реферрера и поставить в адресную строку?

    см.:
    -> document.referrer
    -> document.location

    -> javascript работа со строками
    -> javascript работа с массивами
    -> javascript разбор url

    ну и например можно вот так:
    document.location.href += "&" + document.referrer
                                    .split("?")[1]
                                    .split("#")[0]
                                    .split("&")
                                    .filter(str => str.indexOf("utm_") > -1)
                                    .join("&");


    .split
    .filter
    .join

    Upd:
    на случай если у реферера нет параметров, сделать проверку

    document.location.href += document.referrer.indexOf("?") > -1 ?
                "&" + document.referrer
                .split("?")[1]
                .split("#")[0]
                .split("&")
                .filter(str => str.indexOf("utm_") > -1)
                .join("&") : "";
    Ответ написан