2009-05-13 8 views
2

Ne laissez pas le code ci-dessous vous effrayer. La question est vraiment simple, seulement deux lignes font problème:jquery: Variables return NaN

Pourquoi mon code a généré un code d'erreur NaN? J'essaie de soustraire une valeur de variable d'une autre afin que la position des éléments soit correcte.

Les variables ont leur valeur de jQuery position() qui est censée être entière de toute façon.

Vérifiez les lignes de ces lignes:

// For some reason NaN error code gets generated when line below gets executed. 
var posTop = Startpos.top - Stoppos.top; 
var posLeft = Startpos.left - Stoppos.left; 

code complet:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> 
<head> 
    <meta http-equiv="Content-type" content="text/html; charset=iso-8859-1" /> 
    <title>Drag drop 1</title> 
    <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script> 
    <script type="text/javascript" src="js/jquery-ui-1.7.1.custom.min.js"></script> 
    <script type="text/javascript"> 
    $(document).ready(function() { 
     var Startpos = new Array; 
     var Stoppos = new Array; 

     // Make images draggable. 
     $(".item").draggable({ 

      // Elements cannot go outside #container 
      containment: 'parent', 

      // Make sure the element can only be dropped in a grid. 
      grid: [150,150], 

      // Find original position of dragged image. 
      start: function(event, ui) { 

       // Make sure picture always are on top when dragged (z-index). 
       $(this).css({'z-index' : '100'}); 

       // Show start dragged position of image. 
       Startpos = $(this).position(); 
       $("div#start").text("START: \nLeft: "+ Startpos.left + "\nTop: " + Startpos.top); 
      }, 

      // Find position where image is dropped. 
      stop: function(event, ui) { 

       // Revert to default layer position when dropped (z-index). 
       $(this).css({'z-index' : '10'}); 

       // Show dropped position. 
       Stoppos = $(this).position(); 
       $("div#stop").text("STOP: \nLeft: "+ Stoppos.left + "\nTop: " + Stoppos.top); 
      } 
     }); 
     $(".item").droppable({ 
      drop: function(event, ui) { 

       // Dragged image gets swapped with dropped on image. 
       var prev_position = "#" + $(this).attr('id'); 
       // For some reason NaN error code gets generated when line below gets executed. 
       var posTop = Startpos.top - Stoppos.top; 
       var posLeft = Startpos.left - Stoppos.left; 

       // Below variables will work. But unfortunately they 
       // doesn't give the correct numbers for the purpose. 
       // var posTop = Startpos.top; 
       // var posLeft = Startpos.left; 

       $(prev_position).css({'top' : posTop, 'left' : posLeft}); 

       $("div#test").text("Passed variables. Top: " + posTop + " left: " + posLeft); 
      } 
     }); 
    }); 
    </script> 
    <style> 
    body { 

    } 
    #container { 
     position:relative; 
     width:480px; 
     border:1px solid #000; 
    } 
    .item { 
     position:relative; 
     width:150px; 
     height:150px; 
     z-index:10; 
    } 
    </style> 
</head> 
<body> 
    <div id="container"> 
     <img id="productid_1" src="images/pic1.jpg" class="item" alt="" title="" /><img id="productid_2" src="images/pic2.jpg" class="item" alt="" title="" /><img id="productid_3" src="images/pic3.jpg" class="item" alt="" title="" /><img id="productid_4" src="images/pic4.jpg" class="item" alt="" title="" /><img id="productid_5" src="images/pic5.jpg" class="item" alt="" title="" /><img id="productid_6" src="images/pic6.jpg" class="item" alt="" title="" /><img id="productid_7" src="images/pic7.jpg" class="item" alt="" title="" /><img id="productid_8" src="images/pic8.jpg" class="item" alt="" title="" /><img id="productid_9" src="images/pic9.jpg" class="item" alt="" title="" /> 
    </div> 
    <div style="clear:both;"></div> 
    <div id="start">Waiting...</div> 
    <div id="stop">Waiting...</div> 
    <div id="hover">Waiting...</div> 
    <div id="stop2">Waiting...</div> 
    <div id="test">Waiting...</div> 
</body> 
</html> 

Répondre

4

Le problème est que droppable.drop() est appelé avant draggable.stop(). Donc, votre Stoppos n'est pas encore calculé. Une façon de traiter cela serait de simplement suivre quel objet est en train de glisser, et de calculer la position pour cela dans droppable.drop(). par exemple. (sous-ensemble de votre code), notez l'objet "Glisser".

$(document).ready(function() { 
     var Startpos = new Array; 
     var Stoppos = new Array; 
     var Dragging = null; 

     // Make images draggable. 
     $(".item").draggable({ 

       // Elements cannot go outside #container 
       containment: 'parent', 

       // Make sure the element can only be dropped in a grid. 
       grid: [150,150], 

       // Find original position of dragged image. 
       start: function(event, ui) { 
         Dragging=this; 
         // Make sure picture always are on top when dragged (z-index). 
         $(this).css({'z-index' : '100'}); 

         // Show start dragged position of image. 
         Startpos = $(this).position(); 
         $("div#start").text("START: \nLeft: "+ Startpos.left + "\nTop: " + Startpos.top); 
       }, 

       // Find position where image is dropped. 
       stop: function(event, ui) { 
         // Revert to default layer position when dropped (z-index). 
         $(this).css({'z-index' : '10'}); 

         // Show dropped position. 
         Stoppos = $(this).position(); 
         $("div#stop").text("STOP: \nLeft: "+ Stoppos.left + "\nTop: " + Stoppos.top); 
         Dragging=null; 
       } 
     }); 

Cependant, il existe probablement plusieurs autres moyens légitimes de contourner ce problème. Etes-vous sûr que ce sont les lignes qui causent le problème?

+0

Je me demande aussi - quel est le point d'initialiser Stoppos et Startpos à un tableau? Pourquoi ne pas les laisser non initialisés ou setting = null? – jlarson

+0

Hmmm ... Qu'est-ce qui me dérange est que remplaçant: var posTop = Startpos.top - Stoppos.top; var posLeft = Startpos.left - Stoppos.left; Avec: var = postop Startpos.top; var posLeft = Startpos.left; Fonctionne même si les chiffres ne sont pas ce que je voulais. – Cudos

+0

initialisation Stoppos et Startpos les rend disponibles dans le périmètre global. Mais je suis nouveau pour les variables globales en javascript. Juste essayé quelque chose qui semblait fonctionner. – Cudos

1

Pour autant que je sais la position() n'est pas une fonction jQuery.

Essayez ceci:

Startpos = $(this).offset(); 

Vous devriez alors être en mesure d'accéder aux propriétés haut et à gauche.

+0

En fait, vous pouvez utiliser position() Voir le lien: http://docs.jquery.com/CSS/position la position d'un élément – Cudos

0

-

pouvez-vous s'il vous plaît confirmer que "var = postop Startpos.top - Stoppos.top;"

renvoie un entier/valeur Double valide pour postop? J'ai codé sur un de mes projets la semaine dernière et j'ai eu le même problème de NaN, j'ai essayé d'analyser la valeur de Integer et cela a fonctionné.

Parce que vous faites un calcul mathématique, essayez l'analyse syntaxique des valeurs dans Double/Int avant de les soustraire,

Parfois, la solution est assez simple et nous avons tendance à plus compliquer.

Si le traitement par analyse ne fonctionne pas, il se peut que vous ne transmettiez pas la bonne valeur à partir de la matrice. Essayez quelque chose comme Startpos [0] .Top

Espérons que cela aide, bonne chance!

+0

J'ai essayé le parseInt() sans succès: var posTop = parseInt (Startpos.top - Stoppos.top); ou var posTop = parseInt (Startpos.top) - parseInt (Stoppos.top); – Cudos

0

Les Startpos ou les Stoppos ne sont toujours qu'un tableau vide lorsque vous effectuez ce calcul. Essayez plutôt de les paramétrer sur une valeur par défaut appropriée (0, 0), car cela peut faciliter le repérage de ce qui s'égare.

0

Ce qui me déconcerte est que cela fonctionne:

remplacerons:

var posTop = Startpos.top - Stoppos.top; 
var posLeft = Startpos.left - Stoppos.left; 

Avec:

var posTop = Startpos.top; 
var posLeft = Startpos.left; 

fonctionnera même si les chiffres ne sont pas ce que je veux. Il semble qu'une simple soustraction soit invalide pour une raison quelconque.

+0

Stoppos.top & Stoppos.left sont-ils toujours initialisés sous forme de nombres? –

+0

Oui, ils le sont. Le problème est ailleurs. – Cudos

0

Merci pour l'aide les gars :)

Trouvé le problème.

Stoppos = $(this).position(); 

ne devrait pas être:

$(".item").draggable({ 
stop: function(event, ui) { 

Mais au lieu de:

$(".item").droppable({ 
drop: function(event, ui) { 

Code complet:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> 
<head> 
    <meta http-equiv="Content-type" content="text/html; charset=iso-8859-1" /> 
    <title>Drag drop 1</title> 
    <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script> 
    <script type="text/javascript" src="js/jquery-ui-1.7.1.custom.min.js"></script> 
    <script type="text/javascript"> 
    $(document).ready(function() { 
     var Startpos = null; 
     var Stoppos = null; 

     // Make images draggable. 
     $(".item").draggable({ 

      // Elements cannot go outside #container 
      containment: 'parent', 

      // Make sure the element can only be dropped in a grid. 
      grid: [150,150], 

      // Find original position of dragged image. 
      start: function(event, ui) { 

       // Make sure picture always are on top when dragged (z-index). 
       $(this).css({'z-index' : '100'}); 

       // Show start dragged position of image. 
       Startpos = $(this).position(); 
       $("div#start").text("START: \nLeft: "+ Startpos.left + "\nTop: " + Startpos.top); 
      }, 

      // Find position where image is dropped. 
      stop: function(event, ui) { 

       // Revert to default layer position when dropped (z-index). 
       $(this).css({'z-index' : '10'}); 
      } 
     }); 
     $(".item").droppable({ 
      drop: function(event, ui) { 

       // Dragged image gets swapped with dropped on image. 
       var prev_position = "#" + $(this).attr('id'); 
       Stoppos = $(this).position(); 
       var posTop = Startpos.top - Stoppos.top; 
       var posLeft = Startpos.left - Stoppos.left; 
       $(prev_position).css({'top' : posTop, 'left' : posLeft}); 

       // Test window 
       $("div#stop").text("STOP: \nLeft: "+ Stoppos.left + "\nTop: " + Stoppos.top); 
       $("div#test").text("Passed variables. Top: " + posTop + " left: " + posLeft); 
      } 
     }); 
    }); 
    </script> 
    <style> 
    body { 

    } 
    #container { 
     position:relative; 
     width:480px; 
     border:1px solid #000; 
    } 
    .item { 
     position:relative; 
     width:150px; 
     height:150px; 
     z-index:10; 
    } 
    </style> 
</head> 
<body> 
    <div id="container"> 
     <img id="productid_1" src="images/pic1.jpg" class="item" alt="" title="" /><img id="productid_2" src="images/pic2.jpg" class="item" alt="" title="" /><img id="productid_3" src="images/pic3.jpg" class="item" alt="" title="" /><img id="productid_4" src="images/pic4.jpg" class="item" alt="" title="" /><img id="productid_5" src="images/pic5.jpg" class="item" alt="" title="" /><img id="productid_6" src="images/pic6.jpg" class="item" alt="" title="" /><img id="productid_7" src="images/pic7.jpg" class="item" alt="" title="" /><img id="productid_8" src="images/pic8.jpg" class="item" alt="" title="" /><img id="productid_9" src="images/pic9.jpg" class="item" alt="" title="" /> 
    </div> 
    <div style="clear:both;"></div> 
    <div id="start">Waiting...</div> 
    <div id="stop">Waiting...</div> 
    <div id="hover">Waiting...</div> 
    <div id="stop2">Waiting...</div> 
    <div id="test">Waiting...</div> 
</body> 
</html> 

Maintenant, je dois juste comprendre comment obtenir les emplacements des images lorsqu'ils ont été déplacés plus d'une fois. Il semble que la position: relative est automatiquement ajouté aux traîneaux et faire des problèmes dans le calcul des positions :(