Question

New to jQuery but quite fascinated with it and really loving it. Starting to turn me off, though, with this problem. Would really appreciate any help. Spent the last week trying to make heads or tails out of it. I apologize if this problem has been posted before.

I have a list of products. Each product is enclosed in a <div>. Inside each div has a floated <span> for product information and an <a> to go the appropriate URL of the product. This list is generated programmatically using ASP.NET.

<div id="prod1">
   <span id="infoProd1" class="prodInfo" />
   <a class="prodURL" href="url1">Name of product #1</a>
</div>
   :
   :

Unfortunately, I don't have a URL as this is only in a development platform behind a firewall. The site pretty much looks like the one below. I hope this helps.

+----------+------------------------------+
|  #prod1  |                              |
+----------+                              |   Each #prodNum div looks like:
|  #prod2  |    overlay and frame divs    |
+----------+       appear over here       |  +-- #prod1 -----------------+
|  #prod3  |     with product details     |  |               |           |
+----------+       only if .prodInfo      |  |  .prodURL     | .prodInfo | 
|          |         is clicked.          |  |               |           |
|    :     |                              |  +---------------------------+
|          |                              |   
+----------+------------------------------+

The information for each product (including photo) is stored in a database.
Depending on the action of the user on the span (i.e. prodInfo), the desired process is:

  • hover will display a small popup with some product info and some details (e.g. price).
  • click will show (animate) a semi-transparent overlay and a <div id="frame"> containing all information regarding the product, including the photo.

I have an image inside the frame that when clicked, would hide the overlay/frame.
Information (including photo) is pulled using jQuery Ajax $.get().
Using jQuery, I was able to achieve this on the first pass (the first click). However, after I close "frame" and hide the overlay, and then hover over any "prodInfo," it'll display the small popup as it should be but at the same time ALSO DISPLAYS the overlay and the "frame" as if I invoked a click.

Here is the simplified jQuery code for the two events:

$(".prodInfo").mouseover(
  function(e) {   // function fired when 'moused over'
    var popupItem = $("#div_infoPopupItem");  // absolute positioned popup
    var prod = $(this).attr('id');
    var prd;

    popupInit(popupItem, e); // changes the top/left coords

    $.ajax({            
      type    : 'GET',
      url     : 'prodInfo.aspx',
      data    : 'id=' + prod,
      success :

        function(prodInfo, status) {
          var prodStr = '<b>No product name.</b>';

          prd = prodInfo.split('::');  // product info delimited by '::'
          prodStr = '<div class="popupInfo_head">' + prd[0] + '</div>' +
                    '<div style="margin:2px;">' + prd[1] + '</div>';
                    // and so on...

          popupItem.html(prodStr);
          return false;
        },
    error :
      function() {
        popupItem.html('Error in collecting information.');
      }
    });

    popupItem.animate({ opacity : .94 }, { queue:false, duration: 120 });
    return false;
  }
);

$(".prodInfo").click(
  function(e) {
    var prod    = $(this).attr('id');
    var frame   = $("#div_frame");
    var overlay = $("#div_overlay");
    var info;
    var img     = new Image();

    document.getElementById('div_frame').scrollTop = 0;
    $.get('prodInfo.aspx', { id: prod },
      function (result) {
        info = result.split(';;');     // name ;; status ;; description ;; price, etc.

        $(this).ajaxSuccess(
          function (e, request, settings) {
            img.src = 'prodImage.aspx?id=' + prod;
            img.id  = 'prodImg';

            //populate the frame with prod info
            $(img).load(function () {
              $("#prodInfoImage")
                  .css('background', 'transparent url("prodImage.aspx?id=' + prod + '") no-repeat 50% 50%');
              switch (info[1]) {
                case '0':
                    $("#prodStatus")
                        .removeAttr("class")
                        .addClass("status_notavail")
                        .text('Not available');
                        break;
                case '1':
                    $("#prodStatus")
                        .removeAttr("class")
                        .addClass("status_avail")
                        .text('Available');
                        break;
              } // switch

              $("#prodInfoDesc")
                  .empty()
                  .append(info[2]);
              $("#prodInfoExtra")
                  .empty()
                  .append(info[3]);

              $("#prodName").text(info[0]);
            }
          )
          .error(
            function() {
              return false;
            }
          );  // image load

          // animate overlay, frame and display product info
          overlay .animate({ top   : '0' }, { queue: false, duration: 280 })
                  .animate({ height: '100%' }, 280, '',
                    function() {
                      frame.animate({ opacity : .92 }, 320);
                      return false;
                    }
                  );
          return false;
          }
        );     // ajax success
      }
    );  // get
  }
);

Below is the event definition of the "close" image located inside the frame.

$("#img_close").click(
  function (e) {
    $("#div_frame")
      .animate({ opacity: 0}, 100, '', 
        function() {
          $("#div_overlay")
            .animate({ top   : "50%" }, { queue: false, duration: 120 })
            .animate({ height: "0px" }, 120);
        }
      );

      return false;
  }
);

As mentioned, this will work as planned only before the first click. After I click on a prodInfo span and close the frame/overlay, the next mouseover on a prodInfo actually invokes BOTH mouseover and ALSO a click (which shows back the overlay/frame).

EDIT: Thanks to all who responded. I will try to debug it using each of your suggestions.

EDIT(2): Mahalo for everyone who commented and responded.

Was it helpful?

Solution

I can't quite picture the entire setup you have, but this was the first thing that popped to mind. It might be a case of event bubbling, carrying the click event to both the close button and the span. Perhaps when you click the close event, the span click might also fire, but the frame is being hidden by the close event. Check out the bind function for more info on stopping default action and event bubbling: http://jquery.bassistance.de/api-browser/#bindStringObjectFunction

As Don mentioned, a sample URL would definitely help a lot!

Edit:

Upon further examination, I think that it's the way you're attaching the ajaxSuccess event within the click() event. It might still be active and firing whenever ANY ajax request is made.

Edit, again:

I've just confirmed this with my own test of the code and it definitely seems to be the issue. In fact, it's attaching the ajaxSuccess function each time you click, so if you've clicked five times, it executes that function five times. Since an AJAX request is made in the mouseover event, it's also firing the previously attached ajaxSuccess functions and showing your overlay and frame.

To get around this try the following:

Instead of:

    $.get('prodInfo.aspx', { id: prod },
  function (result) {
    info = result.split(';;');     // name ;; status ;; description ;; price, etc.

    $(this).ajaxSuccess(

Try:

    $.get('prodInfo.aspx', { id: prod },
  function (result, statusText) {
    info = result.split(';;');     // name ;; status ;; description ;; price, etc.

    if ( statusText == 'success' ) {

OTHER TIPS

I'm going to take a punt, and say that the problem is that you generate/show the popup on the first mouseover/click, and then just render it opaque. On the second mouseover, it looks like the old div is being nabbed and made visible again.

Other than that, if you could provide a URL linking to the page where you have this problem, I can take a deeper look.

the problem might be that you aren't hiding what was created on the click when you do the mouseover. So, when you mouseover again, you are showing the first, but since the first now has the click event item in it, it shows it as well. You'll want to hide the click event item on mouseover, so it doesn't show as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top