2016-07-06 118 views
0

我想在「內容腳本」谷歌瀏覽器擴展程序中使用「YouTube iframe API」。我應該如何在我的擴展中需要Youtube iframe API?在Google Chrome瀏覽器擴展程序中需要外部javascript

Youtube iFrame API的URL:https://www.youtube.com/iframe_api

您通常會在清單文件中的Google Chrome擴展程序中包含腳本,但由於URL不會以.js結尾,因此Chrome的擴展頁會引發錯誤。

此外,它看起來像這個URL上的腳本嘗試注入<script>標籤,由於它無法訪問該頁面的javascript,因此不會與content_script插件一起使用。

manifest.json的

{ 
    ... 
    "content_scripts": [ 
     { 
      "matches": ["<all_urls>"], 
      "js": ["main.js"], 
      "all_frames": true 
     } 
    ] 
} 

main.js

// Inject the script, but this won't work since content scripts can't access the page's javascript (which is where this script is injected). 
var tag = document.createElement('script'); 
tag.src = "https://www.youtube.com/player_api"; 

(document.head || document.documentElement).appendChild(tag); 


// Create our own player 
var player; 

var videoID = 'e7Px2yJA6S4'; 

// When the YouTube API is loaded, it calls this function. 
function onYouTubeIframeAPIReady() { 
    player = new YT.Player('movie_player', { 
    height: '390', 
    width: '640', 
    videoId: videoID, 
    events: { 
     'onReady': onPlayerReady, 
     'onStateChange': onPlayerStateChange 
    } 
    }); 
} 

我應該怎麼做不同?我如何正確包含這個腳本?

回答

1

Rob W的答案涵蓋了這種情況:Insert code into the page context using a content script,請參閱方法1 &方法2。

在一般情況下,由於內容腳本isolated word執行,如果包括的Yo​​uTube API爲<script>標籤(這是在網頁世界),而初始化內容腳本YouTube播放器(這是一個孤立的世界),它會因爲內容腳本和<script>標記不能訪問彼此定義的變量/函數。

一種解決方法是通過<script>標籤注入這些代碼,請參閱以下示例。

的manifest.json

{ 
    ... 
    "content_scripts": [ 
     { 
      "matches": ["<all_urls>"], 
      "js": ["inject.js"], 
      "all_frames": true 
     } 
    ], 
    "web_accessible_resources": ["https://www.youtube.com/player_api"] 
} 

inject.js

function insertScriptFile(callback) { 
    // Inject the script 
    var tag = document.createElement('script'); 
    tag.src = "https://www.youtube.com/player_api"; 
    tag.onload = function() { 
     callback(); 
    }; 
    (document.head || document.documentElement).appendChild(tag); 
} 

function insertEmmedCode() { 
    var actualCode = `// 3. This function creates an <iframe> (and YouTube player) 
    // after the API code downloads. 
    var player; 
    function onYouTubeIframeAPIReady() { 
    player = new YT.Player('player', { 
     height: '390', 
     width: '640', 
     videoId: 'M7lc1UVf-VE', 
     events: { 
     'onReady': onPlayerReady, 
     'onStateChange': onPlayerStateChange 
     } 
    }); 
    } 

    // 4. The API will call this function when the video player is ready. 
    function onPlayerReady(event) { 
    event.target.playVideo(); 
    } 

    // 5. The API calls this function when the player's state changes. 
    // The function indicates that when playing a video (state=1), 
    // the player should play for six seconds and then stop. 
    var done = false; 
    function onPlayerStateChange(event) { 
    if (event.data == YT.PlayerState.PLAYING && !done) { 
     setTimeout(stopVideo, 6000); 
     done = true; 
    } 
    } 
    function stopVideo() { 
    player.stopVideo(); 
    } 
`; 

    var script = document.createElement('script'); 
    script.textContent = actualCode; 
    (document.head || document.documentElement).appendChild(script); 
} 

var div = document.createElement("div"); 
div.id = "player"; 
document.body.appendChild(div); 

insertScriptFile(function() { 
    insertEmmedCode(); 
}); 
+0

這種解決方案的問題是main.js仍然沒有獲得來自inject.js注入的API。 –

+1

@DonnyP,已更新。基本上由於執行環境的原因,內容腳本和'

相關問題