2014-02-25 22 views
0

我有這個問題,將YouTube視頻嵌入到PhoneJS單頁移動應用程序中。在PhoneJS中,JS腳本是在不同的文件中定義的。所以我定義的HTML DIV是這樣的:在JS文件將YouTube視頻綁定到單元JS文件中的div元素

<div id="player"></div> 

現在,我這樣做:

function getVideo() {   
    var tag = document.createElement('script'); 
    tag.src = "https://www.youtube.com/iframe_api"; 
    var playerDiv = document.getElementById('player'); 
    var firstScriptTag = document.getElementsByTagName('script')[0]; 
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 

    var player; 
    function onYouTubeIframeAPIReady() { 
     player = new YT.Player(playerDiv, { 
      height: '250', 
      width: '444', 
      videoId: sIFYPQjYhv8    
     }); 
    }   
} 

當我運行和查看調試器,電話就被打出到Youtube和響應收到,但它不顯示在視圖上。

確定自我使用KnockoutJS結合,我修改在div在這樣的HTML視圖:

<iframe id="player" type="text/html" width="444" height="250" frameborder="0" data-bind="attr: { src: src }"></iframe> 

然後在src視頻ID從而通過:

src: ko.observable('http://www.youtube.com/embed/' + sIFYPQjYhv8 + '?autoplay=1') 

在這種情況下然而,在調試器中,這個調用甚至沒有被Youtube所調用。沒有事情發生。其實我更喜歡使用API​​調用,而不是第二種方法。

如何使第一種方法的工作有什麼建議?我的意思是使用API​​調用?

編輯 只是想提一提的是,當我在下面添加視圖中的代碼,該視頻流沒有問題。

<h1>Video</h1> 
     <div id="player"></div> 
     <script> 
      var tag = document.createElement('script'); 
      tag.src = "https://www.youtube.com/iframe_api"; 
      var playerDiv = document.getElementById('player'); 
      var firstScriptTag = document.getElementsByTagName('script')[0]; 
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 

      var player; 
      function onYouTubeIframeAPIReady() { 
       player = new YT.Player(playerDiv, { 
        height: '250', 
        width: '444', 
        videoId: 'sIFYPQjYhv8' 
       }); 
      } 
     </script> 

回答

1

我認爲這樣做最簡單的方法是使用自定義綁定處理程序與設置一個標誌從onYouTubeIFrameAPIReady回調

Sample jsFiddle

ko.bindingHandlers['player'] = { 
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
     // Check if global script and function is declared. 
     if (!document.getElementById('playerScript')) { 
      // Create script 
      var tag = document.createElement('script'); 
      tag.src = "https://www.youtube.com/iframe_api"; 
      var playerDiv = document.getElementById('player'); 
      var firstScriptTag = document.getElementsByTagName('script')[0]; 
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 

      // Create global function that their API calls back 
      window.playerReady = ko.observable(false); 
      window.onYouTubeIframeAPIReady = function() { 
       window.playerReady(true); 
      }; 
     } 
    }, 
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 

     var value = valueAccessor(), 
      id = value.id(), 
      height = ko.unwrap(value.height) || '250', 
      width = ko.unwrap(value.width) || '444' 
     ; 

     if (!value.id()) { 
      return; 
     } 

     if (!window.playerReady()) { 
      // YT hasn't invoked global callback. Subscribe to update 
      var subscription; 
      subscription = window.playerReady.subscribe(function(newValue) { 
       if (newValue) { 
        subscription.dispose(); 
        // Just get this binding to fire again 
        value.id.notifySubscribers(value.id()); 
       } 
      }); 
     } else { 

      var player = new YT.Player(element, { 
       height: height, 
       width: width, 
       videoId: id 
      }); 
     } 
    }, 
} 

現在更改播放器div來

<div data-bind="player: { id: id, height: height, width: width }"></div> 

最後結合

var vm = { 
    id: 'sIFYPQjYhv8', 
    height: '250', 
    width: '444' 
}; 
ko.applyBindings(vm) 

編輯

要刪除窗口上的依賴,把你的腳本標籤,增加了新的腳本元素(如圖所示)tweek,修改自己的回調和使用的setTimeout代替「playerReady」 可觀察

HTML腳本

var tag = document.createElement('script'); 
tag.src = "https://www.youtube.com/iframe_api"; 
tag.setAttribute('id', 'playerScript'); 
tag.setAttribute('data-ready', 'false'); 
... 

function onYouTubeIframeAPIReady = function() { 
    document.getElementById('playerScript').setAttribute('data-ready', 'true'); 
}; 

玩家綁定

update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 

     var value = valueAccessor(), 
      id = value.id(), 
      height = ko.unwrap(value.height) || '250', 
      width = ko.unwrap(value.width) || '444', 
      playerScript = document.getElementById('playerScript') 
     ; 

     if (!value.id()) { 
      return; 
     } 

     if (!playerScript || playerScript.getAttribute('data-ready') !== 'true')) { 
      // YT hasn't invoked global callback. 
      setTimeout(function() { 
       value.id.notifySubscribers(value.id()); 
      }, 50); 
     } else { 

      var player = new YT.Player(element, { 
       height: height, 
       width: width, 
       videoId: id 
      }); 
     } 
    } 
+0

這個完美的作品上的HTML文件,其最優雅的解決方案。特別是綁定高度和寬度的能力。但是,在Devexpress PhoneJS應用程序中,它仍然不起作用。它一定是PhoneJS框架的問題?我已經在他們的網站上詢問,但尚未收到回覆。出於某種虛幻的原因,看起來JS文件無法訪問HTML文件中的DIV。我等待他們的迴應,並會盡快接受您的回答。謝謝。小提琴真棒,我相信我(和其他人)會使用它!太感謝了!!! – Machiavelli

+0

爲了支持上述觀點,或許問題是PhoneJS JS文件無法訪問html視圖中的播放器div,我添加了這個應該自動將視頻自動適應其包含div的JQuery插件,從https://github.com/davatron5000/FitVids.js我然後調用它初始化在PhoneJS JS文件,但注意到發生。所以它一定是PhoneJS! – Machiavelli

+0

嗨@羅伯特斯萊尼,我真的應該受到你的嚴厲懲罰,讓你修改你以前的答案。這就是爲什麼:PhoneJS處理KO綁定的方式略有不同(我的意思是語法)。沒有調用ko.applyBindings()。這就是我一直想念的。修改綁定後,第一個答案完美無缺!你不是救世主嗎?所以,現在數十億的感謝!還有更多的感謝。一直清醒28小時解決這個問題!不是有些人超級棒? – Machiavelli