IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Utilisation du "name" fenêtre pour activer un onglet déjà ouvert, pb : l'onglet courant s'actualise aussi ?


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Par défaut Utilisation du "name" fenêtre pour activer un onglet déjà ouvert, pb : l'onglet courant s'actualise aussi ?
    Bonjour,

    Le problème posé :
    Le problème global est la gestion d'un ensemble d'onglets tels que l'on n'ouvre pas (sauf action volontaire) à nouveau un document déjà ouvert.
    Un fragment (élement) peut être défini comme cible dans l'url (toutes les pages utilisent une fonction mettant graphiquement en évidence un fragment (élément) ciblé. En général si l'on vise un nouveau fragment dans un onglet déja ouvert on active l'onglet et la nouvelle cible sera atteinte.

    Bien, je sèche.

    La solution élémentaire
    Pour réouvrir des onglets déja ouverts à partir d'une même "famille d'onglets", j'utilise l'option "name" dans l'exécution de window.open(url,name,.. []).

    Je teste et débogue d'abord avec chrome (Version 43.0.2357.130 m) puis avec Explorer et Firefox.

    Le test en ligne de l'exemple de W3School ( adapté par mes soins pour la réouverture et les fragments) fonctionne très bien (y compris pour atteindre un fragment "anchor (ancre)".

    Lorsque je fais tourner l'appli (lourde Wordpress avec beaucoup de plugins dont mes développements), j'obtiens un phénomène incongru :
    1- l'activation ou l'ouverture de l'onglet défini par url et name se déroule normalement, mais
    2- L'activation (ou la création) d'onglet est obtenu par un lien utilisant onclick. Mais l'exécution de window.open(url,name,.. []) lance aussi la mise à jour de l'onglet parent comme si on exécutait simultanément window.location(url) sur la même url. J'obtiens ainsi deux onglets identiques

    Le code est simplissime
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    <a href="url" onclick="ActivateTab(url, name,..." >Aller à... </a>

    et pour js :
    Code js : Sélectionner tout - Visualiser dans une fenêtre à part
    function ActivateTab(url,name,...) { window.open(url,name) }

    Je ne trouve pas de piste.
    J'ai mis des points d'arrêts sur tous les points sensibles sans rien trouver.
    Il est certain que le problème est lié au reste du code, mais en quoi ?

    Merci d'avance, pour une idée pour comprendre ou explorer...

    Cordialement

    Trebly

    Note :
    1- clic exécute la fonction par défaut clic-droit offre les options du navigateur
    2- Tous les onglets sont nommés
    3- Test avec explorer 11 id°
    4- Exemple W3School :
    http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_win_open
    Code js : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <!DOCTYPE html>
    <html>
    <body>
     
    <p>Click the button to open a new browser window or simply activate it if exists.</p>
     
    <a href="http://www.w3schools.com#test3" onclick="myFunction()">Try it</a> 
    <!-- button ou a =dito -->
     
    <script>
    function myFunction() {
        window.open("http://www.w3schools.com#test3","w3s3"); /* Ajouter un id="test3" dans l'url avec le debogger */
    }
    </script>
     
    </body>
    </html>

  2. #2
    Membre expérimenté
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2015
    Messages
    98
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2015
    Messages : 98
    Par défaut
    Bonjour,

    Pour moi le click sur le lien provoque deux actions :
    La fonction du onclick qui ouvre la nouvelle fenêtre à l'adresse : http://www.w3schools.com#test3
    Le href du a qui mets à jour la page actuelle : http://www.w3schools.com#test3

    Il faut donc supprimer le href du a.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Par défaut Solution et reférence
    Bonsoir,

    Merci de ta réponse, tu as partiellement raison.

    Le fait de rédiger force l'auteur à une réflexion qui assez souvent mène à la solution.

    En fait il faut arrêter l'action et pour cela il faut que onclick se termine par "return false;"

    Sans le "return false;" l'exécution continue et le href est exécuté par défaut avec target="_self".

    Conserver le href permet de garder disponible l'ensemble du menu du click droit.

    Je n'ai pour l'instant trouvé aucun document qui traite de la séquence opératoire d'un tag A ou BUTTON.

    En ce qui concerne la gestion de l'ouverture d'onglets (tabs), c'est la même chose.

    On trouve de la doc pour les extensions qui ont accès à l'url des tabs (droits demandés explicitement par le fichier "manifest") ce qui est interdit à des applications pour des raisons de sécurité.

    La seule solution qui existe est pour l'application de nommer ses onglets (window.open(url,name)), il devient possible de gérer des contenus de plusieurs onglets à partir du même script. C'est d'ailleurs un des cas où l’attribut "name" (window.name) garde toute son importance quand il a disparu pour de nombreux autres objets avec HTML5.

    Par contre je n'ai trouvé aucune doc explicative claire sur la manière de résoudre ce problème (juste de questions avec des réponses souvent très anciennes et souvent fausses).

    Je n'ai pas trouvé d'explications sur la manière dont window.open(...) fonctionnait avec des onglets (windows) nommés. J'ai du le découvrir à l'aide de test. En particulier le fait que l'utilisation d'un nom existant produit l'actualisation avec l'url désignée, et s'il n'existe pas une création.

    Par contre comme il reste semble-t-il impossible pour raisons toujours de sécurité de tester l'existence de noms sans ouvrir une nouvelle fenêtre, il semble impossible pour y atteindre un fragment (on imagine : var frag= document.GetElementById(idfrag); frag.focus() de ne pas provoquer l'actualisation d'un onglet parce que le seul moyen d'obtenir un handle vers un onglet est window.open qui va travailler tout seul et en particulier actualiser la fenêtre. Dès lors atteindre le fragment passe par sa définition dans l'url ( window.open(url,name)).
    Il me semble d'ailleurs fort conseillé pur les mêmes raisons de sécurité que le nom donné à l'onglet soit introuvable par une application autre que celle qui le crée.

    Enfin l'utilisation du query de l'url permettra de passer à la nouvelle fenêtre (souvent les mêmes scripts), si nécessaire, des paramètres qui pourront être analysés par le script associé au nouvel onglet lors de son activation.

    Donc en dehors de ces possibilités, reposant totalement sur l'utilisation du name de l'onglet, l'environnement de gestion des onglets dérivés reste pauvre pour l'application.

    Les extensions disposent, elles, pour la gestion des onglets d'API de type window.tabs (webkit) qui diffèrent d'un navigateur à l'autre.

    Le contexte de ce développement est la gestion des documents volumineux à l'aide de WordPress, mais aussi de TIKI, découpés en "pages" mais avec une table des matières et des index et autres bibliographies communs. Plusieurs "sections" du même ouvrage peuvent être "ouvert(es)" simultanément et l'ensemble des liens "internes" au document multi-page (multipage) restent assurés et permettent de naviguer sans risque de réouverture de "sections (pages)" déjà ouvertes.

    Bien que le problème ponctuel soit résolu, le sujet général que j'évoque mérite, je pense, que le sujet reste ouvert.
    Je n'ai pas trouvé de tuto sur le sujet, et je n'ai pas trop le temps d'en concocter un.

    Bien cordialement

    Trebly

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Par défaut Un script qui marche, à propos de choses non dites sur window.open
    Bonjour,

    J'ai mis au point un script qui marche bien et repose sur le fonctionnement de window.open(url,name, frag) dans différents cas.

    Le résultat obtenu est exactement celui que je cherchais :
    1. Si la "tab" existe elle est réouverte avec focus sur le fragment requis
    2. Si la tab n'existe pas elle est créée et référencée.
    3. Vrai pour toutes les Tab ouvertes à partir d'url d'un même domaine et chargeant le script.


    Rappel : le problème est non seulement celui de l'ordre d'exécution et des interactions dans le traitement d'évènements, mais celui liè au fait que pour raisons de sécurité des navigateurs un script n'a pas accès aux identifiants de fenêtre qu'il n'a pas chargé lui-même.
    Ce dernier point est traité en créant un "cookie" d'échange global attaché au domaine et qui est lu et mis à jour par un script court dupliqué dans chaque fenêtre (tab).

    Note : "tab" lever l'ambiguité entre l'objet window qui va désigner alternativement un onglet ou "tab" et la fenêtre dans un navigateur qui comprend plusieurs onglets. Ici "window" "tab" et "onglet" ont le même sens.

    Les points fondamentaux sont :
    • Gérer une liste des noms de fenêtres uniques créés
    • Si la fenetre appelée est la fenetre courante il suffit de faire un focus sur le fragment recherché
    • Si l'on tente d'ouvrir une fenêtre de nom inexistant sans url, alors une fenêtre vide nouvelle est ouverte
    • Si l'on exécute window.open("",wname) pour un nom existant un objet window sera récupéré (var w = window.open("",wname)), il sera alors possible de manipuler l'objet window à titre préparatoire et en particulier effectuer un focus sur le fragment avant de la montrer.
    • Si l'on exécute successivement window.open("",wname1), que l'on teste si elle n'existe pas déjà, alors elle sera ouverte vide mais à la suite window.open(url1,wname1) la peuplera avec url1


    Les liens comprennent uniquement le href et sont triés en externes ou internes au domaine.
    Je ne traite pas ici le cas des liens externes.
    Pour les liens internes vers des pages déjà ouvertes ou non, le script est appelé par des fonctions JQuery
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $(selector).click( function(event) {... OpenOrReusePageOrFrag(parameters); ... })
    Le retour logique de la fonction permet d'arrêter ou nom le processus de traitement des événements.

    Désolé pour les commentaires de code qui sont en anglais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    /**
     * Created by Trebly on 27/08/2015.
     */
    var OpenOrReusePageOrFrag = function (url, pWname, rfrag,libel,idSrc) {/* version b50826 */
        /**
         * url : full url
         * pwname : name previously given to the window (tab) or new unique name
         * rfrag : the fragment to focus
         * libel : title of the window
         * idSrc : the identifier to manages the extended window object for data and cookie management into the others parts of script
         */
        /**
         * Principle :
         *   if pWname the one of the current page (window) then focus the fragment
         *   if not : verify if it is set
         *      - if yes : focus the fragment into the window object and show (focus) the window
         *      - if not : open new with 
         *          -> if yes : focus the frag into the windows and then the widow (which show it)
         *          -> if not : open it
         *   The url must be split or not used if window exist : the window.open considers that if url is not exactly (including frag) the same it must be updated. Then use first window.open("",wmane) and after check window.open(url,wname) to populate it
         *   So we get the window, we get the hash and the new full url (with hash) and open it on right element
         */
        if (window.name === pWname) { /* B50828 - The function can be called from the current window then we just target the frag */
            var t= document.getElementById(rfrag);
            if (t===null) {
                alert('The fragment (element link) doesn\'t exist) : ['+libel+']');
                return false;
            }
            set_header_top_position(t);
            t.focus();
            return true;
        }
     
        var w = window.open("", pWname); /* Try to find if pWanme window exists : this opens an empty tab if not known */
        if (w.document.body.innerHTML === "") { /* Check if the reference contains data : if so it is not new */
            alert("The window (tab) [" + pWname +"] doesn't exist a new tab is opened");
            window.open(url, pWname); /* if not open new */
            set_new_TOC_tab(url,pWname,libel,idSrc); // set_new_TOC_tab : crée ou met à jour le cookie
            w.focus();
            return true;
        }
        else { /* it exists then reopen will update url with frag */
            var frag = w.document.getElementById(rfrag); /* Get the rfrag id element */
            if (frag !== null) { /* If found we focus */
                alert("The window (tab) [" + pWname +"] exist and found and the element [rfrag] exist too the tab at the frag element is focused");
                frag.focus(); /* in w but not show it */
                w.focus();    /* show w in navigator */
                /* note : w = window.open(url, pWname); cannot be used it updates the window if the rfrag is not the current hash */
                return true; /* Will allow to end the onclck sequence */
            }
            else { /* frag don't exist it should not be targetted */
                alert("System error : the fragment [" + rfrag + "] \nhas not been found into the display section\n[" + pWname +
                    "]\nEven you have an obvious explanation (broken link) for example, if not\n" +
                    "please report this error to the plugin author\nThe new tab is going to be opened on current focused element  by default");
                /* Just focus the window after the alert */
                w.focus();
                return true; /* Will allow to end the onclck sequence */
                /* w = window.open(url, pWname); */
            }
            /* the structure of soft should make that reach this point is not normal */
            alert ("System error :OpenOrReusePageOrFrag b51007 - this point should not ever be reached");
            return false;
        }
     
    }
    Cordialement,

    Trebly

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo