2010-04-29 4 views
5

ajouter dynamiquement une <un> (lien) balise DOM avec:« return false » est ignoré dans certains navigateurs pour le lien ajouté dynamiquement au DOM avec JavaScript

var link = document.createElement('a'); 
link.href = 'http://www.google.com/'; 
link.onclick = function() { window.open(this.href); return false; }; 
link.appendChild(document.createTextNode('Google')); 
//someDomNode.appendChild(link); 

Je veux que le lien pour ouvrir dans une nouvelle fenêtre (je sais que c'est mauvais, mais c'est obligatoire). J'ai également essayé d'utiliser l'attribut "target", mais j'ai aussi un mauvais comportement avec cette solution aussi.

Mon code fonctionne bien dans IE et Firefox, mais le renvoie false ne fonctionne pas dans Safari, Chrome et Opera. Par ne fonctionne pas, je veux dire que le lien est suivi après l'ouverture de la nouvelle fenêtre.

Je pense que je pourrais être à cause de l'environnement V3 Google Maps ...

Edit: Pour voir le comportement sur la page réelle:

  1. Aller à http://tinyurl.com/29q6nw6
  2. Cliquez sur n'importe quel marqueur sur la carte, un ballon montrera.
  3. Cliquez sur le titre dans le ballon, le lien doit ouvrir dans une nouvelle fenêtre (travail dans IE et FF, mais pas dans Safari, Chrome et Opera.

Toute aide est la bienvenue!

Edit2: Le problème est dans la fonction "MakeInfoWindowContent" qui se trouve dans "gmaps3.js" Je n'utilise pas DOM pour créer les éléments (j'utilise une chaîne) car cette chaîne HTML doit être passée à Google Maps (pour la fenêtre d'information - le ballon) En fait, le même lien est créé à 2 endroits différents: un à gauche, créé avec la fonction DOM (comme indiqué dans cette question) qui fonctionne dans tous les navigateurs et une dans le ballon, cr Avec une chaîne HTML, celle-ci ne fonctionne pas bien dans Safari, Chrome et Opera (le lien est suivi après l'ouverture de la nouvelle fenêtre même avec le retour false).

Éditer 3: Encore aucune idée pourquoi cela se produit ... Si quelqu'un a une idée, faites le moi savoir!

+0

Fonctionne pour moi: http://jsbin.com/aqode#noedit Chrome 2 + 4, Opera 10, Safari 4 (tous Win). Cliquez sur le lien, une nouvelle fenêtre/onglet est ouvert, la fenêtre parent reste sur la même page. –

+0

Ça marche aussi pour moi à cette URL, bizarre que ça ne marche pas dans ma page avec le même code: S Peut-être que c'est à cause de l'envi de Google Maps. Question mise à jour avec plus de détails ... – AlexV

Répondre

3

Est-ce que prévenir l'action par défaut pour le travail d'événement peut-être? Je ne sais pas si gmaps gère les liens dans sa fenêtre d'information d'une autre manière, sinon, cela devrait fonctionner.

Mise à jour: le premier exemple n'a pas fonctionné. L'événement n'a pas été transmis lors de l'utilisation de "inline" onclick pour affecter un événement. Celui-ci est tested and found to be working.

function bindEvent(target, event, handler) { 
    if (typeof target.addEventListener != 'undefined') {  
     target.addEventListener(event, handler, false); 
    } else if (typeof target.attachEvent != 'undefined') { 
     target.attachEvent('on' + event, handler); 
    } 
} 

var link = document.createElement('a'); 
link.href = 'http://www.google.com/'; 
link.appendChild(document.createTextNode('Google')); 

bindEvent(link, 'click', function (e) { 
    if (typeof e.preventDefault != 'undefined') { 
     // Common/W3C events 
     e.preventDefault(); 
    } 

    // (Old) IE specific events 
    e.returnValue = false; 

    var target = e.target || e.srcElement; 
    window.open(target.href); 

    return false; 
}); 

document.getElementsByTagName('body')[0].appendChild(link); 
+0

Ça ne marche pas mais c'est le plus proche de ce que je pensais que ce serait. Ma conclusion est que c'est Google Maps qui interfère avec mes événements ... – AlexV

0

Comment éviter d'utiliser un script pour ouvrir la fenêtre?

var link = document.createElement('a'); 
link.href = 'http://www.google.com/'; 
link.target = '_blank'; 
link.appendChild(document.createTextNode('Google')); 
+0

Testé cette solution et j'ai le même problème. Question mise à jour avec plus de détails ... – AlexV

+0

J'ai testé en ajoutant target = "_ blank" à l'élément et cela a fonctionné (vous devriez alors supprimer le gestionnaire d'événement onclick). –

1

Le problème peut être une erreur de script qui annule l'exécution de javascript avant que le résultat false soit atteint. Dans ce cas, le lien est généralement suivi. Vérifiez si vous utilisez une méthode/propriété spécifique au navigateur et vérifiez les erreurs javascript.

Je ne peux pas vérifier votre script car il ne semble pas être disponible.

+0

Le script que vous pouvez voir est très simple et fonctionne dans IE 6-7-8 et Firefox. Je doute fortement que ce soit une erreur de script car je ne vois rien dans les journaux d'erreurs de Chrome, Safari et Opera. – AlexV

+0

Vous devriez vérifier si vous atteignez le retour de toute façon (peut-être juste ajouter une alerte). Si vous l'atteignez, les navigateurs ne prennent pas en charge cette syntaxe pour définir les événements onclick. Essayez "#" comme href si vous n'avez pas à vous soucier des utilisateurs sans javascript. – dbemerlin

+0

J'ai ajouté une alerte ('debug') après le retour et l'alerte n'est pas affichée, donc le retour est exécuté mais ignoré dans certains navigateurs ... Etrange! – AlexV

1

Quelques idées

  • Google maps en quelque sorte re-copies (juste une supposition) contenu html avant d'ouvrir les événements js popup et laisse derrière lui. Vous pouvez essayer d'attacher un écouteur d'événement après l'ouverture de la fenêtre contextuelle gmap. Le code contruit les événements en concaténant des chaînes - peut-être Vous devriez essayer aussi.

  • Dernière suggestion (et stupide): essayez d'utiliser addEventListener au lieu d'attacher un événement directement.

+0

Après une recherche, c'est la concaténation qui ne fonctionne pas (celle de MakeInfoWindowContent). Celui en JavaScript pur fonctionne ... – AlexV

2

Réglez le href-'javascript:void(0);' et au lieu de référencer this.href dans votre gestionnaire onclick, coder en dur l'URL il à la place.

0
var link = document.createElement('A'); 
link.setAttribute('href', 'http://www.google.com/'); 
link.setAttribute('onclick', 'window.open(this.href, "_blank");return false;'); 
link.appendChild(document.createTextNode('Google')); 
0

Essayez ceci:

link.onclick = function(event) { 
    window.open(this.href); 
    if (event.stopPropagation) 
     event.stopPropagation(); 
    return false; 
}; 

Je modifié directement les DOM, via le Chrome-Developer-Tools et cela a fonctionné pour moi.

0

Vous n'êtes pas réellement "ajouter dynamiquement une balise de lien au DOM". Votre code concatène simplement les chaînes HTML. Remplacez votre fonction MakeInfoWindowContent (dans gmaps3.js) avec des méthodes DOM natives.

function MakeInfoWindowContent(name, institutionName, description, address, url) { 
    var result = document.createElement('div'); 
    result.className = 'infoBulle'; 
    // etc. 
    return result; 
} 
0

@AlexV - Vous devez garder les événements onclick en ligne atomiques. Il y a deux solutions faciles: envelopper l'action entière à l'intérieur d'une seule fonction d'auto-exécution ou déplacer le window.open() et return false dans sa propre fonction:

Option One

utiliser une fonction anonyme auto-exécution.

result += ' <h3><a href="' + url + '" onclick="(function(){window.open(' + url + '); return false;})()">' + instituteName + '</a></h3>' + "\n"; 

Option Deux

Déplacez le code dans sa propre fonction:

function openCustomWindow(url) { 
    window.open(url); 
    return false; 
} 

... et appeler cette fonction à la place:

result += ' <h3><a href="' + url + '" onclick="openCustomWindow(' + url + ')">' + instituteName + '</a></h3>' + "\n"; 

[EDIT] Je suis tellement désolé. J'ai totalement raté ça. Vous devriez toujours faire l'une des deux méthodes ci-dessus (seule une fonction peut return false, pas une déclaration). Le problème ici est en fait que votre this change de votre fonction à l'onclick réel. Lorsqu'il est exécuté dans le onclick, this fait référence à window, et non à l'événement. Parce qu'il n'y a pas window.href, l'instruction à window.open(undefined) échoue. Et parce qu'il échoue, l'étiquette <a> entre en jeu, je pense spécifier l'URL deux fois (une fois dans le <a href> et encore dans le window.open() devrait fixer

+0

Ahh j'ai sûrement pensé que cela fonctionnerait, mais aucune de vos solutions ne fonctionne (le lien est suivi après l'ouverture de la nouvelle fenêtre dans Safari, Chrome et Opera). – AlexV

+0

Wow. Complètement manqué le problème. J'ai mis à jour la réponse. C'est vraiment difficile de déchiffrer ce qu'il y a dans la fenêtre de Google Maps. J'ai dû utiliser 'document.getElementById ('resultMap'). InnerHTML' pour voir à quoi ressemblait le HTML rendu dans Safari (et FF). Je me demande comment ils font ça ... – Andrew

0

Essayez d'utiliser la délégation de l'événement jQuery:..

function initialize(){ 
    // ... code ... 

     $("#resultMap").delegate("a.myLink").click(function(){ 
      window.open(this.href, "myWindow"); 
      return false; 
     }); 
     Search(); 

    // ... more code ... 
} 


function MakeInfoWindowContent(name, instituteName, description, address, url) 
{ 
    var result = '<div class="infoBulle">'; 
    if (url != '') 
     result += ' <h3><a href="' + url + '" class="myLink">' + instituteName + '</a></h3>'; 
    else 
     result += ' <h3>' + instituteName + '</h3>'; 
    if (Trim(description) != '') 
     result += ' <p>' + description + '</p>'; 
    result += ' <p>' + address + '</p>'; 
    result += '</div>'; 
    return result; 
} 
0

Je J'ai testé cette solution et ça marche!

Je vous propose d'adopter une approche différente, mais à mon avis plus simple et plus propre: utilisez les événements jQuery .live (je vois que vous utilisez déjà jQuery, donc cela ne devrait pas poser de problème)!

Vous avez seulement besoin de deux petits changements:

Premier changement:

Modifier la 3ème ligne de MakeInfoWindowContent fonction pour créer des liens de cette façon (il supprime simplement l'attribut onclick et ajoute une classe pour plus de clarté) :

result += '<h3><a class="marker_link" href="' + url + '">' + instituteName + '</a></h3>' + "\n"; 

Deuxième changement:

Où que vous voulez (par exemple sur la charge DOM ou avant la création de la carte) exécuter ceci:

$('div#resultMap a.marker_link').live('click', function(e) { 
    window.open(this.href); 
    e.preventDefault(); 
}); 

Fin :)

Cela fonctionne interceptant l'événement click dans la phase de bouillonnement au document. Je l'ai essayé et cela fonctionne même avec Google Chrome.

+0

En fait, il utilise la même idée de la réponse de David Murdoch. –

+0

Ne semble pas fonctionner car les liens sont ajoutés dynamiquement à la page. J'ai essayé d'exécuter le 2ème changement au bon endroit, mais la fonction append n'est pas faite. – AlexV

+0

Laissez-moi vous prouver que cela fonctionne :) Ouvrez Google Chrome et rendez-vous sur la page intéressée: http://www.plateformesinnovie.com/. Puis appuyez sur Maj + Ctrl + J pour ouvrir la console Javascript et exécutez (en le collant dans la console) le code suivant (c'est un code différent de celui ci-dessus, j'ai supprimé la classe marker_link): '$ ('div # resultMap ') .live (' clic ', fonction (e) {window.open (this.href); e.preventDefault();}); '. Ensuite, cliquez sur le lien dans un marqueur et vous remarquerez que maintenant le lien ne sera pas suivi dans la page en cours, mais seulement dans (deux) nouvelles fenêtres !!. –

Questions connexes