Скрипты: async, defer
В современных сайтах скрипты обычно «тяжелее», чем HTML: они весят больше, дольше обрабатываются.
Когда браузер загружает HTML и доходит до тега <script>...</script>, он не может продолжать строить DOM. Он должен сначала выполнить скрипт. То же самое происходит и с внешними скриптами <script src="..."></script>: браузер должен подождать, пока загрузится скрипт, выполнить его, и только затем обработать остальную страницу.
Это ведёт к двум важным проблемам:
Скрипты не видят DOM-элементы ниже себя, поэтому к ним нельзя добавить обработчики и т.д.
Если вверху страницы объёмный скрипт, он «блокирует» страницу. Пользователи не видят содержимое страницы, пока он не загрузится и не запустится:
https://learn.javascript.ru/script-async-defer
					
										
																										
            Собственное контекстное меню с использованием JavaScript
https://habr.com/ru/articles/258167/
https://github.com/callmenick/Custom-Context-Menu
Демо: http://codepen.io/SitePoint/pen/MYLoWY
					
										
																										
            https://habr.com/ru/articles/258167/
https://github.com/callmenick/Custom-Context-Menu
Демо: http://codepen.io/SitePoint/pen/MYLoWY
Малоизвестные возможности JavaScript
- Оператор void
- Скобки при вызове конструкторов необязательны
- Скобки при работе с IIFE можно не использовать
- Конструкция with
- Конструктор Function
и многое другое....
https://habr.com/ru/companies/ruvds/articles/431878/
					
										
																										
            - Оператор void
- Скобки при вызове конструкторов необязательны
- Скобки при работе с IIFE можно не использовать
- Конструкция with
- Конструктор Function
и многое другое....
https://habr.com/ru/companies/ruvds/articles/431878/
Повесить обработчик ВСЕХ  событий на элемент и посмотреть какие когда срабатывают:
					
										
																										
            Код: Выделить всё
var myObj = document.querySelector('video');
for (var key in myObj) {
  if (key.search('on') === 0) {
    console.log("EVENT=>", key.slice(2));
    myObj.addEventListener(key.slice(2), (e) => { console.log("Event worked=>", e.type, key.slice(2)); })
  }
}Замена аудио видео элемента (трека)
https://stackoverflow.com/questions/636 ... deotracks0
					
										
																										
            Код: Выделить всё
function replaceTracks(elementId, newStream, localStream, peerConnection) {
    detachMediaStream(elementId);
    newStream.getTracks().forEach(function (track) {
      localStream.addTrack(track);
    });
    attachMediaStream(elementId, newStream);
    // optionally, if you have active peer connections:
    _replaceTracksForPeer(peerConnection);
    function _replaceTracksForPeer(peer) {
      console.log(peer)
      peer.getSenders().map(function (sender) {
        sender.replaceTrack(newStream.getTracks().find(function (track) {
          return track.kind === sender.track.kind;
        }));
      });
    }
    function attachMediaStream(id, stream) {
      var elem: any = document.getElementById(id);
      if (elem) {
        if (typeof elem.srcObject === 'object') {
          elem.srcObject = stream;
        } else {
          elem.src = window.URL.createObjectURL(stream);
        }
        elem.onloadedmetadata = function (e) {
          elem.play();
        };
      } else {
        throw new Error('Unable to attach media stream');
      }
    }
    function detachMediaStream(id) {
      var elem;
      elem = document.getElementById(id);
      if (elem) {
        elem.pause();
        if (typeof elem.srcObject === 'object') {
          elem.srcObject = null;
        } else {
          elem.src = '';
        }
      }
    }
  }https://stackoverflow.com/questions/636 ... deotracks0

