代码之家  ›  专栏  ›  技术社区  ›  Red

textracklist onchange事件在ie和edge中不工作

  •  10
  • Red  · 技术社区  · 6 年前

    这个 TextTrackList.onchange 事件不在中工作 工业工程 。在 火狐 它工作得很好。

    我还有别的选择吗?我搜索了所有可用的 事件 但找不到。

    或者我如何创建一个变通方案?所以它可以在所有浏览器中使用?

    https://www.javascripture.com/TextTrackList

    var video = document.getElementById('video');
    
    video.textTracks.addEventListener('change', function () {
      console.log("TextTracks change event fired!");
    });
    video {
      max-width: 400px;
      max-height: 400px;
    }
    <video controls id="video">
      <source src="https://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_30mb.mp4" type="video/mp4" />
      <track label="Caption #1" kind="subtitles" srclang="nl" src="path/to/caption1.vtt">
      <track label="Caption #2" kind="subtitles" srclang="en" src="path/to/caption2.vtt">
      <track label="Caption #3" kind="subtitles" srclang="de" src="path/to/caption3.vtt">
    </video>
    2 回复  |  直到 6 年前
        1
  •  4
  •   Kaiido NickSlash    6 年前

    ('onchange' in window.TextTrackList)

    mode "showing"

    // in an outer scope
    // textTracks is our TextTrackList object
    var active = getActive();
    
    // start polling
    poll();
    
    function poll() {
      // schedule next check in a frame
      requestAnimationFrame(poll);
      var current = getActive();
    
      if (current !== active) {
        active = current; // update the active one
        // dispatchEvent is not supported on TextTrackList in IE...
        onchange({
          target: textTracks
        });
      }
    }
    
    function getActive() {
      for (var i = 0; i < textTracks.length; i++) {
        if (textTracks[i].mode === 'showing') {
          return textTracks[i];
        }
      }
    }
    

    addEventListener removeEventListener onchange

    (function() {
      /* Tries to implement an 'change' Event on TextTrackList Objects when not implemented */
    
      if (window.TextTrackList && !('onchange' in window.TextTrackList.prototype)) {
        var textTracksLists = [], // we will store all the TextTrackLists instances
          polling = false; // and run only one polling loop
    
        var proto = TextTrackList.prototype,
    
          original_addEvent = proto.addEventListener,
          original_removeEvent = proto.removeEventListener;
    
        var onchange = {
          get: getonchange,
          set: setonchange
        };
    
        Object.defineProperty(proto, 'onchange', onchange);
        Object.defineProperty(proto, 'addEventListener', fnGetter(addListener));
        Object.defineProperty(proto, 'removeEventListener', fnGetter(removeListener));
    
        function fnGetter(fn) {
          return {
            get: function() {
              return fn;
            }
          };
        }
    
    
        /* 	When we add a new EventListener, we attach a new object on our instance
        	This object set as '._fakeevent' will hold informations about
        		the current EventListeners
        		the current onchange handler
        		the parent <video> element if any
        		the current activeTrack
        */
        function initFakeEvent(instance) {
          // first try to grab the video element from where we were generated
          // this is useful to not run useless tests when the video is detached
          var vid_elems = document.querySelectorAll('video'),
            vid_elem = null;
          for (var i = 0; i < vid_elems.length; i++) {
            if (vid_elems[i].textTracks === instance) {
              vid_elem = vid_elems[i];
              break;
            }
          }
    
          textTracksLists.push(instance);
          instance._fakeevent = {
            parentElement: vid_elem,
            listeners: {
              change: []
            }
          }
          if (!polling) { // if we are the first instance being initialised
            polling = true;
            requestAnimationFrame(poll); // start the checks
          }
    
          return instance._fakeevent;
        }
    
        function getonchange() {
          var fakeevent = this._fakeevent;
          if (!fakeevent || typeof fakeevent !== 'object') {
            return null;
          }
          return fakeevent.onchange || null;
        }
    
        function setonchange(fn) {
          var fakeevent = this._fakeevent;
          if (!fakeevent) {
            fakeevent = initFakeEvent(this);
          }
          if (fn === null) fakeevent.onchange = null;
          if (typeof fn !== 'function') return fn;
          return fakeevent.onchange = fn;
        }
    
        function addListener(type, fn, options) {
          if (type !== 'change') { // we only handle change for now
            return original_addEvent.bind(this)(type, fn, options);
          }
          if (!fn || typeof fn !== 'object' && typeof fn !== 'function') {
            throw new TypeError('Argument 2 of EventTarget.addEventListener is not an object.');
          }
          var fakeevent = this._fakeevent;
          if (!fakeevent) {
            fakeevent = initFakeEvent(this);
          }
          if (typeof fn === 'object') {
            if (typeof fn.handleEvent === 'function') {
              fn = fn.handleEvent;
            } else return;
          }
          // we don't handle options yet...
          if (fakeevent.listeners[type].indexOf(fn) < 0) {
            fakeevent.listeners[type].push(fn);
          }
        }
    
        function removeListener(type, fn, options) {
          if (type !== 'change') { // we only handle change for now
            return original_removeEvent.call(this, arguments);
          }
          var fakeevent = this._fakeevent;
          if (!fakeevent || !fn || typeof fn !== 'object' && typeof fn !== 'function') {
            return
          }
          if (typeof fn === 'object') {
            if (typeof fn.handleEvent === 'function') {
              fn = fn.handleEvent;
            } else return;
          }
          // we don't handle options yet...
          var index = fakeevent.listeners[type].indexOf(fn);
          if (index > -1) {
            fakeevent.listeners[type].splice(index, 1);
          }
        }
    
    
        function poll() {
          requestAnimationFrame(poll);
          textTracksLists.forEach(check);
        }
    
        function check(instance) {
          var fakeevent = instance._fakeevent;
          // if the parent vid not in screen, we probably have not changed
          if (fakeevent.parentElement && !fakeevent.parentElement.parentElement) {
            return;
          }
          // get the current active track
          var current = getActiveTrack(instance);
          // has changed
          if (current !== fakeevent.active) {
            if (instance.onchange) {
              try {
                instance.onchange({
                  type: 'change',
                  target: instance
                });
              } catch (e) {}
            }
            fakeevent.listeners.change.forEach(call, this);
          }
          fakeevent.active = current;
        }
    
        function getActiveTrack(textTracks) {
          for (var i = 0; i < textTracks.length; i++) {
            if (textTracks[i].mode === 'showing') {
              return textTracks[i];
            }
          }
          return null;
        }
    
        function call(fn) {
          fn({
            type: 'change',
            target: this
          });
        }
    
    
      }
    })();
    
    var video = document.getElementById('video');
    
    video.textTracks.onchange = function ontrackchange(e) {
      console.log('changed');
    };
    video {
      max-width: 400px;
      max-height: 400px;
    }
    <video controls id="video">
      <source src="https://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_30mb.mp4" type="video/mp4" />
       <track label="Caption #1" kind="subtitles" srclang="nl" src="path/to/caption1.vtt">
       <track label="Caption #2" kind="subtitles" srclang="en" src="path/to/caption2.vtt">
       <track label="Caption #3" kind="subtitles" srclang="de" src="path/to/caption3.vtt">
    </video>
        2
  •  2
  •   Shahar    6 年前

    https://codepen.io/shahar-polak/project/live/AnVpEw/

    const video = document.getElementById('video');
    const tracks = Array.from(document.querySelectorAll('track'));
    video.textTracks.addEventListener('change', function() {
      console.log('TextTracks change event fired!');
    });
    // For IE and Edge
    tracks.forEach((track) => {
      track.addEventListener("load", function() {
        console.log('change track');
      }, false);
    })
    video {
      max-width: 400px;
      max-height: 400px;
    }
    <video controls id="video" >
        <source src="https://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_30mb.mp4" type="video/mp4"/>
        <track label="Caption #1" kind="subtitles" srclang="nl" src="./en.vtt">
        <track label="Caption #2" kind="subtitles" srclang="en" src="./en.vtt">
        <track label="Caption #3" kind="subtitles" srclang="de" src="https://iandevlin.com/html5/dynamic-track/captions/sintel-en.vtt">
    </video>