Ответы пользователя по тегу JavaScript
  • Как на jQuery свернуть развернуть div?

    AngReload
    @AngReload
    Кратко о себе
    $(document).ready(function(){
        $(".slideT").hide();
        $(".pointer").click(function () {
          // можно и иначе выбрать все другие блоки
          // вот так $(".pointer").not(this)
          $(this).siblings()
            .children()
            .slideUp("slow");
          $(this)
          	.children()
            .slideDown("slow");
        });
    })
    Ответ написан
  • Нужно вывести числа в заданном диапазоне. Почему выводит результат не при всех задаваемых значениях?

    AngReload
    @AngReload
    Кратко о себе
    Это конечно говнокод, но ошибка только одна:
    var n = prompt('введите начальное число диапозона', '0');
    var k = prompt('введите конечное число диапозона', '0' );

    prompt возвращает строки а не числа, поэтому нужно конвертировать в число, например так:
    var n = parseInt(prompt('введите начальное число диапозона', '0'), 10);
    var k = parseInt(prompt('введите конечное число диапозона', '0' ), 10);

    через Number или parseInt.

    Вообще, полезно знать разницу при сравнении чисел и строк:
    9 < 10 // true
    '9' < '10' // false
    Во втором случае получается «ложь», потому что строки сравниваются по кодам символов, начиная с первого символа, те '9' < '1'. Смотрим коды символов:
    '9'.charCodeAt(0) // 57
    '1'.charCodeAt(0) // 49
    57 больше 49, поэтому сравнение заканчивается, выдавая значение false.
    Поэтому условие цикла n <= k работает не как ожидается.
    Ответ написан
    1 комментарий
  • Как сделать checkbox равным 0 или 1?

    AngReload
    @AngReload
    Кратко о себе
    У checkbox отмечен он или нет определяется по наличию атрибута checked, а value не меняется.
    https://developer.mozilla.org/en-US/docs/Web/HTML/...

    function getData(obj_form){
        var hData = {};
        $('input, textarea, select', obj_form).each(function(){
            if(this.name && this.name!=='') {
                var data;
                if (this.type === 'checkbox') {
                    console.log('ветка true');
                    data = this.checked;
                } else {
                    console.log('ветка false');
                    data = this.value;
                }
                hData[this.name] = data;
                console.log('hData[' +this.name + '] = ' + hData[this.name]);
            }
        });
        return hData;
    };

    PS: В value надо писать что он означает, а не отмечен он или нет.
    Ответ написан
  • Почему множественный fetch-запрос возвращает Promise вместо объектов?

    AngReload
    @AngReload
    Кратко о себе
    Потому что then всегда возвращает promise.
    Даже если ты внутри функции resolve напишешь return 42, это then вернёт Promise(42).
    fetch(url).then(function(response) {
      return 42;
    })

    Это работает так по двум причинам.
    Первая, чтобы можно было без проблем писать .then().then().then(). Ведь если какой-нибудь then вернёт число посреди такой цепочки, то произойдёт ошибка. Ведь у чисел нет метода then, верно?
    (42).then() // => TypeError: 42.then is not a function
    Вторая причина, это то что промисы не выполняются сразу. В этом и смысл, верно? Мы создаём цепочку отложенных вычислений по принципу Если произошло это, тогда сделать То, а потом Вот это и т.д. Методу then просто нечего возвращать на тот момент, когда ты его запускаешь. Его запуск только создаёт план действий.

    Поэтому, когда ты запускаешь console.log(data), в массиве data лежат промисы. И они даже ещё не начали выполняться на этот момент. Ни одна из функций resolve или reject еще не была запущена.

    Код можно поправить так:
    'use strict';
    
    let urls = [
      'https://apiv2.bitcoinaverage.com/indices/global/ticker/ETHUSD',
      'https://apiv2.bitcoinaverage.com/indices/global/ticker/LTCUSD',
      'https://apiv2.bitcoinaverage.com/indices/global/ticker/BTCUSD'
    ];
    
    let data = urls.map((item, index) => {
      return fetch(item).then(function(response) {
        return response.json();
      }).then(function(data) {
        console.log(data);
      }).catch( alert );
    })
    
    console.log(data);
    Сначала в консоли появится массив промисов, который ты уже видел. А уже через секунду три объекта, которых ты ждал.

    Чтобы получить три объекта сразу, в массиве, нужно прибегнуть к либо async / await, либо как писали в других ответах Promise.all. Promise.all(array).then(resolve, reject) ждет выполнения всех промисов в array, и только тогда вызывает resolve или reject для массива ответов или ошибок.

    'use strict';
    
    let urls = [
      'https://apiv2.bitcoinaverage.com/indices/global/ticker/ETHUSD',
      'https://apiv2.bitcoinaverage.com/indices/global/ticker/LTCUSD',
      'https://apiv2.bitcoinaverage.com/indices/global/ticker/BTCUSD'
    ];
    let array = urls.map((item, index) => {
      return fetch(item).then(function(response) {
        return response.json();
      }).catch( alert );
    });
    
    Promise.all(array).then(console.log);
    Ответ написан
    1 комментарий
  • Как правильно написать код при клике на объект водвигается блок слева?

    AngReload
    @AngReload
    Кратко о себе
    Правильно. Трудно ошибиться в трёх строках.
    Ответ написан
  • Как сделать такие табы?

    AngReload
    @AngReload
    Кратко о себе
    Это обычные кнопки, которые лежат в родителе с display: flex; раньше такое делали с помощью display: inline-block;
    Под кнопками 10 таблиц, при нажатии на любую кнопку всем таблицам применяется display: none, а для таблицы равной href кнопки display: block;

    Вот onclick кнопки (его можно увидеть в инструментах разработчика):
    function(event) {
      event.preventDefault();
      $('.device_model_btns a').removeClass('active');
      $(this).addClass('active');
    
      var id = $(this).attr('href');
      $('.phone_tabs_item').hide();
      $('.phone_tabs_item').removeClass('phone_tabs_item_active');
    
      $(id).addClass('phone_tabs_item_active');
      $(id).show();
    
      resetMoreContentBtn();
    }
    Ответ написан
    Комментировать
  • Почему новый созданный объект конструктора не меняет локальные переменные конструктора?

    AngReload
    @AngReload
    Кратко о себе
    Вы наверное забыли, что при каждом запуске функции User всё что внутри её будет запущено заново, в том числе создание пустых переменных firstname и surname. Чтобы создать замыкание код должен быть такой:

    код убрал под спойлер
    var firstname, surname;
    function User() {
      this.setFirstName = function(name) {
        if (name.replace) {
        	firstname = name;
        }
        else {
        	throw new Error('Введите имя');
        }
      }
      this.setSurname = function(name) {
        if (name.search) {
        	surname = name;
        }
        else {
        	throw new Error('Введите фамилию');
        }
      }
      this.getFullName = function() {
      	return firstname + ' ' + surname;
      }
      
    }
    
    var user = new User();
    user.setFirstName("Петя");
    user.setSurname("Иванов");
    
    alert( user.getFullName() ); // Петя Иванов
    var user2 = new User();
    user2.setFirstName('Фёдор');
    user2.setSurname("Марков");
    alert( user2.getFullName() );
    alert( user.getFullName() ); // Уже не Петя Иванов

    То что раньше было это тоже замыкание, но каждый новый объект замыкал свои версии firstname и surname.
    Ответ написан
  • Как модернизировать скролл на IE11?

    AngReload
    @AngReload
    Кратко о себе
    Попробуй остановить видео когда текущая прокрутка не равна нулю. Оно всё равно фоновое, и даром не нужно его воспроизведение, когда оно на половину обрезано.
    Ответ написан
    Комментировать
  • Как сделать видео перематываемым?

    AngReload
    @AngReload
    Кратко о себе
    Перекодировать в ffmpeg с параметром g, если в видео 24fps то ставь -g 24 чтобы перемотка работала с точностью до секунды.
    ffmpeg -i tutor.mp4 -g 24 tutorWithG48.mp4
    Ответ написан
    Комментировать
  • ShowingTooltip = null; зачем?

    AngReload
    @AngReload
    Кратко о себе
    С 14 по 26 устанавливаются координаты где будет расположена подсказка. Считается исходя из позиции вьюпорта, элемента на который наведена мышь, и размеров посказки. И если координата заходит за верхнюю или левую границу вьюпорта (те отрицательные получились), то кординаты ставятся такие что бы подсказка была в его границах.
    На 27-й сохраняется элемент подсказки в переменную «showingTooltip», чтобы потом её можно было скрыть при отведении мыши.

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

    AngReload
    @AngReload
    Кратко о себе
    function func(arr, parametres) {
    	for (let i = 0; i < parametres.length; i++) {
    		const param = parametres[i];
    
    		let condition;
    		if (param.type === 'type1') {
    			condition = true;
    		} else if (param.type === 'type2') {
    			condition = false;
    		} else {
    			// может ли быть 'type3' или что-то такое, тогда пропускаем этот шаг
    			continue;
    		}
    
    		// судя по телу второго цикла
    		// при каждой итерации founded переписывается
    		// значит в результате происходит сравнение только последней пары
    		// и цикл можно убрать
    		if (
    			(
    				arr[arr.length - 1].property1 === param.property1 &&
    				arr[arr.length - 1].property2 === param.property2
    			) === condition
    		) {
    			return false;
    		}
    
    		// но скорее всего это была бага, и цикл нужно переписать так
    		for (let j = 0; j < arr.length; j++) {
    			if (
    				(
    					arr[j].property1 === param.property1 &&
    					arr[j].property2 === param.property2
    				) === condition
    			) {
    				// при первом же совпадении функция будет завершена
    				// без бесполезных проходов по оставшимся элементам
    				return false;
    			}
    		}
    	}
    	return true;
    };
    Ответ написан
    1 комментарий
  • Замыкания, return и ссылки на функцию?

    AngReload
    @AngReload
    Кратко о себе
    Кратко.

    В первом случае, функция создаёт и возвращает bar.
    При каждом запуске происходит создание объекта bar. И при каждом запуске функции, она возвращает уникальную ссылку на уникальный объект.

    Во втором случае, функция возвращает foo.
    В коде функции нет объявления foo, а значит это переменная в лексическом окружении при создании функции.
    Функция создаётся только один раз, значит и эта переменная будет одна и та же при каждом запуске.

    Нужно знать, как работают объекты в js, чем отличаются от примитивных типов. Они не равны, даже если они имеют одинаковое содержимое, они все равно хранятся в разных областях памяти. Только примитивы в виде чисел \ строк \ null, undefined равны если их содержимое одинаково. Объекты не копируются при присвоении, только создаются ссылки на них.
    Ответ написан
    Комментировать
  • Насколько актуальна книга "Javascript Patterns" С. Стефанова?

    AngReload
    @AngReload
    Кратко о себе
    Пролистал, похоже на Руководство по написанию JavaScript кода от Airbnb(), но более развёрнуто. Цель книги, как я понимаю, показать особенности js кода, и как лучше сделать то чего можно добиться разными путями.
    То что там написано, наверное ещё очень долго будет актуальным. Но, например, вместо var сейчас принято использовать let и const, про оператор delete я почему-то не нашел упоминания что его лучше не использовать. Думаю это некритично.
    Ответ написан
    Комментировать
  • Как организовать быструю сортировку на JS со средним опорным элементом?

    AngReload
    @AngReload
    Кратко о себе
    Несколько мелких ошибок
    function quickSort (array) {
    	if (array.length <= 1) { // так понятнее
    		return array;
    	} else {
    		let pivotIndex = Math.floor(array.length / 2); // так понятнее
    		let pivot = array[pivotIndex];
    		let less = [];
    		let greater = []; // не объявляйте переменные через запятую
    
    		for (let i = 0; i < array.length; i++) { // индексы элементов в массиве идут с нуля
    			if (i === pivotIndex) continue; // опорный элмент нужно пропускать
    			if (array[i] <= pivot) {
    				less.push(array[i]);
    			} else {
    				greater.push(array[i]);
    			}
    		}
    		let result = [];
    		return result.concat(quickSort(less), pivot, quickSort(greater));
    	}
    }
    console.log(quickSort([5,1,7,4,3])); // алерт?
    Ответ написан
    2 комментария
  • Как построить дерево из объектов в массиве JavaScrypt?

    AngReload
    @AngReload
    Кратко о себе
    function getTree(flatTree) {
    	// node["1"] is node.index
    	// node["key"] is node.parent.index
    
    	flatTree.forEach(node => {
    		const nodeIndex = node["1"];
    		const nodeParentIndex = node["key"];
    		
    		node.parent = flatTree
    			.find(someNode => someNode["1"] === nodeParentIndex);
    
    		node.childrens = flatTree
    			.filter(someNode => someNode["key"] === nodeIndex);
    
    		node.siblings = flatTree
    			.filter(someNode => someNode["key"] === nodeParentIndex && someNode !== node);
    	});
    
    	const rootNode = flatTree.find(obj => obj["1"] === 1);
    	return rootNode;
    }
    
    const flatTree = [
    	{"1": 1, "3": 128, "4": 1, "key": 0},
    	{"1": 2, "3":   0, "4": 0, "key": 1},
    	{"1": 3, "3":   0, "4": 0, "key": 1},
    	{"1": 4, "3":   0, "4": 0, "key": 2},
    	{"1": 5, "3":   0, "4": 0, "key": 2},
    	{"1": 6, "3":   0, "4": 0, "key": 3},
    	{"1": 6, "3":   0, "4": 0, "key": 3},
    	{"1": 7, "3":   0, "4": 0, "key": 1}
    ];
    
    console.log(getTree(flatTree));
    Ответ написан
    Комментировать
  • Как сделать функцию на js, что бы нельзя было занимать занятые клетки при игре в крестики нолики?

    AngReload
    @AngReload
    Кратко о себе
    Нужно изменить обработчик, добавить проверку что клетка пустая:
    document.getElementById('game').onclick = function(event){
        console.log(event);
        if (event.target.className == 'block' && event.target.innerHTML === ''){
          if (hod%2==0) {
            event.target.innerHTML = 'x';
          }
          else {
            event.target.innerHTML = '0';
          }
          hod++;
          checkWinner();
        }
      }

    Но, как справедливо пишут, код не очень красивый. Прочитай как-нибудь про DRY (и другие принципы), иначе самому же тяжело будет свой код читать и редактировать.
    Ответ написан
    1 комментарий
  • Как изменить метод класса в неизменяемом js коде?

    AngReload
    @AngReload
    Кратко о себе
    То есть, ты можешь вставить любой код между head и body? Тогда в чём вопрос?
    Если чужой скрипт грузится в head, тогда прямо так и вставляй свой код, если в body то по событию
    document.addEventListener('DOMContentLoaded', () => {
      form.prototype.submitForm = function { console.log('test') }
      form.prototype.submitForm()
    });
    Ответ написан
  • Как сделать так, что-бы условие выполнялось после того, как оно будет НЕ выполнено один раз?

    AngReload
    @AngReload
    Кратко о себе
    Как-то так?
    // global variable
    let isBeforeWasNotOffset = false;
    
    function myAwesomeListener() {
      if (top_offset >= general_logo_offset.top) isBeforeWasNotOffset = true;
      if (isBeforeWasNotOffset &&
          top_offset <= general_logo_offset.top - 55 && top_offset >= 0
      ) {
        // bla bla bla
      }
    }
    Ответ написан
    Комментировать
  • Почему функция следующего вида не работает в обработчике событий?

    AngReload
    @AngReload
    Кратко о себе
    Функция f создаёт и возвращает анонимную функцию. Но и всё. Что бы новосозданная функция запустилась, нужно добавить скобок.
    parentElem.onclick = function(event) {
      if(условие) f(event.target)();
    }

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

    AngReload
    @AngReload
    Кратко о себе
    У вас нет точек с запятой, а сам язык между закрывающей круглой скобкой и открывающей квадратной её не ставит. Ваш код аналогичен такому:

    console.log()[puzzles[first],puzzles[second]] = [puzzles[second],puzzles[first]]


    Надо так:
    replacePuzzles({commit, getters},{first,second}){
            let puzzles = getters.getPuzzles 
            console.log(puzzles[first],puzzles[second])
            ;[puzzles[first],puzzles[second]] = [puzzles[second],puzzles[first]]
    Ответ написан
    Комментировать