iFrame src Detekcja zdarzeń zmiany?
Zakładając, że nie mam kontroli nad treścią w ramce iframe, czy jest jakiś sposób, że mogę wykryć zmianę src w nim poprzez Stronę nadrzędną? Może jakiś ładunek?
Moją ostatnią deską ratunku jest wykonanie 1-sekundowego testu interwałowego, jeśli iframe src jest taki sam jak wcześniej, ale zrobienie tego hakerskiego rozwiązania byłoby do bani.
Używam biblioteki jQuery, jeśli to pomoże.
7 answers
Możesz użyć zdarzenia onLoad
, jak w poniższym przykładzie:
<iframe src="http://www.google.com/" onLoad="alert('Test');"></iframe>
Alert pojawi się po każdej zmianie lokalizacji w ramce iframe. Działa we wszystkich nowoczesnych przeglądarkach, ale może nie działać w niektórych bardzo starszych przeglądarkach, takich jak IE5 i wczesna Opera. (Source )
Jeśli ramka iframe wyświetla stronę w tej samej domenie rodzica , będzie można uzyskać dostęp do lokalizacji za pomocą contentWindow.location
, jak w poniższym przykładzie:
<iframe src="/test.html" onLoad="alert(this.contentWindow.location);"></iframe>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-18 18:54:21
Odpowiedź na podstawie JQuery
$('#iframeid').load(function(){
alert('frame has (re)loaded');
});
Jak wspomniał subharb, od JQuery 3.0 należy to zmienić na:
$('#iframe').on('load', function() {
alert('frame has (re)loaded ');
});
Https://jquery.com/upgrade-guide/3.0/#breaking-change-load-unload-and-error-removed
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 09:55:25
Jeśli nie masz kontroli nad stroną i chcesz obserwować jakąś zmianę, to nowoczesną metodą jest użycie MutationObserver
Przykład jego użycia, obserwowanie atrybutu src
do zmiany iframe
new MutationObserver(function(mutations) {
mutations.some(function(mutation) {
if (mutation.type === 'attributes' && mutation.attributeName === 'src') {
console.log(mutation);
console.log('Old src: ', mutation.oldValue);
console.log('New src: ', mutation.target.src);
return true;
}
return false;
});
}).observe(document.body, {
attributes: true,
attributeFilter: ['src'],
attributeOldValue: true,
characterData: false,
characterDataOldValue: false,
childList: false,
subtree: true
});
setTimeout(function() {
document.getElementsByTagName('iframe')[0].src = 'http://jsfiddle.net/';
}, 3000);
<iframe src="http://www.google.com"></iframe>
Wyjście po 3 sekundach
MutationRecord {oldValue: "http://www.google.com", attributeNamespace: null, attributeName: "src", nextSibling: null, previousSibling: null…}
Old src: http://www.google.com
New src: http://jsfiddle.net/
On jsFiddle
Posted answer here as original question was closed as a duplicate of this one.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:39
Ramka iframe zawsze przechowuje Stronę nadrzędną, powinieneś użyć tego, aby wykryć, na której stronie jesteś w ramce iframe:
Kod Html:
<iframe id="iframe" frameborder="0" scrolling="no" onload="resizeIframe(this)" width="100%" src="www.google.com"></iframe>
Js:
function resizeIframe(obj) {
alert(obj.contentWindow.location.pathname);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-05 09:21:05
Oto metoda, która jest używana wCommerce SagePay i wCommerce Paypoint modułach Drupal, który zasadniczo porównuje document.location.href
ze starą wartością, najpierw ładując własny iframe, a następnie zewnętrzny.
Więc zasadniczo chodzi o załadowanie pustej strony jako elementu zastępczego z własnym kodem JS i ukrytym formularzem. Następnie rodzic kod JS prześle Ukryty formularz, gdzie jego #action
wskazuje na zewnętrzną ramkę iframe. Gdy nastąpi przekierowanie / submit, kod JS, który nadal działa na tej stronie można śledzić zmiany wartości document.location.href
.
Oto przykład JS używany w iframe:
;(function($) {
Drupal.behaviors.commercePayPointIFrame = {
attach: function (context, settings) {
if (top.location != location) {
$('html').hide();
top.location.href = document.location.href;
}
}
}
})(jQuery);
I tu jest js używany na stronie nadrzędnej:
;(function($) {
/**
* Automatically submit the hidden form that points to the iframe.
*/
Drupal.behaviors.commercePayPoint = {
attach: function (context, settings) {
$('div.payment-redirect-form form', context).submit();
$('div.payment-redirect-form #edit-submit', context).hide();
$('div.payment-redirect-form .checkout-help', context).hide();
}
}
})(jQuery);
Następnie w tymczasowej pustej stronie docelowej musisz dołączyć formularz, który przekieruje na stronę zewnętrzną.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-16 15:49:08
Inne odpowiedzi zaproponowały Zdarzenie load
, ale wywołało ono Po załadowaniu nowej strony w ramce iframe. Może być konieczne powiadomienie natychmiast po zmianie adresu URL , a nie po załadowaniu nowej strony.
Oto proste rozwiązanie JavaScript:
function iframeURLChange(iframe, callback) {
var unloadHandler = function () {
// Timeout needed because the URL changes immediately after
// the `unload` event is dispatched.
setTimeout(function () {
callback(iframe.contentWindow.location.href);
}, 0);
};
function attachUnload() {
// Remove the unloadHandler in case it was already attached.
// Otherwise, the change will be dispatched twice.
iframe.contentWindow.removeEventListener("unload", unloadHandler);
iframe.contentWindow.addEventListener("unload", unloadHandler);
}
iframe.addEventListener("load", attachUnload);
attachUnload();
}
iframeURLChange(document.getElementById("mainframe"), function (newURL) {
console.log("URL changed:", newURL);
});
<iframe id="mainframe" src=""></iframe>
To z powodzeniem wyśledzi zmiany atrybutów src
, jak również wszelkie zmiany adresów URL dokonane wewnątrz ramki iframe.
Uwaga: powyższy fragment będzie działał tylko wtedy, gdy ramka iframe ma to samo pochodzenie.
Zrobiłem gist z tego kodu, jak również. Możesz też sprawdzić moją drugą odpowiedź . To idzie trochę dogłębnie do tego, jak to działa.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-06 14:25:15
Od wersji 3.0 Jquery może pojawić się błąd
TypeError: url.indexOf nie jest funkcją
Które można łatwo naprawić wykonując
$('#iframe').on('load', function() {
alert('frame has (re)loaded ');
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-18 09:58:01