Задать вопрос
Ответы пользователя по тегу JavaScript
  • Как воспроизвести видео YouTube при клике по стороннему элементу в 2021?

    @maximrabotaet
    Писал недавно подобное с ресайзом при изменении разрешения, в проекте используется jquery, но в основном для селекторов и слушания событий, можно легко поменять на ванильный.

    YouTube.js:
    export default class YouTube {
    
      states = Object.freeze({
        INIT: 'INIT',
        PLAY: 'PLAY',
        PAUSE: 'PAUSE',
      });
    
      constructor({container, videoId}) {
    
        this.container = container;
        this.videoId = videoId;
        this.isPlayerReady = false;
        this.initState = this.states.INIT;
        this.resizeTimeout = null;
        this.resizeTimeoutDelay = 500;
    
        YouTube.addScript();
    
        YouTube.onYouTubeIframeAPIReady(() => {
    
          this.player = this.getPlayer();
        });
    
        $(window).on('resize', () => {
    
          clearTimeout(this.resizeTimeout);
    
          this.resizeTimeout = setTimeout(() => {
    
            this.setDimensions();
    
          }, this.resizeTimeoutDelay);
        });
      }
    
      setDimensions() {
    
        $.getJSON(`https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=${this.videoId}&format=json`,
          ({width, height}) => {
    
            const elm = $(this.player.getIframe());
            const elmWidth = elm.width();
            const elmHeight = height * elmWidth / width;
    
            elm.height(Math.floor(elmHeight));
          });
      }
    
      isPauseState() {
    
        return this.states.PAUSE === this.initState;
      }
    
      isPlayState() {
    
        return this.states.PLAY === this.initState;
      }
    
      onPlayerReady() {
    
        this.isPlayerReady = true;
    
        if (this.isPauseState())
          this.pause();
    
        else if (this.isPlayState())
          this.play();
    
        this.setDimensions();
      }
    
      play() {
    
        if (this.isPlayerReady)
          this.player.playVideo();
    
        this.initState = this.states.PLAY;
      };
    
      pause() {
    
        if (this.isPlayerReady)
          this.player.pauseVideo();
    
        this.initState = this.states.PAUSE;
      };
    
      getPlayer() {
    
        return new YT.Player(this.container, {
          videoId: this.videoId,
          width: 945,
          events: {
            'onReady': this.onPlayerReady.bind(this),
          }
        });
      }
    
      static onYouTubeIframeAPIReady(fn) {
    
        if (!window.hasOwnProperty('onYouTubeIframeAPIReadyEvents') && !Array.isArray(window.onYouTubeIframeAPIReadyEvents))
          window.onYouTubeIframeAPIReadyEvents = [];
    
        if (!window.hasOwnProperty('onYouTubeIframeAPIReady') || !window.onYouTubeIframeAPIReady) {
    
          window.onYouTubeIframeAPIReady = function () {
    
            for (let i = 0; i < window.onYouTubeIframeAPIReadyEvents.length; i++)
              window.onYouTubeIframeAPIReadyEvents[i]();
          };
        }
    
        window.onYouTubeIframeAPIReadyEvents.push(fn);
      }
    
      static addScript() {
    
        if (!YouTube.isScriptAdded()) {
    
          const tag = document.createElement('script');
    
          tag.src = 'https://www.youtube.com/iframe_api';
          const firstScriptTag = document.getElementsByTagName('script')[0];
          firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    
          window.youTubeScriptAdded = true;
        }
      }
    
      static isScriptAdded() {
    
        return window.hasOwnProperty('youTubeScriptAdded') && window.youTubeScriptAdded;
      }
    }


    место где надо вешать эвенты на кнопку:
    import YouTube from '../../../utils/YouTube';
    
    $(window).on('load', () => {
    
      const video = $('.video-js');
      const playButton = $('.video_button-js');
      const youTube = new YouTube({
        container: video.get(0),
        videoId: 'ТУТ ВИДЕО ID', // обычно get параметр в ссылке на видео "v=ВИДЕО_ID'"
      });
    
      
      playButton .on('click', () => {
    
        youTube.play();
        // youTube.pause();
      });
    });


    место где должно быть видео:
    <div class="video-js"></div>
    <div class="video_button-js">Play</div>
    Ответ написан
  • Как в onclick передать родителя?

    @maximrabotaet
    Как в onclick передать родителя?

    https://developer.mozilla.org/ru/docs/Web/API/Elem...

    Есть ли какой-нибудь более элегантный способ, чем мой?

    class FormSubmitHandler{
    
        constructor(form){
    
            this.form = form;
    
            this.isSending = false;
    
            this.form.addEventListener('submit', this.onSubmit.bind(this));
        }
        onSubmit(e){
    
            e.preventDefault();
    
            // не отправляем форму пока ответ не пришел
            if(this.isSending)
                return;
    
            const data = new FormData(this.form);
    
            if(!this.validate(data))
                return;
    
            this.isSending = true;
    
            this.send(this.form.getAttribute("php"), data);
        }
        send(url, data){
    
            fetch(url, {
                method: "POST",
                body: data,
            })
                .then(response => response.json())
                .then(this.onCommit.bind(this))
                .catch(this.onBadRequest.bind(this));
        }
        onCommit(responseData){
    
            console.log(responseData, this.form);
    
            this.isSending = false;
        }
        onBadRequest(error){
    
            console.log(error, this.form);
    
            this.isSending = false;
        }
        validate(data){
    
            console.log(data.getAll(), this.form);
    
            // проверка полей формы
        }
    }
    
    ///////////////////////////////////////////////
    
    document.querySelectorAll('form').forEach((formElm) => {
    
        new FormSubmitHandler(formElm);
    });
    Ответ написан
    Комментировать
  • Как сделать такой календарь?

    @maximrabotaet
    Можете поискать календарь где есть api по смене месяца или года, скрыть через css стандартное отображение смены месяца/года и сделать свое, привязав его к api календаря, например тут есть методы next() и prev(), которые в зависимости от вида меняют месяц или год, и есть свойство view которое меняет вид календаря отображая месяц или год.

    Можно попробовать что-то типа этого:
    //...
    
    // клик на кнопку следующего месяца, если текущее представление дни месяца:
    datepicker.next();
    
    // клик на кнопку следующего года, если текущее представление дни месяца:
    datepicker.view = 'months';
    datepicker.next();
    datepicker.view = 'days';
    
    //...
    Ответ написан
    Комментировать
  • Поиск по select?

    @maximrabotaet
    https://select2.org/searching триггерит все события на скрытый селект и скорее всего добавляет свои (я точно не помню), этого вполне достаточно для любой задачи, хоть для использования в форме, хоть для построения логики при взаимодействии. Похоже на то что вы либо ищите не стандартный веб-комопнент, либо плагин который никто никогда не делал.

    Вы можете продублировать селект с теми же значениями и выводить его где вам нужно, можно даже инициализировать не заполняя тег селекта, повесить нужные эвенты на выбор значения и выбирать в продублированном НЕ скрытом селекте выбранное значение, но зачем это нужно?
    Ответ написан
    Комментировать