简体   繁体   中英

In jQuery how can I correctly use a selector as var in a for loop?

I'm trying to use a variable in my selector when applied to dynamically created div's (from an XML file) in a for loop. The previewDialog is only opening when I click on the very last div. How do I get the previewDialog to open when I click on EACH overview div?

<script type="text/javascript">
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
  xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET", "Library.xml", false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML;

var f = xmlDoc.getElementsByTagName("FeaturedEntry");
var x = xmlDoc.getElementsByTagName("BookEntry");
for (b = 0; b < x.length; b++) {

  var bToString = b.toString();
  var overviewOpener = "#overview" + bToString;
  var previewDialog = "#preview" + bToString;

  // increase the default animation speed to exaggerate the effect
  $.fx.speeds._default = 1000;
  $(function () {
    $(previewDialog).dialog({
      autoOpen : false,
      show : "blind",
      hide : "explode"
    });

    $(overviewOpener).click(function () {
      $(previewDialog).dialog("open");
      return false;
    });

  });

  document.write(overviewOpener + " " + b.value + " " + bToString);
  document.write("<div id='overview");
  document.write(b);
  document.write("'><img id='cover' src='/ClientBin/");
  icon = x[b].getAttribute("Icon");
  document.write(icon);
  document.write("'/><br><strong><a href='http://www.google.com'>");
  title = x[b].getAttribute("Title");
  document.write(title);
  document.write("</a></strong><br>");
  author = x[b].getAttribute("Author");
  document.write(author);
  document.write("<br>");
  document.write("Rating:");
  rating = x[b].getAttribute("Rating");
  numStars = Math.round(rating * 5);
  for (n = 0; n < numStars; n++) {
    document.write("<img src='/Media/star.png'/>");
  }
  document.write("<br><a><img id='button' src='Media/Small_iBookstore_Badge.gif' /></a>");
  document.write("</div>");

  document.write("<div id='preview");
  document.write(b);
  document.write("'>This is a test ");
  document.write(b);
  document.write("</div>");

}
</script>

Closures my friend. Closures. The problem is that $(function () { isn't executed inline like you think it is, it's executed when the DOM loads. But your var b is OUTSIDE of the $(function) call, which means when this function is called, it will pick up the current version of b, which is why you see it only works for the last one. You need to take your $(function) completely outside your for loop and then do something like this:

$(function () {
  //add the for loop here 
    for (var b = 0; b < x.length; b++) {
        $("#preview" + b).dialog({
            autoOpen: false,
            show: "blind",
            hide: "explode"
        });

        $("#overview" + b).click(function () {
            $("#preview" + b).dialog("open");
            return false;
        });
    });

Having said that. You're still doing it the wrong way. A loop like this is not the right way to do it either. What you should REALLY do is instead of this:

document.write("<div id='preview");
    document.write(b);
    document.write("'>This is a test ");
    document.write(b);
    document.write("</div>");

Do this:

document.write("<div class='preview'>This is a test ");
    document.write(b);
    document.write("</div>");

See how we've given each div the same class of "preview?"

Now you can just do this:

$(function () {
      //no for loop needed now
            $(".preview").dialog({
                autoOpen: false,
                show: "blind",
                hide: "explode"
            });

Edited : You're right, you do need to have a unique name for each div, but not exactly for the reason you think. The reason is because the jQuery UI Dialog moves the element to the top of the DOM. Originally, I was thinking you would do something like:

$(".overview").closest(".SomeContainerDiv").find(".preview") .... But unfortunately, in this case (because the div is moved), you can't do that. Take a look at this jsfiddle:

http://jsfiddle.net/ehs4K/

I couldn't go through the entire code but from what I could understand the overview div is created dynamically.For dynamicaly created elements you have to use

$(overviewOpener).live("click",function(){
//hanfle click function});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM