web-dev-qa-db-fra.com

jQuery .click () fonctionne sur tous les navigateurs mais Safari

J'ai un morceau de JavaScript qui crée dynamiquement une balise A à l'intérieur d'un div existant, puis appelle la fonction jQuery "cliquez" dessus. Cela fonctionne comme prévu dans tous les navigateurs, sauf Safari.

Safari renvoie l'erreur suivante:

'undefined' n'est pas une fonction (évaluant '$ ('. Shell a ') [0] .click ()')

Toutes les idées sur ce que je fais mal ou pourquoi cela ne fonctionne pas dans Safari et comment le faire fonctionner (ou un morceau de code qui fonctionne dans tous les navigateurs), j'ai essayé d'utiliser .trigger("click") comme bien et cela donne la même erreur.

Javascript

function writeAndClickLink(url) {

    $('.Shell').html('<a href="' + url + '"></a>');
    $('.Shell a')[0].click();
}

et dans le HTML:

<div class="Shell"></div>

La raison pour laquelle je le fais de cette façon étrange est que la fonction est appelée à partir d'un site Flash pour ouvrir une fenêtre Twitter où je donne une récompense pour avoir tweeté. Jusqu'à présent, cela a été le seul moyen pour que l'événement "Tweet" soit lié à la fenêtre. Si j'ouvre la fenêtre d'une autre manière (window.open par exemple), il ne capture pas l'événement lié qui me permet de savoir qu'ils ont réellement terminé le Tweet.

Le flux est quelque chose comme:

  • L'utilisateur clique sur le bouton Tweet en flash
  • Flash appelle la fonction javascript pour écrire dynamiquement href et "cliquer" dessus
  • La fenêtre Twitter s'ouvre
  • L'utilisateur a réussi à tweeter
  • L'événement Tweet est capturé et les mises à jour clignotent avec succès
  • Le contenu est déverrouillé en flash
33
Scott
var a = $('.Shell a')[0];
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent('click', true, true, window);
a.dispatchEvent(evObj);

Voir http://www.howtocreate.co.uk/tutorials/javascript/domevents (rechercher "Événements de déclenchement manuel").

34
Trevor Dixon

La réponse de Trevor Dixon corrige Safari, mais interrompt même le dernier Firefox:

TypeError: Pas assez d'arguments pour MouseEvent.initMouseEvent

La meilleure façon de prendre en charge Safari - sans casser Firefox - serait d'utiliser initEvent au lieu de initMouseEvent comme ceci:

var element = document.getElementById('your_id_here');
if(element.click)
    element.click();
else if(document.createEvent)
{
    var eventObj = document.createEvent('MouseEvents');
    eventObj.initEvent('click',true,true);
    element.dispatchEvent(eventObj);
}

Pour mettre à jour pour 2016, MouseEvent doit être utilisé à la place de initMouseEvent qui est déconseillé:

var eventObj = new MouseEvent("click", {
    bubbles: true,
    cancelable: true
});
element.dispatchEvent(eventObj);
8
Alex W

$('.Shell a')[0] extrait un objet DOM de l'objet jQuery. Cet objet DOM n'a que des méthodes DOM (pas des méthodes jQuery) et il n'y a pas de méthode .click() standard de l'industrie sur un élément <a> Jusqu'à HTML5 et il n'est pas encore implémenté dans tous les navigateurs. voir une implémentation incomplète sur différents navigateurs.

Vous avez deux choix. La première option obtient un objet jQuery et utilise la méthode .click() sur l'objet jQuery. Cela ne fonctionnera de manière fiable que si vous déclenchez des gestionnaires de clics jQuery, pas si vous voulez simplement le clic par défaut pour la balise <a>.

function writeAndClickLink(url) {

    $('.Shell').html('<a href="' + url + '"></a>');
    $('.Shell a').eq(0).click();
}

Ou, si cliquer sur l'URL va simplement aller sur une nouvelle page Web, ne vous embêtez même pas à modifier le DOM et définissez simplement window.location car il est inutile de modifier le DOM du tout si vous allez simplement sur un nouvelle page web:

function writeAndClickLink(url) {
    window.location = url;    
}
6
jfriend00

$('.Shell a')[0] renvoie l'élément DOM natif auquel aucune méthode jQuery n'est liée

Supprimez le "[0]" pour conserver l'objet jQuery afin d'utiliser les méthodes jQuery

 $('.Shell a').click()
3
charlietfl