Ответы пользователя по тегу JavaScript
  • Как преобразовать такой массив в нумерованный многоуровневый список?

    Finesse
    @Finesse
    Реализация алгоритма на JavaScript:

    function treeToPlainList(tree, idPrefix = '') {
        let list = [];
    
        // Проходит по каждому элементу массива
        tree.forEach((item, index) => {
            // Добавляет к элементу свойство id
            const itemForPlainList = {...item, id: idPrefix + (index + 1)};
            // Удаляет из элемента свойство children
            delete itemForPlainList.children; 
            // Добавляет элемент в итоговый массив
            list.push(itemForPlainList);
    
            if (item.children) {
                // Добавляет в конец итогового массива элементы, которые возвращает функция treeToPlainList
                list = [...list, ...treeToPlainList(item.children, idPrefix + (index + 1) + '.')];
            }
        });
    
        return list;
    }
    
    const list = treeToPlainList(tree); // tree — изначальный массив, list — результат
    Ответ написан
  • Как осуществить такую анимацию?

    Finesse
    @Finesse
    Через <canvas>. Программирование производится с помощью JavaScript. Схема примерно такая:
    1. На то место, где должен быть эффект, помещается canvas, который занимает всю площадь места.
    2. В памяти генерируется набор случайных точек со своим вектором скорости.
    3. В каждом кадре анимации точки сдвигаются в соответствии в вектором скорости.
    4. В каждом кадре анимации точки отрисовываются на canvas. Дополнительно проводятся линии между всеми парами точек, между которыми расстояние меньше определённого значения.

    Есть готовая библиотека для создания таких анимаций.
    Ответ написан
    Комментировать
  • Как изменить текст балуна метки, добавленной через ObjectManager (API Яндекс Карт)?

    Finesse
    @Finesse Автор вопроса
    objectManager.objects.getById(1).properties.balloonContentBody = 'Загружено (тут полезная информация)';

    Где 1 — id нужной точки. Будьте осторожны, objectManager.objects.getById может вернуть null. Демо на CodePen.

    У способа есть недостаток. Содержимое всплывающего окна не изменится, пока оно открыто. Новый текст применяется перед открытием балуна.
    Ответ написан
    Комментировать
  • Как добавить метки с помощью objectManager на Яндекс.картах?

    Finesse
    @Finesse
    Указанный вами код для задания списка меток нужно поместить внутрь функции createMap, переименовав переменную myMap в map. Туда же нужно поместить код для задания элементов управления

    Вот более простой пример создания карты со списком меток, добавляемым через ObjectManager:

    ymaps.ready(function() {
        // Создание карты и установка элементов управления
        var map = new ymaps.Map(document.getElementById('map'), {
            center: [42, 54],
            zoom: 6,
            controls: ['zoomControl', 'fullscreenControl'] // Полный список тут: https://tech.yandex.ru/maps/doc/jsapi/2.1/dg/concepts/controls-docpage/#standard
        });
    
        // Добавление меток через ObjectManager
        var objectManager = new ymaps.ObjectManager({
            clusterize: true
        });
        map.geoObjects.add(objectManager);
        $.ajax({
            url: 'wp-content/themes/urbech-style/data.json'
        }).done(function(data) {
            objectManager.add(data);
        })
    });
    Ответ написан
    Комментировать
  • Как запускать js только на страницах в URL которых есть /shop/?

    Finesse
    @Finesse
    Вот так, если надо, чтобы путь содержал /shop/:
    if (window.location.pathname.indexOf('/shop/') >= 0)) {
      alert('Работает');
    }

    Вот так, если надо, чтобы страница была в директории shop, которая располагается в корне сайта (как в примерах в вопросе):
    if (window.location.pathname.match(/^\/shop(\/|$)/)) {
      alert('Работает');
    }
    Ответ написан
    1 комментарий
  • Как правильно задать условие в цикле while?

    Finesse
    @Finesse
    While строго обязателен? Я бы сделал так:

    [100, 80, 60, 50, 40, 20, 10, 0].forEach(function(number) {
        document.write('Число: <b>' + number + '</b><br>');
    });
    Ответ написан
  • В чём разница done и success в ajax?

    Finesse
    @Finesse
    Практически ни в чём. Функции, переданные туда, будут выполнены при одинаковых условиях.

    Разница лишь в том, как передаётся функция-обрабочик события done (при инициализации запроса в первом случае и привязкой к обещанию во втором случая). На практике разница заключается в том, что втором примере можно указать сразу несколько функций, которые будут вызваны при завершении:

    var deferred = $.ajax({ ... });
    deferred.done(function(data) { /* Действие 1 */ });
    deferred.done(function(data) { /* Действие 2 */ });
    Ответ написан
    1 комментарий
  • Как заблокировать остальные чекбоксы при клике по чекбоксу с value=0, к примеру?

    Finesse
    @Finesse
    jQuery тут не нужен. Работает в IE≥9.

    var masterCheckbox = document.querySelector('input[type="checkbox"][value="0"]');
    var slaveCheckboxes = document.querySelectorAll('input[type="checkbox"]:not([value="0"])');
    
    masterCheckbox.addEventListener('change', function() {
        if (masterCheckbox.checked) {
            // Галочка поставлена. Деактивируем остальные чекбоксы.
            Array.prototype.forEach.call(slaveCheckboxes, function(checkbox) {
                checkbox.checked = false;
                checkbox.disabled = true;
            });
        } else {
            // Галочка убрана. Активируем остальные чекбоксы.
            Array.prototype.forEach.call(slaveCheckboxes, function(checkbox) {
                checkbox.disabled = false;
            });
        }
    });
    Ответ написан
  • Как получать Email с вашего сайта без использования PHP?

    Finesse
    @Finesse
    Воспользоваться сервисом email-рассылок, например, MailChimp. Там вам дадут готовый HTML-код формы или API для более гибкой настройки формы, с помощью которой email-адреса будут отправляться на сервер сервиса и сохраняться там.
    Ответ написан
    Комментировать
  • Как исправить генерацию лишних событий dragenter и dragleave?

    Finesse
    @Finesse Автор вопроса
    С этим хорошо справляется библиотека Dragster.
    Ответ написан
    Комментировать
  • Как сделать логику из общих значений?

    Finesse
    @Finesse
    Лучше всего применить однонаправленный поток данных.

    То есть. Хранить в постоянной памяти только исходный набор данных в виде списка объектов:
    var items = [
      {
        color: 'red',
        size: 100
      },
      {
        color: 'blue',
        size: 70
      }
      // и так далее
    ]

    Затем, когда пользователь выбрал какой-нибудь фильтр, например, цвет красный, пройтись по списку items и собрать те значения фильтра "размер", которые встречаются в элементах, которые подходят под фильтр цвета:
    var color = 'red';
    var availableSizes = [];  // Будет содержать список доступных размеров для красного цвета
    
    items
      // Отсеиваем элементы по фильтру цвета
      .filter( function( item ) { return item.color === color; })
      // Собираем значения фильтра размера для них
      .forEach( function( item ) {
        if ( availableSizes.indexOf( item.size ) === -1 )
          availableSizes.indexOf.push( item.size );
      });

    Полученный список размеров нужно передать в селектор на представлении и забыть его. Если пользователь выбрал другой цвет, то нужно взять начальный массив items и заново проделать с ним операцию, описанную выше. Не надо сохранять и использовать результат предыдущего запроса, надо работать только с начальным набором данных и тем, что ввёл пользователь, иначе сложность программы будет расти быстрее грибов после дождя.
    Ответ написан
    Комментировать
  • Как сделать вызов функции?

    Finesse
    @Finesse
    Вы вызываете функцию runCar прямо во время вызова animate, а не посылаете её вызываться по завершению анимации, потому что круглые скобки сразу после её названия вызывают её в тот же момент. Чтобы вызвать её с указанными аргументами по завершению анимации, сделайте так:
    function runCar(carNumber) {
      $(".car").animate({$start,$speed, 'linear', function() {
        runCar(carNumber)
      });
    }
    Ответ написан
    Комментировать
  • Как понять такое поведение участка кода на js?

    Finesse
    @Finesse
    Чтобы добиться правильного вывода, нужно создать замыкание. Например, так:
    for (var i = 0; i < 10; i++) {
      // Значение переменной i копируется в переменную value, которая при каждом из 10 вызовов отдельная
      (function(value) {
        setTimeout(function () {
          console.log(value);
        }, 0);
      })(i);
    }
    Ответ написан
    Комментировать
  • Как понять строку кода. (метод splice и оператор ...)?

    Finesse
    @Finesse
    Метод apply функции вызывает эту функцию с указанными аргументами. Первый аргумент метода apply — значение переменой this внутри функции во время её выполнения, а второй — список аргументов в виде массива.

    Метод concat массива объединяет его с другими массивами. Если конкретней, то к массиву, на котором он вызван, добавляет содержимое массивов из всех аргументов и возвращает итоговый массив. При этом массив, на котором вызван этот метод, остаётся неизменным.

    В строке
    arr.splice.apply(arr, [index, tmpArr.length].concat(tmpArr));
    сначала составляется список аргументов с помощью метода concat (массив аргументов, переданных по-обычному, объединяется с аргументами, переданными через оператор ...), затем с помощью apply вызывается метод splice массива и ему передаётся составленный массив аргументов.
    Ответ написан
    3 комментария
  • Как реализовать метод .change на js?

    Finesse
    @Finesse
    Если полей ввода больше одного или неизвестно сколько:
    var inputs = document.querySelectorAll( "input" );
    
    for ( var i = 0; i < inputs.length; ++i ) {
        inputs[ i ].addEventListener( 'change', function() {
            alert("The text has been changed.");
        });
    }


    Если поле ввода всегда одно:
    document.querySelector( "input" ).addEventListener( 'change', function() {
        alert("The text has been changed.");
    });
    Ответ написан
    2 комментария
  • Как изменить сам тег с помощью js (jq)?

    Finesse
    @Finesse
    У DOM-элемента невозможно изменить тэг. Можно только заменить старый элемент на новый, перенеся всё его содержимое. Например, так:

    function replaceTag( element, newTag )
    {
        var elementNew = document.createElement( newTag );
        elementNew.innerHTML = element.innerHTML;
    
        Array.prototype.forEach.call( element.attributes, function( attr ) {
            elementNew.setAttribute( attr.name, attr.value );
        });
    
        element.parentNode.insertBefore( elementNew, element );
        element.parentNode.removeChild( element );
        return elementNew;
    }


    Функция не переносит слушатели событий. Возвращает новый элемент.
    Ответ написан
    Комментировать
  • Как измерить 1 месяц на javascript?

    Finesse
    @Finesse
    Сохраняем значение var startTime = (new Date()).getTime(); в хранилище, а потом проверяем, прошёл ли месяц:
    if ( (new Date()).getTime() > startTime + 30 * 24 * 60 * 60 * 1000 )
      alert( 'Месяц прошёл' );
    Ответ написан
    Комментировать
  • Стоит ли сейчас изучать JQuery?

    Finesse
    @Finesse
    Именно jQuery — не обязательно. Но она (и подобные) берёт на себя большое количество рутины в коде.
    Ответ написан
    Комментировать
  • Как динамически подключать скрипты и стили на одностраничном сайте?

    Finesse
    @Finesse
    Подключение скрипта динамически:
    var elem = document.createElement( 'script' );
    elem.type = 'text/javascript';
    elem.async = true;
    document.body.appendChild( elem );
    elem.src = 'Ваш скрипт.js';


    Подключение файла стилей динамически:
    var elem = document.createElement( 'link' );
    elem.rel = 'stylesheet';
    elem.type = 'text/css';
    document.body.appendChild( elem );
    elem.href = 'Ваш стиль.css';
    Ответ написан
    4 комментария
  • Возможно ли уменьшить скрипт?

    Finesse
    @Finesse
    Да:
    function onResize() {
      $('.getstarted').height($('.getstarted').width() / (16/8));
    }
    $(onResize);		
    $(window).resize(onResize);
    Ответ написан