Détecter quand le navigateur reçoit le téléchargement de fichier

j'ai une page qui permet à l'utilisateur de télécharger un générées dynamiquement fichier. Cela prend beaucoup de temps à générer, donc j'aimerais montrer un indicateur "attente". Le problème, c'est que je ne sais pas comment détecter quand le navigateur a reçu le fichier, donc je peux cacher l'indicateur.

je fais la demande dans une forme cachée, qui poste sur le serveur, et cible une iframe cachée pour ses résultats. C'est pour que je ne remplace pas toute la fenêtre du navigateur par le résultat. Je écoutez un événement" load " sur l'iframe, dans l'espoir qu'il se déclenche lorsque le téléchargement sera terminé.

je renvoie un en-tête" Content-Disposition: attachment "avec le fichier, ce qui fait que le navigateur affiche la boîte de dialogue" Save". Mais le navigateur ne déclenche pas d'événement" load " dans l'iframe.

l'une des approches que j'ai essayées est d'utiliser une réponse en plusieurs parties. Afin d'envoyer un fichier HTML vide, ainsi que le fichier téléchargeable. Par exemple:

Content-type: multipart/x-mixed-replace;boundary="abcde"

--abcde
Content-type: text/html

--abcde
Content-type: application/vnd.fdf
Content-Disposition: attachment; filename=foo.fdf

file-content
--abcde

cela fonctionne dans Firefox; il reçoit le fichier HTML vide, déclenche l'événement" load", puis affiche la boîte de dialogue" Save " pour le fichier téléchargeable. Mais il échoue sur IE et Safari; IE déclenche l'événement " load "mais ne télécharge pas le fichier, et Safari télécharge le fichier (avec le mauvais nom et le type de contenu), et ne tire pas l'événement" load".

une approche différente pourrait être de faire un appel pour lancer la création du fichier, puis de sonder le serveur jusqu'à ce qu'il soit prêt, téléchargez ensuite le fichier déjà créé. Mais je préfère éviter de créer des fichiers temporaires sur le serveur.

quelqu'un a une meilleure idée?

413
demandé sur JW. 2009-07-10 00:51:12
la source

16 ответов

Un solution utilise le JavaScript sur le client.

l'algorithme client:

  1. génère un token aléatoire unique.
  2. soumettre la demande de téléchargement et inclure le jeton dans un champ GET/POST.
  3. affiche l'indicateur "attente".
  4. démarrez une minuterie, et à chaque seconde ou plus, cherchez un cookie nommé "fileDownloadToken" (ou n'importe quoi d'autre vous de décider).
  5. si le cookie existe et que sa valeur correspond au token, masquez l'indicateur" waiting".

l'algorithme du serveur:

  1. recherchez le champ GET/POST dans la requête.
  2. s'il a une valeur non vide, déposez un cookie (par exemple" fileDownloadToken"), et réglez sa valeur sur la valeur du token.

source du Client code (JavaScript):

function getCookie( name ) {
  var parts = document.cookie.split(name + "=");
  if (parts.length == 2) return parts.pop().split(";").shift();
}

function expireCookie( cName ) {
    document.cookie = 
        encodeURIComponent(cName) + "=deleted; expires=" + new Date( 0 ).toUTCString();
}

function setCursor( docStyle, buttonStyle ) {
    document.getElementById( "doc" ).style.cursor = docStyle;
    document.getElementById( "button-id" ).style.cursor = buttonStyle;
}

function setFormToken() {
    var downloadToken = new Date().getTime();
    document.getElementById( "downloadToken" ).value = downloadToken;
    return downloadToken;
}

var downloadTimer;
var attempts = 30;

// Prevents double-submits by waiting for a cookie from the server.
function blockResubmit() {
    var downloadToken = setFormToken();
    setCursor( "wait", "wait" );

    downloadTimer = window.setInterval( function() {
        var token = getCookie( "downloadToken" );

        if( (token == downloadToken) || (attempts == 0) ) {
            unblockSubmit();
        }

        attempts--;
    }, 1000 );
}

function unblockSubmit() {
  setCursor( "auto", "pointer" );
  window.clearInterval( downloadTimer );
  expireCookie( "downloadToken" );
  attempts = 30;
}

exemple de code serveur (PHP):

$TOKEN = "downloadToken";

// Sets a cookie so that when the download begins the browser can
// unblock the submit button (thus helping to prevent multiple clicks).
// The false parameter allows the cookie to be exposed to JavaScript.
$this->setCookieToken( $TOKEN, $_GET[ $TOKEN ], false );

$result = $this->sendFile();

où:

public function setCookieToken(
    $cookieName, $cookieValue, $httpOnly = true, $secure = false ) {

    // See: http://stackoverflow.com/a/1459794/59087
    // See: http://shiflett.org/blog/2006/mar/server-name-versus-http-host
    // See: http://stackoverflow.com/a/3290474/59087
    setcookie(
        $cookieName,
        $cookieValue,
        2147483647,            // expires January 1, 2038
        "/",                   // your path
        $_SERVER["HTTP_HOST"], // your domain
        $secure,               // Use true over HTTPS
        $httpOnly              // Set true for $AUTH_COOKIE_NAME
    );
}
391
répondu bulltorious 2017-02-11 20:58:33
la source

une solution très simple (et boiteuse) d'une ligne est d'utiliser l'événement window.onblur() pour fermer la boîte de dialogue de chargement. Bien sûr, si cela prend trop de temps et que l'utilisateur décide de faire autre chose (comme lire des e-mails), la boîte de dialogue de chargement se ferme.

27
répondu birdman 2012-11-20 16:42:45
la source

vieux fil, je sais...

mais ceux qui sont ici par google pourrait être intéressé à ma solution. c'est très simple, mais fiable. et il permet d'Afficher des messages de progrès réels (et peut être facilement branché aux processus existants):

le script qui traite (mon problème était: récupérer des fichiers via http et les livrer en zip) écrit le statut à la session.

le statut est interrogé et affiché chaque seconde. c'est tout (ok, ce n'est pas. vous devez prendre soin de beaucoup de détails [par exemple les téléchargements simultanés], mais c'est un bon endroit pour commencer ;-)).

la page de téléchargement:

    <a href="download.php?id=1" class="download">DOWNLOAD 1</a>
    <a href="download.php?id=2" class="download">DOWNLOAD 2</a>
    ...
    <div id="wait">
    Please wait...
    <div id="statusmessage"></div>
    </div>
    <script>
//this is jquery
    $('a.download').each(function()
       {
        $(this).click(
             function(){
               $('#statusmessage').html('prepare loading...');
               $('#wait').show();
               setTimeout('getstatus()', 1000);
             }
          );
        });
    });
    function getstatus(){
      $.ajax({
          url: "/getstatus.php",
          type: "POST",
          dataType: 'json',
          success: function(data) {
            $('#statusmessage').html(data.message);
            if(data.status=="pending")
              setTimeout('getstatus()', 1000);
            else
              $('#wait').hide();
          }
      });
    }
    </script>

getstatus.php

<?php
session_start();
echo json_encode($_SESSION['downloadstatus']);
?>

de téléchargement.php

    <?php
    session_start();
    $processing=true;
    while($processing){
      $_SESSION['downloadstatus']=array("status"=>"pending","message"=>"Processing".$someinfo);
      session_write_close();
      $processing=do_what_has_2Bdone();
      session_start();
    }
      $_SESSION['downloadstatus']=array("status"=>"finished","message"=>"Done");
//and spit the generated file to the browser
    ?>
11
répondu bytepirate 2010-09-11 02:27:07
la source

j'utilise ce qui suit pour télécharger des blobs et révoquer l'objet-url après le téléchargement. il fonctionne en chrome et firefox!

function download(blob){
    var url = URL.createObjectURL(blob);
    console.log('create ' + url);

    window.addEventListener('focus', window_focus, false);
    function window_focus(){
        window.removeEventListener('focus', window_focus, false);                   
        URL.revokeObjectURL(url);
        console.log('revoke ' + url);
    }
    location.href = url;
}

après la fermeture de la fenêtre de téléchargement de fichier, la fenêtre récupère son focus et l'événement de focus est déclenché.

11
répondu Elmer 2013-03-26 17:46:08
la source

j'ai écrit une classe JavaScript simple qui met en œuvre une technique similaire à celle décrite dans bulltorious réponse . J'espère que cela peut être utile à quelqu'un ici. Le projet github est appelé réponse-moniteur.js

par défaut il utilise spin.js comme indicateur d'attente mais il fournit également un ensemble de callbacks pour la mise en œuvre d'un indicateur personnalisé.

jQuery is prise en charge, mais pas nécessaire.

caractéristiques Notables

  • intégration Simple
  • Pas de dépendances
  • JQuery plug-in (en option)
  • Spin.js Intégration (facultatif)
  • callbacks configurables pour la surveillance d'événements
  • traite plusieurs requêtes simultanées
  • Détection d'erreurs côté serveur
  • Timeout "de détection des 1519230920"
  • de la Croix-navigateur

exemple d'usage

HTML

<!-- the response monitor implementation -->
<script src="response-monitor.js"></script>

<!-- optional JQuery plug-in -->
<script src="response-monitor.jquery.js"></script> 

<a class="my_anchors" href="/report?criteria1=a&criteria2=b#30">Link 1 (Timeout: 30s)</a>
<a class="my_anchors" href="/report?criteria1=b&criteria2=d#10">Link 2 (Timeout: 10s)</a>

<form id="my_form" method="POST">
    <input type="text" name="criteria1">
    <input type="text" name="criteria2">
    <input type="submit" value="Download Report">
</form>

Client (JavaScript simple)

//registering multiple anchors at once
var my_anchors = document.getElementsByClassName('my_anchors');
ResponseMonitor.register(my_anchors); //clicking on the links initiates monitoring

//registering a single form
var my_form = document.getElementById('my_form');
ResponseMonitor.register(my_form); //the submit event will be intercepted and monitored

Client (JQuery)

$('.my_anchors').ResponseMonitor();
$('#my_form').ResponseMonitor({timeout: 20});

Client avec callbacks (JQuery)

//when options are defined, the default spin.js integration is bypassed
var options = {
    onRequest: function(token){
        $('#cookie').html(token);
        $('#outcome').html('');
        $('#duration').html(''); 
    },
    onMonitor: function(countdown){
        $('#duration').html(countdown); 
    },
    onResponse: function(status){
        $('#outcome').html(status==1?'success':'failure');
    },
    onTimeout: function(){
        $('#outcome').html('timeout');
    }
};

//monitor all anchors in the document
$('a').ResponseMonitor(options);

serveur (PHP)

$cookiePrefix = 'response-monitor'; //must match the one set on the client options
$tokenValue = $_GET[$cookiePrefix];
$cookieName = $cookiePrefix.'_'.$tokenValue; //ex: response-monitor_1419642741528

//this value is passed to the client through the ResponseMonitor.onResponse callback
$cookieValue = 1; //for ex, "1" can interpret as success and "0" as failure

setcookie(
    $cookieName,
    $cookieValue,
    time()+300,            // expire in 5 minutes
    "/",
    $_SERVER["HTTP_HOST"],
    true,
    false
);

header('Content-Type: text/plain');
header("Content-Disposition: attachment; filename=\"Response.txt\"");

sleep(5); //simulate whatever delays the response
print_r($_REQUEST); //dump the request in the text file

pour plus d'exemples, consultez le dossier exemples du dépôt.

7
répondu Jorge Paulo 2017-05-23 15:18:15
la source

basé sur L'exemple D'Elmer, j'ai préparé ma propre solution. Après les éléments cliquez avec défini télécharger classe il permet d'afficher le message personnalisé sur l'écran. J'ai utilisé focus trigger pour cacher le message.

JavaScript

$(function(){$('.download').click(function() { ShowDownloadMessage(); }); })

function ShowDownloadMessage()
{
     $('#message-text').text('your report is creating, please wait...');
     $('#message').show();
     window.addEventListener('focus', HideDownloadMessage, false);
}

function HideDownloadMessage(){
    window.removeEventListener('focus', HideDownloadMessage, false);                   
    $('#message').hide();
}

HTML

<div id="message" style="display: none">
    <div id="message-screen-mask" class="ui-widget-overlay ui-front"></div>
    <div id="message-text" class="ui-dialog ui-widget ui-widget-content ui-corner-all ui-front ui-draggable ui-resizable waitmessage">please wait...</div>
</div>

Maintenant vous devez implémenter n'importe quel élément pour télécharger:

<a class="download" href="file://www.ocelot.com.pl/prepare-report">Download report</a>

ou

<input class="download" type="submit" value="Download" name="actionType">

après chaque télécharger Cliquez pour voir le message votre rapport se crée, s'il vous plaît attendre...

4
répondu Jerzy Gebler 2014-10-15 17:25:25
la source

lorsque l'utilisateur déclenche la génération du fichier, vous pouvez simplement assigner un ID unique à ce" téléchargement", et envoyer l'utilisateur à une page qui se rafraîchit (ou vérifie avec AJAX) toutes les quelques secondes. Une fois le fichier terminé, enregistrez-le sous le même ID unique et...

  • si le fichier est prêt, faites le téléchargement.
  • si le fichier n'est pas prêt, afficher la progression.

alors vous pouvez sauter le tout iframe / waiting / browserwindow mess, encore avoir une solution très élégante.

3
répondu gahooa 2009-07-10 01:37:44
la source

je suis très en retard à la fête mais je vais mettre ça ici si quelqu'un d'autre voudrait connaître ma solution:

j'ai eu une vraie lutte avec ce problème précis mais j'ai trouvé une solution viable en utilisant iframes (je sais, je sais. C'est terrible mais cela fonctionne pour un simple problème que j'ai eu)

j'ai eu une page html qui a lancé un script php séparé qui a généré le fichier et l'a ensuite téléchargé. Sur la page html, j'ai utilisé jquery dans le html en-tête (vous devrez également inclure une bibliothèque jquery):

<script>
    $(function(){
        var iframe = $("<iframe>", {name: 'iframe', id: 'iframe',}).appendTo("body").hide();
        $('#click').on('click', function(){
            $('#iframe').attr('src', 'your_download_script.php');
        });
        $('iframe').load(function(){
            $('#iframe').attr('src', 'your_download_script.php?download=yes'); <!--on first iframe load, run script again but download file instead-->
            $('#iframe').unbind(); <!--unbinds the iframe. Helps prevent against infinite recursion if the script returns valid html (such as echoing out exceptions) -->
        });
    });
</script>

sur votre_download_script.php, ont le suivant:

function downloadFile($file_path) {
    if (file_exists($file_path)) {
        header('Content-Description: File Transfer');
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename=' . basename($file_path));
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file_path));
        ob_clean();
        flush();
        readfile($file_path);
        exit();
    }
}


$_SESSION['your_file'] = path_to_file; //this is just how I chose to store the filepath

if (isset($_REQUEST['download']) && $_REQUEST['download'] == 'yes') {
    downloadFile($_SESSION['your_file']);
} else {
    *execute logic to create the file*
}

pour décomposer cela, jquery lance d'abord votre script php dans une iframe. L'iframe est chargé une fois que le fichier est généré. Puis jquery lance à nouveau le script avec une variable de requête disant au script de télécharger le fichier.

La raison pour laquelle vous ne pouvez pas faire le téléchargement et le fichier generation all in one go est due à la fonction d'en-tête php (). Si vous utilisez header(), vous changez le script en autre chose qu'une page web et jquery ne reconnaîtra jamais le script de téléchargement comme étant "chargé". Je sais que ce n'est pas nécessairement détecter quand un navigateur reçoit un fichier, mais votre problème semblait similaire au mien.

3
répondu Walker Boh 2014-12-10 00:57:06
la source

j'ai eu exactement le même problème. Ma solution était d'utiliser des fichiers temporaires puisque je générais déjà un tas de fichiers temporaires. Le formulaire est présenté avec:

var microBox = {
    show : function(content) {
        $(document.body).append('<div id="microBox_overlay"></div><div id="microBox_window"><div id="microBox_frame"><div id="microBox">' +
        content + '</div></div></div>');
        return $('#microBox_overlay');
    },

    close : function() {
        $('#microBox_overlay').remove();
        $('#microBox_window').remove();
    }
};

$.fn.bgForm = function(content, callback) {
    // Create an iframe as target of form submit
    var id = 'bgForm' + (new Date().getTime());
    var $iframe = $('<iframe id="' + id + '" name="' + id + '" style="display: none;" src="about:blank"></iframe>')
        .appendTo(document.body);
    var $form = this;
    // Submittal to an iframe target prevents page refresh
    $form.attr('target', id);
    // The first load event is called when about:blank is loaded
    $iframe.one('load', function() {
        // Attach listener to load events that occur after successful form submittal
        $iframe.load(function() {
            microBox.close();
            if (typeof(callback) == 'function') {
                var iframe = $iframe[0];
                var doc = iframe.contentWindow.document;
                var data = doc.body.innerHTML;
                callback(data);
            }
        });
    });

    this.submit(function() {
        microBox.show(content);
    });

    return this;
};

$('#myForm').bgForm('Please wait...');

À la fin du script qui génère le fichier que j'ai:

header('Refresh: 0;url=fetch.php?token=' . $token);
echo '<html></html>';

cela provoquera le déclenchement de l'événement de charge sur l'iframe. Ensuite, le message d'attente est fermé et le téléchargement du fichier démarre. Testé sur IE7 et Firefox.

2
répondu grom 2009-07-23 11:59:31
la source

si vous ne voulez pas générer et stocker le fichier sur le serveur, êtes-vous prêt à stocker l'état, par exemple fichier-en-cours, fichier-complet? Votre page "en attente" pourrait sonder le serveur pour savoir quand la génération de fichier est terminée. Vous ne pouvez pas être sûr que le navigateur a démarré le téléchargement, mais vous avez une certaine confiance.

2
répondu bmb 2011-10-05 18:06:05
la source

si vous diffusez en continu un fichier que vous générez dynamiquement, et que vous avez également mis en place une bibliothèque de messagerie Serveur-client en temps réel, vous pouvez alerter votre client assez facilement.

la bibliothèque de messagerie Serveur-client que j'aime et recommande est Socket.io (via le noeud.js). Une fois que le script de votre serveur est terminé, la génération du fichier qui est en cours de lecture pour télécharger votre dernière ligne dans ce script peut émettre un message vers Socket.io qui envoie une notification au client. Sur le client, Socket.io écoute les messages entrants émis par le serveur et vous permet d'agir sur eux. L'avantage d'utiliser cette méthode par rapport à d'autres est que vous êtes en mesure de détecter un "vrai" événement de finition après la diffusion en continu est fait.

par exemple, vous pouvez afficher votre indicateur de charge après avoir cliqué sur un lien de téléchargement, diffuser votre fichier, envoyer un message à Socket.io du serveur dans la dernière ligne de votre script de streaming, écouter sur le client pour un notification, recevoir la notification et mettre à jour votre UI en masquant l'indicateur occupé.

je me rends compte que la plupart des gens qui lisent les réponses à cette question n'ont peut-être pas ce type de configuration, mais j'ai utilisé cette solution exacte avec beaucoup d'efficacité dans mes propres projets et cela fonctionne merveilleusement.

Socket.io est incroyablement facile à installer et à utiliser. Voir plus: http://socket.io/

2
répondu Art Geigel 2016-11-06 19:38:53
la source

la question Est d'avoir un indicateur "en attente" pendant qu'un fichier est généré, puis de revenir à la normale une fois que le fichier est téléchargé. La façon dont j'aime faire ceci est d'utiliser une iFrame cachée et d'accrocher l'événement onload du Cadre pour faire savoir à ma page quand le téléchargement commence. mais onload ne s'allume pas dans IE pour les téléchargements de fichiers (comme avec le token d'en-tête de pièce jointe). Sonder le serveur fonctionne, mais je n'aime pas la complexité supplémentaire. Alors voici ce que je fais:

  • visez l'iFrame cachée comme d'habitude.
  • génère le contenu. Cache avec un temps mort absolu en 2 minutes.
  • envoyer un redirection javascript le client appelant, appelant essentiellement l' générateur bipe une seconde fois. NOTE: cela provoquera le feu de L'événement onload dans IE parce qu'il agit comme une page normale.
  • supprimer le contenu du cache et l'envoyer au client.

Avertissement, ne fais pas ça sur un site très fréquenté, en raison de la mise en cache pourrait ajouter jusqu'à. Mais vraiment, si vos sites qui occupent le long processus de fonctionnement va vous priver de fils de toute façon.

voici à quoi ressemble le codebehind, qui est tout ce dont vous avez vraiment besoin.

public partial class Download : System.Web.UI.Page
{
    protected System.Web.UI.HtmlControls.HtmlControl Body;

    protected void Page_Load( object sender, EventArgs e )
    {
        byte[ ] data;
        string reportKey = Session.SessionID + "_Report";

        // Check is this page request to generate the content
        //    or return the content (data query string defined)
        if ( Request.QueryString[ "data" ] != null )
        {
            // Get the data and remove the cache
            data = Cache[ reportKey ] as byte[ ];
            Cache.Remove( reportKey );

            if ( data == null )                    
                // send the user some information
                Response.Write( "Javascript to tell user there was a problem." );                    
            else
            {
                Response.CacheControl = "no-cache";
                Response.AppendHeader( "Pragma", "no-cache" );
                Response.Buffer = true;

                Response.AppendHeader( "content-disposition", "attachment; filename=Report.pdf" );
                Response.AppendHeader( "content-size", data.Length.ToString( ) );
                Response.BinaryWrite( data );
            }
            Response.End();                
        }
        else
        {
            // Generate the data here. I am loading a file just for an example
            using ( System.IO.FileStream stream = new System.IO.FileStream( @"C:.pdf", System.IO.FileMode.Open ) )
                using ( System.IO.BinaryReader reader = new System.IO.BinaryReader( stream ) )
                {
                    data = new byte[ reader.BaseStream.Length ];
                    reader.Read( data, 0, data.Length );
                }

            // Store the content for retrieval              
            Cache.Insert( reportKey, data, null, DateTime.Now.AddMinutes( 5 ), TimeSpan.Zero );

            // This is the key bit that tells the frame to reload this page 
            //   and start downloading the content. NOTE: Url has a query string 
            //   value, so that the content isn't generated again.
            Body.Attributes.Add("onload", "window.location = 'binary.aspx?data=t'");
        }
    }
0
répondu MarcLawrence 2009-09-13 08:00:53
la source

une solution rapide si vous voulez seulement afficher un message ou un chargeur gif jusqu'à ce que la boîte de dialogue de téléchargement soit affichée est de mettre le message dans un conteneur caché et lorsque vous cliquez sur le bouton qui génère le fichier à télécharger vous rendre le conteneur visible. Ensuite, utilisez jQuery ou javascript pour saisir l'événement de mise au point du bouton pour cacher le conteneur qui contient le message

0
répondu Mihaela Rada 2017-08-06 12:50:01
la source

si Xmlhttprequest avec blob n'est pas une option, alors vous pouvez ouvrir votre fichier dans une nouvelle fenêtre et vérifier si les éléments eny sont remplis dans le corps de cette fenêtre avec interval.

var form = document.getElementById("frmDownlaod");
 form.setAttribute("action","downoad/url");
 form.setAttribute("target","downlaod");
 var exportwindow = window.open("", "downlaod", "width=800,height=600,resizable=yes");
 form.submit();

var responseInterval = setInterval(function(){
	var winBody = exportwindow.document.body
	if(winBody.hasChildNodes()) // or 'downoad/url' === exportwindow.document.location.href
	{
		clearInterval(responseInterval);
		// do your work
		// if there is error page configured your application for failed requests, check for those dom elemets 
	}
}, 1000)
//Better if you specify maximun no of intervals
0
répondu aniketKumkar 2017-12-04 07:24:00
la source

si vous avez téléchargé un fichier, qui est sauvegardé, par opposition à être dans le document, il n'y a aucun moyen de déterminer quand le téléchargement est complet, car il n'est pas dans la portée du document actuel, mais un processus séparé dans le navigateur.

-1
répondu Diodeus - James MacFarlane 2011-10-06 10:48:35
la source

crée une iframe lorsque le bouton / lien est cliqué et ajoute ceci au corps.

                  $('<iframe />')
                 .attr('src', url)
                 .attr('id','iframe_download_report')
                 .hide()
                 .appendTo('body'); 

crée une iframe avec delay et la supprime après le téléchargement.

                            var triggerDelay =   100;
                            var cleaningDelay =  20000;
                            var that = this;
                            setTimeout(function() {
                                var frame = $('<iframe style="width:1px; height:1px;" class="multi-download-frame"></iframe>');
                                frame.attr('src', url+"?"+ "Content-Disposition: attachment ; filename="+that.model.get('fileName'));
                                $(ev.target).after(frame);
                                setTimeout(function() {
                                    frame.remove();
                                }, cleaningDelay);
                            }, triggerDelay);
-2
répondu Pir Abdul 2014-05-27 13:45:07
la source

Autres questions sur javascript http mime