2011-11-01 3 views
2

J'ai un bouton tout sélectionner sur cette page qui fonctionne sur d'autres navigateurs mais pas IE8, quelqu'un peut-il voir le problème mais en regardant ma source?Tout sélectionner ne fonctionne pas dans IE8

MISE À JOUR:

Voici mon code:

<td valign="middle" align="center"><input type="checkbox" name="products-quote[]" value="<?php echo $product_option['id']; ?>" /></td> 
<td valign="middle" align="center"><input type="checkbox" name="products-sample[]" value="<?php echo $product_option['id']; ?>" /></td> 

<script language="JavaScript"> 
function toggle(source) { 
    checkboxes = document.getElementsByName(source.name); 
    for(var i in checkboxes) 
    checkboxes[i].checked = source.checked; 
} 
</script> 

    <tr> 
    <td valign="middle" align="center"><input type="checkbox" onClick="toggle(this)" name="products-quote[]" value="0" /></td> 
    <td valign="middle" align="center"><input type="checkbox" onClick="toggle(this)" name="products-sample[]" value="0" /></td> 
    <td><p><b>Select all</b></p></td> 
    </tr> 
+0

quand vous commencez une prime - vous devriez vraiment choisir une réponse .. vous allez donner la prime de toute façon (c'est ainsi que la prime fonctionne) donc mieux vous choisissez la réponse - pour la prochaine fois de toute façon – alonisser

Répondre

1

Vous avez fait les erreurs suivantes:

  1. Votre fragment de marquage, si les sections PHP sont ignorées, n'est pas valide → W3C Markup Validator
  2. Vous n'avez pas déclaré checkboxes une variable (locale) avec le mot-clé var, sujet aux erreurs.
  3. Vous n'avez pas utilisé les collections en direct rétrocompatibles pour les formulaires et les contrôles de formulaire normalisés par W3C DOM Level 2 HTML.
  4. Vous avez tenté d'itérer sur les propriétés d'un objet implémentant l'interface NodeList de W3C DOM Level 2+ Core avec une instruction for - in. for - in itère sur propriétés énumérables d'un objet, mais les propriétés de ces objets hôtes n'ont pas besoin d'être énumérables. En fait, si leurs propriétés avec le nom numérique (que vous étiez après) sont énumérables, et si leurs propriétés avec nom non numérique sont énumérables (!), Dépend de l'implémentation DOM. Cela explique les différences entre les navigateurs. Toujours utiliser une déclaration (C-style) for là.

Modification:

<script type="text/javascript"> 
    function toggleAll(source) 
    { 
    var checked = source.checked; 
    var checkboxes = source.form.elements[source.name]; 

    for (var i = checkboxes.length; i--;) 
    { 
     var checkbox = checkboxes[i]; 
     if (checkbox != source) 
     { 
     checkbox.checked = checked; 
     } 
    } 
    } 
</script> 

… 

<form …> 
    <table …> 
<?php 
    foreach (… as $product_option) 
    { 
    /* DRY */ 
    $id = $product_option['id']; 
?> 
    <tr> 
     <td><input type="checkbox" name="products-quote[]" 
       value="<?php echo $id; ?>"></td> 
     <td><input type="checkbox" name="products-sample[]" 
       value="<?php echo $id; ?>"></td> 
    </tr> 
<?php 
    } 
?> 
    <tr> 
     <td><input type="checkbox" name="products-quote[]" value="0" 
       onclick="toggleAll(this)"></td> 
     <td><input type="checkbox" name="products-sample[]" value="0" 
       onclick="toggleAll(this)"></td> 
     <td>Select all</td> 
    </tr> 
    </table> 
</form> 

Non testé dans ce cas, mais généralement prouvé. J'ai supprimé les attributs et les éléments de présentation afin que vous puissiez voir la solution plus clairement. Vous devez remplacer ceux avec le formatage CSS. Vous pouvez également envisager de donner des noms différents aux cases à cocher de bascule (de sorte que vous n'ayez pas à les exclure dans l'itération côté client et le traitement côté serveur) et de passer le nom du groupe de cases à cocher en tant que seconde argument à toggle(…).

-1

Try 'getElementsByTagName' au lieu de 'getElementsByName'. getElementsByName ne fonctionne pas dans IE.

+0

Il ne fonctionne plus dans les autres navigateurs. – Rob

+1

Comment avez-vous eu cette idée? getElementsByName() fonctionne ** au moins ** dans IE/MSHTML 6.0.2800.1106. Ce n'est pas la raison pour laquelle cela échoue. Voir mon autre réponse. – PointedEars

2

Pourquoi ne pas simplement utiliser la collection document.forms['myForm'].elements?

0

L'utilisation d'index peut être la méthode la plus efficace. Parce que, quand j'ai essayé d'énumérer l'objet nommé checkboxes (comme vous), semble stocké le nombre d'objets différents dans les différents navigateurs.
Donc, essayez d'utiliser une boucle qui compte jusqu'à la longueur de checkboxes et l'itérer.

function toggle(source) { 
    checkboxes = document.getElementsByName(source.name); 
    for(var i=0;i<checkboxes.length;i++) 
    checkboxes[i].checked = source.checked; 
} 
+0

getElementsByName() est comparativement inefficace et incompatible. Utilisez plutôt les collections, elles sont là pour cette raison. – PointedEars

+0

@PointerdEars ce n'est pas une raison pour un downvote - pour une page typique c'est presque imperceptible. – alonisser

+0

@ Kul-Tigin notez que vous devriez mettre en cache checkboxs.length avant la boucle for avec: var i = checkboxes.length; peu de différence dans une boucle régulière mais fait la différence dans un grand – alonisser

0

plus d'aide et de bonnes pratiques: au lieu de la balise meta Tou utilisent vous pouvez forcer IE à utiliser son bord moteur Rendring par les balises meta suivantes (le jeu de caractères que pour la compatibilité pour le code actuel)

<meta charset="windows-1252" /> why are using this encoding instead of utf-8? 

<meta http-equiv="X-UA-Compatible" content="IT=edge,chrome=IE8"> 

avis que l'ajout du chrome = IE8 est pas vraiment nécessaire, mais si vous rencontrez un utilisateur avec IE8 ou moins qui a installé chorme le cadrez utiliserait le chrome avancé moteur de rendu au lieu de IE8

(par la façon dont vous aussi rapidement possible eux d'installer Google Frame - mais c'est hors sujet)

d'après mon expérience ce hack résout beaucoup de problèmes IE8 mystère. 1.12 vous utilisez language = javascript - vous n'en avez plus besoin .. mieux en utilisant type = text/javascript (aussi presque pas nécessaire aujourd'hui, peut-être pertinent dans le futur avec la montée de coffeescript etc.)

2.le script est inclus dans la table! Pourquoi? mieux d'inclure dans la tête ou même mieux (pour la performance) dans la partie inférieure de la section du corps avec $ (document) .produire la fonction autour ou mieux encore dans le bas avec $ .ready et appelé à partir d'un fichier js différent pour séparer js de le reste du html.

et maintenant pour la partie la plus importante - vous appelez déjà jQuery dans votre page - laissez-le faire le gros du travail! Jquery est déjà optimisé pour la compatibilité inter-navigateur, performances, etc, il est aussi plus simple à utiliser:

vous pouvez lier l'événement à bascule sans le « onclick » avec quelque chose comme: l'ajout d'une classe « selectAll » pour la case à cocher boutons.

et maintenant pour le script:

$(document).ready(function(){ 
     $(".selectAll").click(function(){ 
      var b = $(this); 
      if (b.checked){ 
       $('form input:checkbox [name=b.name]').each(function(i){ 
       this.prop("checked",true); 
       }); 
      } 
     }); 

    }); 
  • Je sais que ce n'est pas le sélecteur plus optimisé .. mais ce n'est pas son problème en ce moment.

edit: Il semble que j'ai fait quelques erreurs dans le code - corrigé! et fonctionne comme un charme

+0

jQuery est * interne * bloat par rapport à ce que le DOM offre déjà. Il n'y a pas de "différences de navigateur" à travailler ici. – PointedEars

+0

vous avez complètement raté le point! il utilise déjà jquery dans sa page! pour des choses différentes, les plugins etc. ne prêchent pas, et comme il utilise déjà jquery pour d'autres choses, il est beaucoup plus court d'utiliser javascript. aussi je rejette le jQuery est bloatware genre de non-sens - très faible encombrement, sélecteurs optimisés pour le bord (et dans les coulisses défaut navigateur sélecteurs DOM si disponible) et oui - crossbrowser est important - et regardez - c'est vraiment la question ici - Un problème de navigateur croisé! – alonisser

+0

@alanisser Aller déboguer jQuery et être surpris à quel point il est vraiment bloaty. Go jsPerf it: [Sizzle est lent] (http://jsperf.com/sizzle-is-slow/2), [Comparaison des moteurs de choix populaires vs approche native] (http://jsperf.com/jquery-vs -sizzle-vs-midori-vs-mootools-sélecteurs-test/33). Non, ce n'est pas * à la base un problème multi-navigateur, il est juste * perçu * comme un en raison de la mauvaise approche en premier lieu. Vous n'utilisez pas document.getElementsByName() pour accéder aux contrôles de formulaire. DOM 101, vraiment. – PointedEars