2013-08-22 10 views
3

Ce qui suit est un exemple simple de test pour démontrer ce que je suis en train de faire:Sélection: cible sur document.ready()

<html> 
<head> 
<title>Test</title> 
</head> 
<body> 
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> 
<script type="text/javascript"> 
$(document).ready(function() 
{ 
    $(":target").css('color', 'red'); 
}); 
</script> 
<ul> 
    <li id="one">One</li> 
    <li id="two">Two</li> 
    <li id="three">Three</li> 
</ul> 
</body> 
</html> 

L'idée est de faire quelque chose à travers jQuery/Javascript à l'élément ciblé , lorsque quelque chose est ciblé (par exemple, test.html # deux). Cela fonctionne comme je le souhaite dans Firefox et IE 10, mais pas dans Chrome, Opera ou Safari, ce qui me laisse me demander si c'est un bug dans certains navigateurs, si ce que j'essaie de faire est en quelque sorte faux , ou si j'ai été confronté à une partie d'une spécification ou d'une autre qui n'est pas suffisamment précise.

Si je change le code jQuery pour faire

alert($(":target").length); 

il devient évident que Chrome, Opera et Safari ne peut pas trouver le: élément cible pendant document.ready(), mais appeler le même code plus tard (via la console ou la fonction attachée à un événement click) trouve les éléments.

Quand devrait-on: rendre la cible accessible à JS?

Répondre

2

Cela a été posté comme commentaire mais a ensuite été retiré , vous pouvez essayer d'attendre l'événement de chargement de la fenêtre:

$(window).on('load hashchange', function(){ 
    $(':target').css('color', 'red'); 
}); 

Ceci pour moi a produit des résultats mitigés sur Ch rome, il a travaillé lors d'une actualisation de la page (F5) mais pas lors de la frappe entrer dans la barre d'adresse.

Je ne sais pas s'il y a un moyen de gérer cela correctement à la page charge à l'aide du sélecteur :target mais vous pouvez toujours obtenir la valeur de hachage et de l'utiliser comme sélecteur:

$(window).on('load hashchange', function(){ 
    var target = window.location.hash; 
    $(target).css('color', 'red'); 
}); 

MISE À JOUR

que je suis en train de faire des recherches sur la question ainsi que des tests et moi avons quelques idées à partager:

Tout d'abord, nous devons comprendre que lorsque vous appelez $(':target') jQuery utilise en interne querySelectorAll(':target') ce qui signifie qu'il est directement lié à la spécification CSS de la pseudo-classe, mais pourquoi ne fonctionne pas à l'intérieur document.ready()?

Eh bien, je trouve que enveloppant le code à l'intérieur setTimeout(fn,0) fait réellement le sélecteur disponible:

$(document).ready(function(){ 
    setTimeout(function(){ 
     $(':target').css('color', 'red'); //THIS WORKS 
    },0); 
}); 

Vous pouvez lire this answer une explication sur la façon dont l'ajout d'un délai d'attente zéro ms fait réellement une différence, mais au fond, ce permet au navigateur de compléter d'autres tâches non-javascript (dans lesquelles nous trouverions la vraie pseudo-classe CSS disponible pour la requête). Je crois que Firefox gère ses processus internes d'une manière ou d'une autre et c'est pourquoi le code fonctionne là-bas sans avoir besoin d'un timeout.

Maintenant, j'ai aussi découvert que le moteur de sélecteur de grésillement interne de jQuery fournit une solution de repli pour les navigateurs qui ne prennent pas en charge CSS :target pseudo-classe, que vous pouvez utiliser à l'intérieur document.ready() sans problème:

$(document).ready(function(){ 
    $(':target()').css('color', 'red'); 
}); 

Cela fonctionne parce qu'au lieu de compter sur la classe CSS, il est une implémentation javascript qui utilise la propriété de hachage sur l'objet window.location, il est interne défini comme suit:

"target": function(elem) { 
     var hash = window.location && window.location.hash; 
     return hash && hash.slice(1) === elem.id; 
    } 

le seul que vous pensez devrait noter que cette fonction passera par tous les éléments de la page si elle n'est pas passé un sélecteur comme :target(div), donc je crois que l'utilisation de la solution de contournement que j'ai fournie plus tôt serait encore une meilleure option que cela.

+0

Fait intéressant, 'window.location.hash' semble être disponible pendant document.ready(), même si: target ne correspond à rien à ce stade. Cela suffit pour une solution de contournement, mais ne répond pas à la question de savoir s'il s'agit d'un bug de navigateur. –

+0

... et alors que '$ (": target ")' ne trouve rien pendant 'document.ready()', '$ (window.location.hash)' trouve l'élément approprié. Curieux et plus curieux ... –

+0

@StephenBaillie J'ai mis à jour ma réponse avec quelques idées sur la question –

0

vous pouvez utiliser le sélecteur cible CSS3 pour les travaux de style

:target 
{ 
color:red; 
} 
0

Comme il n'y a pas de logique spécialisée dans votre exemple (if déclarations ou tel), pourquoi ne faites-vous pas tout simplement le style en CSS? La pseudo-classe :target est une CSS3 selector.

:target { 
    color: red; 
} 

Notez que cela fonctionnera dans tous les navigateurs modernes, et même certains très anciens navigateurs (Chrome 1 et Firefox 1.3, par exemple), mais avec Internet Explorer, il est pris en charge à partir de la version 9.

Vous pouvez également le faire dans les deux endroits si vous le souhaitez (CSS et JavaScript), mais le JavaScript semble redondant sauf si vous avez spécifiquement besoin de la compatibilité IE < = 8.

J'ai remarqué que vous utilisez jQuery version 1.10.1, qui conserve la prise en charge de IE < = 8. Est-ce important? Sinon, vous pouvez également passer à jQuery 2.0.2 (dernière version au moment de l'écriture).

+0

Je pense que ce qu'il essaye de réaliser pourrait ne pas être juste le tourner au rouge. – Kabie

+0

@Kabie est entièrement correct - c'est juste une charge utile factice pour démontrer le problème. Ce que je veux réellement faire avec l'élément: target implique .parent() et ensuite une autre traversée de DOM, et jusqu'à ce que la prochaine itération de CSS nous donne! ou $ pour sélectionner un élément qui n'est pas en bas de la liste de recherche et qui nécessite JS. –

-1

Vous devriez faire comme ça

$("li:target") 

Cela permet de sélectionner l'élément. Ceci est la meilleure façon

Reportez-vous cette s'il vous plaît,

http://api.jquery.com/target-selector/

Ou vous devez retirer le document prêt et de mettre le script à la fin du document html

1

Parce que la page est pas été rechargées .Vous devez le lier à hashchange:

$(window).on('hashchange', function(){ 
    $(":target").css('color', 'red'); 
}); 

http://jsfiddle.net/sXsYx/

Notez que vous avez beaucoup plus de travail pour faire les choses, combiner peut-être avec $(document).ready