Ответы пользователя по тегу JavaScript
  • Как сделать плавный захват меню?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Вам тут не нужен js. Если конечно не обязательна поддержка ИЕ.
    .panel-nav {
      position: sticky;
      top: 0;
    }
    Ответ написан
    1 комментарий
  • Кто знает как можно дату перевернуть наоборот без использования тегов и тому подобное?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    new Date('2020-02-18').toLocaleDateString() // 18.02.2020


    Ну а если не хотите зависеть от локали пользователя, то
    const [year, month, day] = '2020-02-18'.split('-')
    alert(`${day}.${month}.${year}`)
    Ответ написан
    4 комментария
  • Как исправить перемещение курсора при редактировании и валидации input?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    В момент начала изменения, сохранять позицию каретки input.selectionStart
    После замены значения в инпуте - устанавливать позицию каретки
    input.setSelectionRange(startPos,endPos) // Обе позиции должны быть одинаковыми, например (1,1)
    Ответ написан
    1 комментарий
  • Как написать скрипт, который будет находить среднее арифметическое?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Что-то Вы очень много лишних действий делаете.
    var inputNumbers = prompt("Введіть числа(довільна кількість)", ""); // получили строку чисел. Предположительно разделённых пробелом.
    var numbers = inputNumbers.split(" "); // Получили массив чисел в виде строк.
    var summ = numbers.reduce(function(summ, item){return summ += parseInt(item)}, 0) // используем метод массивов reduce внутри которого преобразуем каждое строковое число в number и складываем.
    var result = summ / numbers.length // делим сумму на количество
    alert(result)
    Ответ написан
    5 комментариев
  • Как в textarea вывести динамически количество набираемых символов?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Использовать событие input на textarea и в обработчике брать event.target.value.length - количество вбитых символов. И пропихивать в этот счётчик.

    const ta = document.querySelector(...) // textarea
    const counter = document.querySelector(...) // счётчик
    
    ta.addEventListener('input', onInput)
    
    funcion onInput(evt) {
    const length = evt.target.value.length
    counter.textContent = length
    }


    Ответ написан
    4 комментария
  • Как сделать всплывающую панель как на андроиде?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    1. Делаем блок контейнер с минимальной высотой во весь вьюпорт.
    2. Делаем в нём 2 "слота". Первый - верхний, где рисочка, за которую пользователь будет тянуть. Второй - сам контент.
    3. Позиционируем его фиксированно так, как больше нравится - вообще не видно, видно только рисочку, видно часть контента.
    4. На рисочку добавляем обработчик нажатия и тача. В момент, пока опущенна кнопка мыши или палец не оторван от экрана отслеживаем на документе позицию курсора\пальца.
    5. Ну и собственно по факту смещения указателя меняем позицию нашего контейнера.
    6. Чтобы у этого "окошка" были состояния стоит добавлять проверку. Например, если текущее состояние "закрыто\открыто" и передвинули вверх\вниз более чем на N пикселей, то менять состояние на противоположное.
    7. Не забываем снимать обработчики с документа когда кнопка мыши отжимается или палец убирается от экрана.
    8. В целом - профит.


    Таким образом, состояния отвечают за то, как отобразить элемент. Спрятанным или раскрытым. При смене состояния меняется отображение.
    Таким образом, не обязательно будет всё время открывать окошко пальцем. Сменили переменную состояния - оно открылось\закрылось.
    Состояния можно хранить в css классах элемента.
    Ответ написан
    Комментировать
  • Рабочий клик по кнопке, если экран меньше 992px?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    if (window.innerWidth < 992) {
      // код скрытия\отображения
    }


    Хотите более развернутого ответа - задавайте более развёрнутый вопрос. В идеале - с демкой в любой песочнице.
    Ответ написан
    Комментировать
  • Как в кнопке располагать иконку рядом с текстом?

    MrDecoy
    @MrDecoy Куратор тега CSS
    Верставший фронтендер
    Если отвечать на поставленный вопрос - то после текста должен идти слот под эту иконку.
    Пустой div, у которого и будет этот background указан.
    Таким образом, div всегда будет идти строго за текстом. Вы сможете задать ему отступ от текста, размеры, и прочие стили.

    div а не span просто потому что span всё таки обёртка для текста. А иконка это не текст.

    <div style="width: 100%; background-color: #fff;">
      <button style="width: 100%;height: 50px;">
        Зарегистрироваться
        <div style="background-size: 20px 20px;background-repeat: no-repeat; background-position: right 0 center;background-image: url(https://img2.freepng.ru/20180325/qaw/kisspng-email-computer-icons-clip-art-coin-5ab83d2671f511.2388637315220237184668.jpg);"></div>
      </button>
    </div>
    Ответ написан
  • Как зациклить фрагмент видео?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    1. (Можно пропустить)Выделяете мышкой в инструментах разработчика в дереве элемент . Теперь он доступен в консоле через алиас $0
    2. Сохраняете ссылку на видео элемент в переменную. (через $0 или поиск элемента)
    3. Пишите функцию setInterval, в которой указываете v.currentTime = %секунда видео, которая вам нужна%
    4. В интервале указываете период, который вас интересует.
    5. Профит.


    const v = $0 // или вместо $0 document.querySelector... - получить элемент video
    let startTime = 15 // 15ая секунда видео - секунда, с которой будет начинаться цикл
    let duration = 1000 // 1000 миллисекунд = 1 секунда - продолжительность цикла
    
    const repeat = setInterval(function () {
      v.currentTime = startTime 
    }, duration)
    Ответ написан
  • Как получить данные и вставить?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Капец у Вас тут каша конечно... var, let,const, разные подходы к объявлению переменных, то используйте dataset, то через getAttribute, то querySelector, то getBy* и куча не нужных циклов.

    Переписал:
    // helper functions
    function linearInterpolate (from_range, to_range, val) {
        var minX = from_range[0],
            minY = to_range[0],
            rangeX = from_range[1] - from_range[0],
            rangeY = to_range[1] - to_range[0];
    
        return (val - minX) * rangeY / rangeX + minY;
    }
    
    function clamp (x, min, max) {
        if (x < min) {
    		return min;
    	}
    	if (x > max) {
    		return max;
    	}
    	return x; 
    }
    
    // constructor
    function Gauge (elem, options) {
        var gaugeVal = elem.dataset.value
    	var options = options || {},
    		canvas = document.createElement('canvas'),
    		value = options.value || 0;
    	
    	this.options = options;
    	
    	this.ctx = canvas.getContext("2d");
    	this.width = options.width || 100;
    	this.height = options.height || this.width;
    	
    	// readjust lineWidth based on radius
    	if (options.radius) {
    		this.lineWidth = (this.width / 2 - options.radius);
    	} else {
    		this.lineWidth = options.lineWidth || 4;
    	}
    	this.radius = (this.width - this.lineWidth) / 2;
    	
    	//set colors for chart
    	if (gaugeVal < 50) {
    		this.color = options.color || 'rgba(224, 99, 100, 1)';
    	} else {
    		this.color = options.color || 'rgba(43, 197, 132, 1)'
    	};
    	
    	this.background = options.background || 'rgba(241, 244, 249, 1)';
    
    	this.range = [0, 100];
    	
    	this.interpolate = linearInterpolate.bind(this, this.range, [Math.PI, 2*Math.PI]);
    	
    	canvas.width = this.width;
    	canvas.height = this.height / 2;
    	
    	this.set( value );
    		
    	elem.appendChild( canvas );
    }
    
    // get/set methods
    Gauge.prototype.get = function () {
    	return this.value || 0;
    };
    
    Gauge.prototype.set = function (value) {
    	var ctx = this.ctx,
    		range = this.range,
    		value = clamp(value, range[0], range[1]),
    		drawArc = function () {
    			ctx.beginPath();
    			ctx.arc.apply(ctx, arguments);
    			ctx.stroke();
    			// bind all arguments except the end value
    		}.bind(this, this.width / 2, this.height / 2, 
    				this.radius,
    				Math.PI);
    
    	this.value = value;
    	ctx.clearRect(0,0,this.width,this.height / 2);
    	
    	ctx.lineWidth = this.lineWidth;
    	
    	// background
    	ctx.strokeStyle = this.background;
    	drawArc( 2 * Math.PI );
    	
    	// foreground
    	ctx.strokeStyle = this.color;
    	drawArc( this.interpolate( value ) );
    	
    	// optional display value
    	if (this.options.displayvalue && 
    	   this.options.displayvalue !== 'false') {
    		ctx.font = "bold " + this.lineWidth + "px Russia, Arial, sans-serif";
    		if (gaugeVal < 50){
    		ctx.fillStyle = "rgba(43, 197, 132, 1)";
    			} else {
    				ctx.fillStyle = 'rgba(224, 99, 100, 1)';
    			}
    		ctx.textAlign = "center";
    		ctx.textBaseline = "top";
    		ctx.fillText(value, this.width / 2, 0);
    	}
    };
    
    
    
    // create instances/handlers
    var gauges = document.querySelectorAll('.gauge');
    var gaugeHtml = document.querySelectorAll('.gauge__value');
    
    
    gaugeHtml.forEach(function(gaugeValue){
        const value = Number(gaugeValue.parentElement.dataset.value)
        gaugeValue.style.color = value > 50 ? 'rgba(43, 197, 132, 1)' : 'rgba(224, 99, 100, 1)';
    })
    // Инициализация
    gauges.forEach(function(gauge){
        let gaugeVal = gauge.dataset.value;
        const gaugeValueElement = gauge.querySelector('.gauge__value')
        gaugeValueElement.textContent = gaugeVal;
        new Gauge(gauge, gauge.dataset)
    })
    Ответ написан
    2 комментария
  • Что означает этот синтаксис?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Возвращает у вас судя по всему всегда this, а то что в скобках это так называемый side effect. Стороннее действие.
    Тык
    Ответ написан
    Комментировать
  • Как вызвать модальное окно при скроллинге до нужного блока?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    В зависимости от необходимой браузернйо поддержки у вас 2 варианта.

    1 - более универсальный, но больше работы руками:
    При загрузке документа находить в дереве ваш элемент с id=popup. Сохранить в переменную.
    Добавлять обработчик скрола на документ и сверять текущий скролл и позицию элемента сверху от начала документа(тык и тык). Совпадает - вызываем модалку.

    2 - более современный, но браузер сделает всё за вас:
    Воспользоваться Intersection Observer
    Суть ,в целом, та же. Указываете за каким элементом следить, указываете что следить нужно за появлением этого элемента во вьюпорте и указываете функцию обработчик этого события, в которой открываете модалку.

    Вот пример кода на Intersection observer
    var options = {
        root: null, // Не указываем = следим за областью вьюпорта.
        rootMargin: '0px', // отступы вокруг root
        threshold: 1.0
    }
    var callback = function(entries, observer) { 
        // Открываем модалку
    };
    var observer = new IntersectionObserver(callback, options);
    
    /* Параметр threshold со значением 1.0 означает что функция будет вызвана при 100% пересечении объекта (за которым мы следим) с объектом root */
    
    
    var target = document.querySelector('#popup'); // элемент, за которым будем следить.
    observer.observe(target);


    Профит
    Ответ написан
    Комментировать
  • Как сделать и как называется когда скролишь и меняется контент в блоке?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    https://www.cssscript.com/tag/scroll-animation/

    Смотрите демки, выбирайте какой душе угодно.
    Такое можно найти если не быть забаненым в гугле за 10 секунд.
    Удивительно, но ищется по запросу : scroll content animation
    Ответ написан
    Комментировать
  • Как временно подсветить якорную ссылку?

    MrDecoy
    @MrDecoy Куратор тега CSS
    Верставший фронтендер
    Не совсем понятно что именно нужно подсветить.
    • Если саму ссылку, на которую нужно нажать, то тут либо через css анимации(transition/keyframes), однако анимация будет зависеть от наличия конкретного состояния(наведение, focus и тд), либо же через JS. Суть та же, однако можно не зависеть от состояния, включать анимацию и выключать по таймеру. А так же есть дополнительные варианты, такие как обработчик нажатия на ссылку.
    • Если цель ссылки, на которую она указывает, то тут, в целом, варианты те же. Однако, через css, например, это можно сделать воспользовавшись псевдоклассом :target htmlbook.ru/css/target, либо через js брать назначение ссылки, искать этот элемент по id и так же навешивать анимацию.

    Пример на :target, то есть если нужно подсветить цель ссылки:

    #one {
      color: blue;
      background-color: transparent;
    }
    
    #one:target {
    // и другие параметры анимации - направление, длительность, задержка и тд. 
    // в соответствии с css keyframes анимациями https://webref.ru/css/keyframes
      animation: blur 10s ease-in-out ... ;
    }
    
    @keyframes blur {
       // другие ключевые кадры
       50% {
         color: red;
         background-color: yellow;
       }
    }
    Ответ написан
    Комментировать
  • Как сделать так, если до окончании таймера пользователь перекрасил/закрасил все path в SVG картинке, остановить таймер и вывести ALERT?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    1) Сохранять id таймера в соответствующем замыкании. Ну или хотя бы в глобале.
    то есть window.gameTimer = setTimeout()... Можете возвращать id таймера из функциие timer().

    2) Добавить для всех необходимых элементов, которые пользователь должен закрасить структуру данных.
    Например:
    {
    element: state
    }
    где element - ключ, который однозначно определяет элемент(уникальное значение дата атрибута, например(
    а state - значение. Например, 0 - не закрашено, 1 - закрашено.

    3) По факту клика на элемент(рекомендую через деллигирование) проверять что все элементы имеют состояние 1. И есть это истинно, то обнулять таймер через clearTimeout и перенаправлять на страницу результата или что там ещё Вам нужно.

    4) Profit.
    Ответ написан
    3 комментария
  • Как реализовать такое на React или JS?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Ну, испокон веков, когда юзер что-то менял в фильтрах, пагинации и тд то это сохранялось в гет параметрах урла.
    Использование session\local storage тоже приемлемые варианты. Выбор как именно сделать зависит, скорее от ТЗ.
    Но через параметры выглядит, как по мне, более правильным вариантом.
    Ответ написан
  • Как дописать jquery скрипт?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Итак, я представил что у Вас следующая html структура:
    <div class="card__wrapper">
      <div class="card__wrapper_api-show">Бургер</div>
      <div class="card__wrapper_api">Скрытый див</div>
    </div>
    <div class="card__wrapper">
      <div class="card__wrapper_api-show">Бургер</div>
      <div class="card__wrapper_api">Скрытый див</div>
    </div>
    <div class="card__wrapper">
      <div class="card__wrapper_api-show">Бургер</div>
      <div class="card__wrapper_api">Скрытый див</div>
    </div>


    Если Вам не принципиально отслеживать клики только на тех card__wrapper_api-show, которые находятся в card__wrapper, то:
    можно сделать так:
    $(".card__wrapper_api-show").click(function() {
        $(this) // jquery элемент, на котором произошёл клик
          .next(".card__wrapper_api") // непосредственно следующий в разметке блок (если идут не друг за другом то можно применить nextAll
          .stop() // Ваш код.
          .animate(
            {
              right: "0"
            },
            500,
            function() {
               // Animation complete.
            }
          );
      });

    Если принципиально, то модифицируйте селектор из примера выше на $('.card__wrapper .card__wrapper_api-show').

    Более лучшей практикой считается использовать в подобном случае делегирование событий.
    Обработчик должен быть на общем контейнере верхнего уровня, и смотреть на каком элементе произошёл клик.
    Таким образом, заворачиваем всё в один контейнер, разметка примет вид:
    <div class="cards">
      <div class="card__wrapper">
        <div class="card__wrapper_api-show">Бургер</div>
        <div class="card__wrapper_api">Скрытый див</div>
      </div>
      <div class="card__wrapper">
        <div class="card__wrapper_api-show">Бургер</div>
        <div class="card__wrapper_api">Скрытый див</div>
      </div>
      <div class="card__wrapper">
        <div class="card__wrapper_api-show">Бургер</div>
        <div class="card__wrapper_api">Скрытый див</div>
      </div>
    </div>


    А скрипт:
    $(".cards").click(function(evt) {
        // Сохраняем элемент, на котором произошёл клик в jQuery обёртку
        const $element = $(evt.target);
         // проверяем, что элемент содержит класс api-show
        // и если содержит, то делаем что нам надо со следующим в разметке элементом .card__wrapper_api
        if($element.hasClass('.card__wrapper_api-show')){ 
           $element
           .next(".card__wrapper_api")
           .stop()
           .animate(
             {
              right: "0"
            },
            500,
            function() {
              // Animation complete.
             }
           );
        }
      });


    Таким образом, у нас всего один обработчик кликов - лучше для производительности.

    P.s. Так как песочницу Вы не предоставили, код на работоспособность не тестировался.
    Ответ написан
    1 комментарий
  • Как решить проблему с двумя slick-слайдерами на странице?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Вам следует использовать по одному css и js файлу для любого количестве slick-слайдеров на странице.
    Если оба слайдера используют одни и те же данные, то тут всего 2 варианта:
    1) Вы по ошибке указали один и тот же объект в качестве настроек для обоих слайдеров,
    2) Вы инициализировали действительно слайдеры с разными настройками, на одном и том же селекторе.

    P.s.Если оба варианта Вам не подходят - приложите js код (можно вместе с html), а то кроме как догадок\предположений ничего не получите.
    Ответ написан
    Комментировать
  • Как работает instanceof?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Instance - Это экземпляр.
    Используя A instanceof B, Вы как бы спрашиваете: является ли А экземпляром класса B?
    Классов у нас нет, но есть прототипное наследование и функции-консструкторы взамен.

    Экземпляр возвращается конструктором через new неявно, или же если в конструкторе Вы строго укажите какой объект, в качестве экземпляра, будет возвращён.

    В примере же указано что функция-конструктор должна возвращать себя же.
    Таким образом, фукнция - не экземпляр самой себя.
    Отсюда и new F() instanceof F - false;

    Но!
    Функции в JS являются экземплярами класса Function.
    А в примере, как уже писалось выше, функция конструтор возвращает саму себя, следовательно, возвращает объект-экземпляр клаcса Function.
    Отсюда и new F() instanceof Function - true;
    Ответ написан
    Комментировать
  • Копирование текста и отправка в консоли?

    MrDecoy
    @MrDecoy Куратор тега JavaScript
    Верставший фронтендер
    Предположу, что Вам нужно скриптом скопировать "AZE KING" и отправить это запросом.
    В таком случае,
    • на основе предоставленной информации;
    • а так же при условии, что в нике игрока не может быть запятых;
    • у каждого игрока есть уровень, который отделяется от ника запятой;
    предложу слудющее:
    var playerInfo = document.querySelector('.win').textContent.trim(); // AZE KING, 47 уровень
    var playerName = playerInfo.slice(0, playerInfo.indexOf(',')) // AZE KING;
    var url = "site.com/add.php?name=" + playerName;
    
    var req = new XMLHttpRequest();
    req.open("GET", url, false);
    req.send(null);


    Можно переделать на:
    // И сделать это массивом. Удобно, если дальше нужно так же что-то делать с уровнем или будут ещё другие параметры игрока через запятую.
    var playerInfo = document.querySelector('.win').textContent.trim().split(','); // ['AZE KING', '47 уровень']
    var playerName = playerInfo[0] // AZE KING;
    var url = "site.com/add.php?name=" + playerName;
    
    var req = new XMLHttpRequest();
    req.open("GET", url, false);
    req.send(null);
    Ответ написан
    Комментировать