メディア再生窓生成

    @@ -83,7 +83,7 @@ if (url.indexOf("http") === 0) { - url = url.indexOf("#") + 1 ? url.split("#")[0] : url; // URLに # を含む場合は除去 + url = url.split("#")[0]; // URLに # を含む場合は除去 if (checked.every(function(li){ return url !== li })) { // 全てとアンマッチなら true checked.push(url);
  • /*
     * @title メディア再生窓生成
     * @description マルチメディア要素へのリンクにhoverすると<audio>や<video>なウィンドウをポップアップしてくれるようにする
     * @include http://*
     * @license NYSL
     */
    
    (function(){
      var checked = [];        // 同じURLに複数回リクエストを送るのを防ぐためのリストを格納
      var timeout = 30 * 1000; // タイムアウトになるまでの時間(単位:ms)
    
      if (!HTMLAnchorElement.prototype.addPopup) { // addPopupメソッドをA要素に追加
    
        Object.defineProperty(HTMLAnchorElement.prototype, "addPopup", {
          value: function(url){
            var self = this;
    
            var xhr = new XMLHttpRequest(); // HEADリクエストを送る
            xhr.open("HEAD", url, true);
            xhr.onreadystatechange = function(){
              if (xhr.readyState === 4) {
                console.log(xhr.status + " : " + url);
    
                if (xhr.status !== 200) return;
    
                var header = xhr.getResponseHeader("Content-Type");
                var type   = header.split("/")[0];
                var allowList = ["audio", "video"];
    
                if (allowList.some(function(v){ return v === type })) { // いずれかにヒットすれば true
                  console.log(header + " - OK");
                  addPopupItem(self, type);
                }
              }
            };
            xhr.send(null);
    
            window.setTimeout(function(){ // 一定時間でタイムアウト
              xhr.abort();
            }, timeout);
          }
        });
      }
      else {
        return false;
      }
    
      // 他のスタイルから影響を受けないよう Date.now() を追加
      var thisClass = "media-popup-" + Date.now();
    
      var elems = document.getElementsByTagName("a");
      elems = Array.prototype.slice.call(elems); // A要素を全て抽出
    
      var popupItem = (function(){ // ポップアップ用の殻を作成
        var div = document.createElement("div");
        div.className = thisClass;
        return div;
      })();
    
      var popupStyle = function(){ // スタイル定義
        var style = document.createElement("style");
        document.getElementsByTagName("head")[0].appendChild(style);
        var s = style.sheet;
    
        // カーソルを置いたらポップアップするように
        s.insertRule("." + thisClass + "{"
        + "display: none !important;"
        + "text-indent: 0 !important;"
        + "z-index: 100 !important;"
        + "}", 0);
        s.insertRule("a:hover + ." + thisClass + ", ." + thisClass + ":hover {"
        + "display: block !important;"
        + "}", s.cssRules.length);
    
        s.insertRule("." + thisClass + "{"
        + "position: absolute !important;"
        + "}", s.cssRules.length);
      };
      popupStyle();
    
      for (var i in elems) {
        var url = elems[i].href;
        
        if (url.indexOf("http") === 0) {
          
          url = url.split("#")[0]; // URLに # を含む場合は除去
          
          if (checked.every(function(li){ return url !== li })) { // 全てとアンマッチなら true
            checked.push(url);
            elems[i].addPopup(url);
          }
        }
      }
    
      function addPopupItem(target, mediaType) { // ポップアップを生成
        var popup = popupItem.cloneNode(), s = popup.style;
        s.left = target.offsetLeft + "px";
        s.top  = target.offsetTop + target.offsetHeight + "px";
    
        var element; // 殻の中身を定義
    
        element = document.createElement(mediaType);
        element.setAttribute("src", target.href);
        element.setAttribute("preload", "metadata");
        element.setAttribute("controls", "controls");
    
        popup.appendChild(element);
        target.parentElement.insertBefore(popup, target.nextSibling); // 目標の直後に配置
    
        // 某ADVの公式サイトでなぜかレイアウトが崩れるので対症療法的な何か
        var objRect = popup.getBoundingClientRect();
        if (objRect.left === 0 && objRect.top === 0) {
          s.left = s.top = "auto";
        }
      }
    
    })();
    
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2013/04/28 18:17:21 - 2013-04-28
  2. 2013/04/27 14:07:33 - 2013-04-27
  3. 2013/04/27 03:49:45 - 2013-04-27
  4. 2013/04/27 02:47:19 - 2013-04-27
  5. 2013/04/27 02:44:48 - 2013-04-27
  6. 2013/04/27 02:43:38 - 2013-04-27
  7. 2013/04/26 17:28:58 - 2013-04-26
  8. 2013/04/23 02:15:08 - 2013-04-23
  9. 2013/04/22 10:27:13 - 2013-04-22
  10. 2013/04/22 10:01:50 - 2013-04-22
  11. 2013/04/22 09:50:14 - 2013-04-22