Liên kết Fiddle: Mã nguồn - Xem trước -
Cập nhật phiên bản nhỏ : Hàm nhỏ này sẽ chỉ thực thi mã theo một hướng duy nhất. Nếu bạn muốn hỗ trợ đầy đủ (ví dụ người nghe sự kiện / thu khí), có một cái nhìn tại Nghe cho tổ chức sự kiện Youtube trong jQuery
Do phân tích mã sâu, tôi đã tạo một hàm: function callPlayer
yêu cầu gọi hàm trên bất kỳ video YouTube đóng khung nào. Xem tài liệu tham khảo Api trên YouTube để có danh sách đầy đủ các cuộc gọi chức năng có thể. Đọc các bình luận tại mã nguồn để được giải thích.
Vào ngày 17 tháng 5 năm 2012, kích thước mã đã được nhân đôi để chăm sóc trạng thái sẵn sàng của người chơi. Nếu bạn cần một chức năng nhỏ gọn không liên quan đến trạng thái sẵn sàng của người chơi, hãy xem http://jsfiddle.net/8R5y6/ .
/**
* @author Rob W <gwnRob@gmail.com>
* @website https://stackoverflow.com/a/7513356/938089
* @version 20190409
* @description Executes function on a framed YouTube video (see website link)
* For a full list of possible functions, see:
* https://developers.google.com/youtube/js_api_reference
* @param String frame_id The id of (the div containing) the frame
* @param String func Desired function to call, eg. "playVideo"
* (Function) Function to call when the player is ready.
* @param Array args (optional) List of arguments to pass to function func*/
function callPlayer(frame_id, func, args) {
if (window.jQuery && frame_id instanceof jQuery) frame_id = frame_id.get(0).id;
var iframe = document.getElementById(frame_id);
if (iframe && iframe.tagName.toUpperCase() != 'IFRAME') {
iframe = iframe.getElementsByTagName('iframe')[0];
}
// When the player is not ready yet, add the event to a queue
// Each frame_id is associated with an own queue.
// Each queue has three possible states:
// undefined = uninitialised / array = queue / .ready=true = ready
if (!callPlayer.queue) callPlayer.queue = {};
var queue = callPlayer.queue[frame_id],
domReady = document.readyState == 'complete';
if (domReady && !iframe) {
// DOM is ready and iframe does not exist. Log a message
window.console && console.log('callPlayer: Frame not found; id=' + frame_id);
if (queue) clearInterval(queue.poller);
} else if (func === 'listening') {
// Sending the "listener" message to the frame, to request status updates
if (iframe && iframe.contentWindow) {
func = '{"event":"listening","id":' + JSON.stringify(''+frame_id) + '}';
iframe.contentWindow.postMessage(func, '*');
}
} else if ((!queue || !queue.ready) && (
!domReady ||
iframe && !iframe.contentWindow ||
typeof func === 'function')) {
if (!queue) queue = callPlayer.queue[frame_id] = [];
queue.push([func, args]);
if (!('poller' in queue)) {
// keep polling until the document and frame is ready
queue.poller = setInterval(function() {
callPlayer(frame_id, 'listening');
}, 250);
// Add a global "message" event listener, to catch status updates:
messageEvent(1, function runOnceReady(e) {
if (!iframe) {
iframe = document.getElementById(frame_id);
if (!iframe) return;
if (iframe.tagName.toUpperCase() != 'IFRAME') {
iframe = iframe.getElementsByTagName('iframe')[0];
if (!iframe) return;
}
}
if (e.source === iframe.contentWindow) {
// Assume that the player is ready if we receive a
// message from the iframe
clearInterval(queue.poller);
queue.ready = true;
messageEvent(0, runOnceReady);
// .. and release the queue:
while (tmp = queue.shift()) {
callPlayer(frame_id, tmp[0], tmp[1]);
}
}
}, false);
}
} else if (iframe && iframe.contentWindow) {
// When a function is supplied, just call it (like "onYouTubePlayerReady")
if (func.call) return func();
// Frame exists, send message
iframe.contentWindow.postMessage(JSON.stringify({
"event": "command",
"func": func,
"args": args || [],
"id": frame_id
}), "*");
}
/* IE8 does not support addEventListener... */
function messageEvent(add, listener) {
var w3 = add ? window.addEventListener : window.removeEventListener;
w3 ?
w3('message', listener, !1)
:
(add ? window.attachEvent : window.detachEvent)('onmessage', listener);
}
}
Sử dụng:
callPlayer("whateverID", function() {
// This function runs once the player is ready ("onYouTubePlayerReady")
callPlayer("whateverID", "playVideo");
});
// When the player is not ready yet, the function will be queued.
// When the iframe cannot be found, a message is logged in the console.
callPlayer("whateverID", "playVideo");
Câu hỏi có thể (& câu trả lời):
Q : Nó không hoạt động!
A : "Không hoạt động" không phải là một mô tả rõ ràng. Bạn có nhận được bất kỳ thông báo lỗi? Vui lòng hiển thị mã có liên quan.
Q : playVideo
không phát video.
Trả lời : Phát lại yêu cầu tương tác của người dùng và sự hiện diện của allow="autoplay"
iframe. Xem https://developers.google.com/web/updates/2017/09/autoplay-policy-changes và https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide
H : Tôi đã nhúng video YouTube bằng cách sử dụng <iframe src="http://www.youtube.com/embed/As2rZGPGKDY" />
nhưng chức năng không thực hiện bất kỳ chức năng nào!
Trả lời : Bạn phải thêm ?enablejsapi=1
vào cuối URL của mình : /embed/vid_id?enablejsapi=1
.
H : Tôi nhận được thông báo lỗi "Chuỗi không hợp lệ hoặc không hợp lệ đã được chỉ định". Tại sao?
Trả lời : API không hoạt động chính xác tại máy chủ cục bộ ( file://
). Lưu trữ trang (kiểm tra) của bạn trực tuyến hoặc sử dụng JSFiddle . Ví dụ: Xem các liên kết ở đầu câu trả lời này.
Q : Làm thế nào bạn biết điều này?
Trả lời : Tôi đã dành một chút thời gian để diễn giải thủ công nguồn của API. Tôi kết luận rằng tôi phải sử dụng postMessage
phương pháp. Để biết đối số nào sẽ vượt qua, tôi đã tạo tiện ích mở rộng Chrome chặn tin nhắn. Mã nguồn cho phần mở rộng có thể được tải xuống ở đây .
Q : Những trình duyệt nào được hỗ trợ?
Trả lời : Mọi trình duyệt hỗ trợ JSON và postMessage
.
- IE 8+
- Firefox 3.6+ (thực tế là 3.5, nhưng
document.readyState
đã được triển khai trong 3.6)
- Opera 10.50+
- Safari 4+
- Chrome 3+
Câu trả lời / triển khai có liên quan: Làm mờ video trong khung bằng cách sử dụng
hỗ trợ API đầy đủ của jQuery : Lắng nghe sự kiện Youtube trong
API chính thức của jQuery : https://developers.google.com/youtube/iframe_api_Vference
Lịch sử sửa đổi
- 17 tháng 5 năm 2012
Thực hiện onYouTubePlayerReady
: callPlayer('frame_id', function() { ... })
.
Các chức năng được tự động xếp hàng khi người chơi chưa sẵn sàng.
- 24 tháng 7 năm 2012
Cập nhật và thử nghiệm thành công trong các trình duyệt được hỗ trợ (nhìn về phía trước).
- 10 tháng 10 năm 2013 Khi một chức năng được thông qua như là một đối số,
callPlayer
buộc phải kiểm tra sự sẵn sàng. Điều này là cần thiết, bởi vì khi callPlayer
được gọi ngay sau khi chèn iframe trong khi tài liệu đã sẵn sàng, không thể biết chắc rằng iframe đã hoàn toàn sẵn sàng. Trong Internet Explorer và Firefox, kịch bản này dẫn đến việc gọi quá sớm postMessage
, đã bị bỏ qua.
- Ngày 12 tháng 12 năm 2013, nên thêm
&origin=*
vào URL.
- Ngày 2 tháng 3 năm 2014, rút lại đề xuất để xóa
&origin=*
URL.
- 9 tháng 4 năm 2019, sửa lỗi dẫn đến đệ quy vô hạn khi YouTube tải trước khi trang sẵn sàng. Thêm ghi chú về tự động phát.