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

    @dmitriu256 Автор вопроса
    Kovalsky, исходя из описанного алгоритма действий получилось следующее
    Вариант1 (поиск городов осуществляется на сервере с отдачей результата клиенту)
    Серверная часть (express js + nodejs)
    //используем этот запрос для живого поиска
    app.post('/city', function(req,res){
    
        let text = req.body.text;
    
       let val = text.trim().toLowerCase(); // приходит от пользователя
        console.log(val);
    
        let city = arr.filter(el => {
            if(val){
                return el.Description.toLowerCase().search(val) !== -1;
            }
        });
        
        res.send(city); // возвращаем массив с данными иначе пустой массив
    });
    
    app.listen(PORT, function(){
        console.log(`Прослушиваем порт по адресу ${PORT}`);
        //Формируем справочник городов компании
            let cityObj = {
                "modelName": "Address",
                "calledMethod": "getCities",
                "methodProperties": {},
                "apiKey": apiKey
            };
            request.post(
                'https://api.novaposhta.ua/v2.0/json/',
                {
                    json: cityObj,
                    headers: {
                        "Content-type": "application/json",
                    }
                },
                function (error, response, body) {
                    let data = body;
    
                    for(let i = 0; i < data.data.length; i++) {
                        arr.push(data.data[i]);
                        console.log(arr[i]);
                    }
                });
        });

    Клиентская часть обработки
    let city = calcForm.elements['cargo-city-to'];
    
    
    if(city.previousElementSibling.hasAttribute('data-select')){
        let el = city.previousElementSibling.querySelector('[data-select-title]');
        el.setAttribute('contenteditable', true);
    
        el.addEventListener('focus', function(){
            this.textContent = '';
    
        });
    
        el.addEventListener('input', function(){
            //Очистка декоративных пунктов
            let selected = city.previousElementSibling.querySelectorAll('[data-select-item]');
    
            
            selected.forEach(el => {
                console.log(el.textContent);
                el.remove();
            });
    
            //очистка стандартного селекта
            for(let i = 0; i < city.options.length; i++){
                city.remove(i);
            }
    
    
            //Запрос живого поиска
            let xhr = new XMLHttpRequest();
    
            xhr.open('POST', 'http://localhost:3010/city');
    
            xhr.setRequestHeader('Content-type', 'application/json; charset = utf-8');
    
            //Отправка данных на сервер
            xhr.send(JSON.stringify({text: this.textContent}));
            console.log(this.textContent);
    
            //проверяем состояние запроса
            xhr.addEventListener('readystatechange', function () {
                if (xhr.readyState < 4) {
    
                } else if (xhr.readyState === 4 && xhr.status === 200) {
    
                    let data = JSON.parse(xhr.response);
    
                    for(let i = 0; i < data.length; i++) {
                        //Формируем список опций у реального селекта
                        createOptions(data[i]);
    
                        city.append(createOptions(data[i]));
                    }
    
                    //Формируем данные в декоративном селекте
                    if(city.previousElementSibling.hasAttribute('data-select')){
    
                        let select = city.previousElementSibling.querySelector('.form-select__dropdown');
    
                        for(let i = 0; i < data.length; i++) {
                            createSelectItem(data[i]);
                            select.append(createSelectItem(data[i]));
                        }
                    }
    
                } else {
                    console.log('Что то пошло не так');
                }
    
            });
    
        });
    }else{
        console.log('---');
    }
    
    
    getCity(city, `http://localhost:3010/city`);
    
    
    //Изначально загружаем с сервера 5 записей из массива городов (что бы декоративный селект имел некоторый список по умолчанию)
    function getCity(elem, url){
        let xhr = new XMLHttpRequest();
    
        xhr.open('GET', url);
    
        xhr.setRequestHeader('Content-type', 'application/json; charset = utf-8');
    
        //Отправка данных на сервер
        xhr.send();
    
        //проверяем состояние запроса
        xhr.addEventListener('readystatechange', function () {
            if (xhr.readyState < 4) {
    
            } else if (xhr.readyState === 4 && xhr.status === 200) {
    
                let data = JSON.parse(xhr.response);
    
                for(let i = 0; i < 5; i++) {
    
                    createOptions(data[i]);
    
                    elem.append(createOptions(data[i]));
                }
    
                //Формируем данные в декоративном селекте
                if(elem.previousElementSibling.hasAttribute('data-select')){
    
                    let select = elem.previousElementSibling.querySelector('.form-select__dropdown');
    
                    for(let i = 0; i < 5; i++) {
                        createSelectItem(data[i]);
                        select.append(createSelectItem(data[i]));
                    }
                }
    
            } else {
                console.log('Что то пошло не так');
            }
    
        });
    }


    Вариант2 (когда вся логика происходит на клиенте, используем API напрямую, города храним в localStorage)
    //Получение городов компании
        let cityTo = calcForm.elements['cargo-city-to'];
        let cityFrom = calcForm.elements['cargo-city'];
    
        checkKeyCity('Mycity', cityTo);
        checkKeyCity('Mycity', cityFrom);
    
        //Получение куки
        function getCookie(name) {
            let matches = document.cookie.match(new RegExp(
                "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
            ));
            return matches ? decodeURIComponent(matches[1]) : undefined;
        }
    
        //Загрузка городов в localStorage
        function getCities(){
            let date = new Date();
            date = new Date(date.setDate(date.getDate() + 1));
    
    
            let cityObj = {
                "modelName": "Address",
                "calledMethod": "getCities",
                "methodProperties": {},
                "apiKey": apiKey
            };
    
            let xhr = new XMLHttpRequest();
    
            xhr.open('POST', 'https://api.novaposhta.ua/v2.0/json/');
    
            xhr.setRequestHeader('Content-type', 'application/json; charset = utf-8');
    
            //Отправка данных на сервер
            xhr.send(JSON.stringify(cityObj));
    
            //проверяем состояние запроса
            xhr.addEventListener('readystatechange', function () {
                if (xhr.readyState < 4) {
    
                } else if (xhr.readyState === 4 && xhr.status === 200) {
                    let city = [];
                    let obj = {};
    
                    let cities = JSON.parse(xhr.response);
    
                    for (let i = 0; i < cities.data.length; i++) {
    
    
                        obj = {
                            Ref: cities.data[i].Ref,
                            Description: cities.data[i].Description
                        };
    
                        //Сформировали справочник населенных пунктов
                        city.push(obj);
    
                    }
    
                    localStorage.setItem('Mycity', JSON.stringify(city));
    
                } else {
                    console.log('Что то пошло не так');
                }
            });
    
            document.cookie = `${decodeURI('cities')} = ${decodeURI(true)}; expires = ${date}; path = /`;
        }
    
    
        //Проверка наличие куки
        if(getCookie('cities') === undefined) {
            getCities();
        }
    
        //Проверка наличия ключа в localStorage
        function checkKeyCity(key, element){
    
            if (localStorage.getItem(key) !== null){
                let data = JSON.parse(localStorage.getItem(key));
    
                //Формируем данные в селекте
                for(let i = 0; i < data.length; i++) {
    
                    createOptions(data[i]);
    
                    element.append(createOptions(data[i]));
                }
    
    
                //Формируем данные в декоративном селекте
                if(element.previousElementSibling.hasAttribute('data-select')){
                    let select = element.previousElementSibling.querySelector('.form-select__dropdown');
                    select.overflowY = 'scroll';
    
                    for(let i = 0; i < data.length; i++) {
                        createSelectItem(data[i]);
                        select.append(createSelectItem(data[i]));
                    }
                }
    
    
                let el = element.previousElementSibling.querySelector('[data-select-title]');
                el.setAttribute('contenteditable', true);
    
                el.addEventListener('focus', function(){
                    this.textContent = '';
                });
    
    
                //Живой поиск ++
                el.addEventListener('input', function(){
    
                    element.previousElementSibling.querySelector('.form-select__dropdown').classList.remove('hidden');
    
                    let val = this.textContent.trim().toLowerCase();
    
                    let items = element.previousElementSibling.querySelectorAll('.form-select__item');
    
    
                    if(val != ''){
                        items.forEach(function(elem) {
                            if(elem.textContent.toLowerCase().search(val) == -1) {
                                elem.classList.add('hidden');
                            }else{
                                elem.classList.remove('hidden');
                            }
                        });
                    }else{
                        items.forEach(function(elem) {
                            elem.classList.remove('hidden');
                        });
                    }
                });
    
            }
        }

    Итог
    Остановился на Варианте2 - скорость поиска быстрее, тк один раз загружаем города в хранилище в дальнейшем постоянно обращаемся к нему, без использования ресурсов сервера.
    -Построение DOM дерева происходит один раз
    - живой поиск осуществляется простым добавления класса hidden городов, которые не подходят под условия поиска.
    Ответ написан
    1 комментарий
  • Почему пропадает содержимое slick-slider?

    @dmitriu256 Автор вопроса
    Решил задачу немного по другому
    visibility: hidden
    Все успешно заработало без изменения js-кода
    Ответ написан
    Комментировать
  • Как обойти cors ограничение ajax method POST?

    @dmitriu256 Автор вопроса
    Задание решено через создание собственного сервера на nodejs+express+бибилотека require
    Код сервера
    app.get('/primer', function(req,res){
        request.post({url:'https://mysite.com/test', form: {key:'value'}}, function(err,httpResponse,body){
            console.log(body);
            res.json(JSON.parse(body));
        });
    
    });


    Клиентская часть
    let btn = document.getElementById('test');
    let res = document.getElementById('res');
    
    btn.addEventListener('click', function(){
    
        let xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://localhost:3000/primer');
        xhr.send();
    
        xhr.addEventListener('readystatechange', function(){
            if(xhr.readyState == 4 && xhr.status == 200){
                let data = JSON.parse(xhr.response);
                console.log(data);
                res.innerHTML = data.token;
            }
        });
    });

    Может кому и пригодиться.
    Ответ написан
    Комментировать