Search code examples
jqueryclicklightboxcolorbox

.stopPropagation() is TOO thorough :/


I have some code. Basically the entire DIV is clickable, but I need ONE button within that DIV to perform a different function to the rest of the DIV, I've tried .stopPropagation() but it's TOO thorough, as it disables the OTHER function I am trying to run on .CLICK().

The button in question (is next to "+ add item") and has unfortunately collapsed, but it still clickable. You'll see that it is supposed to fire a lightbox, but it also adds the product to the DIV above it. I want to fire JUST the lightbox, but NOT add the product into my "basket", can anyone steer me in the right direction? My code is below;

HTML:

<form method="post" id="partnumbers" name="partnumbers" action="formHandler">
<div id="specialOffer">
<ul>
    <li>
    <div id="prodD">
        <input type="hidden" name="partNum_1" id="catnum1" value="" />
        <div id="close" style="display:none;"><a href="#">Remove X</a></div>
        <div id="Prod1"></div>
    </div>
    </li>
    <li>
    <div id="prodO">
        <input type="hidden" name="partNum_2" id="catnum2" value="" />
        <div id="close" style="display:none;"><a href="#">Remove X</a></div>
        <div id="Prod2"></div>
    </div>
    </li>
    <li>
    <div id="prodA">
        <input type="hidden" name="partNum_3" id="catnum3" value="" />
        <div id="close" style="display:none;"><a href="#">Remove X</a></div>
        <div id="Prod3"></div>
    </div>
    </li>
    <li>
    <div id="prodSubmit">
        <input name="Submit" id="Submit" type="submit" value="Submit" />

    </div>
    </li>
</ul>
</div>

<div id="flyout1">
<ul class="paginate-1">
    <li><div id="subProd" class="9059863">
    <img class="thumb" src="images/placeholder.jpg" width="110" height="110" />
    <span class="product">
    <p class="title">PRODUCT TITLE</p>
        <p class="number">PARTnum</p>
        <p class="price">Price</p>
    </span>
    <a href="#" class="button">+ Add item</a>
        <a href="http://www.google.co.uk" class="qv"><img src="images/qv.png" width="17" height="17" /></a>
</div></li>
    <li><div id="subProd" class="9087361">
    <img class="thumb" src="images/placeholder.jpg" width="110" height="110" />
    <span class="product">
    <p class="title">PRODUCT TITLE</p>
        <p class="number">PARTnum</p>
        <p class="price">Price</p>
    </span>
    <a href="#" class="button">+ Add item</a>
    <a href="http://www.google.co.uk" class="qv"><img src="images/qv.png" width="17" height="17" /></a>
</div></li>
    <li><div id="subProd" class="9087378">
    <img class="thumb" src="images/placeholder.jpg" width="110" height="110" />
    <span class="product">
    <p class="title">PRODUCT TITLE</p>
        <p class="number">PARTnum</p>
        <p class="price">Price</p>
    </span>
    <a href="#" class="button">+ Add item</a>
    <a href="http://www.google.co.uk" class="qv"><img src="images/qv.png" width="17" height="17" /></a>
</div></li>
    <li><div id="subProd" class="9087354">
    <img class="thumb" src="images/placeholder.jpg" width="110" height="110" />
    <span class="product">
    <p class="title">PRODUCT TITLE</p>
        <p class="number">PARTnum</p>
        <p class="price">Price</p>
    </span>
    <a href="#" class="button">+ Add item</a>
        <a href="http://www.google.co.uk" class="qv"><img src="images/qv.png" width="17" height="17" /></a>
</div></li>
    <li><div id="subProd" class="9059791">
    <img class="thumb" src="images/placeholder.jpg" width="110" height="110" />
    <span class="product">
    <p class="title">PRODUCT TITLE</p>
        <p class="number">PARTnum</p>
        <p class="price">Price</p>
    </span>
    <a href="#" class="button">+ Add item</a>
    <a href="http://www.google.co.uk" class="qv"><img src="images/qv.png" width="17" height="17" /></a>
</div></li>
</ul>
</div>
</form>

CSS:

#specialOffer, #flyout1, #flyout2, #flyout3 {margin:0; padding:0; width:990px; overflow:hidden;}
#specialOffer {padding:10px 0 0 20px;}
#flyout1 {background:transparent url(../images/popupBG0.png) top left no-repeat;}

#specialOffer UL, UL.paginate-1, UL.paginate-2, UL.paginate-3 {
    float:left;
    margin:0; padding:0;
    height:260px;
    display:block;
}
#specialOffer UL {width:970px;}
#specialOffer UL, UL.paginate-3 {
    height:270px;
}
#specialOffer UL LI, UL.paginate-1 LI, UL.paginate-2 LI, UL.paginate-3 LI {
    float:left;
    margin:30px 30px 0 27px; padding:0;
    display:inline;
    width:130px;
    height:200px;
}
#specialOffer UL LI {
    height:220px;
}

#scrollable {
    margin-top:10px;
    float:left;
    background-color:#eee;
    width:990px;
    border-top: 1px;
    border-top-color: #CCC;
    border-top-style: solid;
}

.pager {
  margin-right:10px;
  overflow:hidden;
  padding:1em 0;
  float:right;
}

.pager li{
  float:left;
  list-style-type:none;
  margin-right:.3em;
  font-size:1.1em;
}

.pager a{
  color:#FF9182;
  outline:none;
  text-decoration:underline;
}
.pager a:hover{
  text-decoration:none;
}
.pager .active a {
 color:#666;
 font-weight:bold;
}

.pager .disabled {
 width:32px;
 text-indent:-9999px;
}

/* Needed for carousel*/
.flexiwrap {
  margin:0 0 0 20px; padding:0;
  float:left;
  width:970px;
  height:271px;
}

/* PAGINATED CONTENT */
#Prod1, #Prod2, #Prod3, #subProd {float:left; margin:0; padding:0; width:130px;}
#Prod4 {float:left; margin:0; padding:0; width:130px;}
#Prod1 img.thumb, #Prod2 img.thumb,
#Prod3 img.thumb, #subProd img.thumb {
    margin:0; padding:0 10px;
    background-color:#fff;
    border:1px solid #ccc;
}

.button, .qv {
    float:left;
    background-image: linear-gradient(#ffffff, #eeeeee);
    border: 1px solid #ccc;
    border-radius: 3px;
    color: #666;
    cursor: pointer;
    display: inline-block;
    font-size: 13px;
    line-height: 17px;
    padding: 5px 10px;
    text-decoration:none;
    overflow: visible;
}
.qv {
    z-index:9999px;
}
#Prod1 .qv, #Prod2 .qv,
#Prod3 .qv, #subProd .qv {
    float:right;
    margin:0;
    padding:0;
    cursor: pointer;
    padding:5px 5px 0px 6px;
}
#Prod1 .qv IMG, #Prod2 .qv IMG,
#Prod3 .qv IMG, #subProd .qv IMG {
    border:0 none;
    margin:0; padding:0;
}

#Prod1 .product P, #Prod2 .product P,
#Prod3 .product P, #subProd .product P {margin:5px 0; padding:0; line-height:13px;}
#Prod1 .product .title, #Prod2 .product .title,
#Prod3 .product .title, #subProd .product .title {color:#666; font-size:13px;}
#Prod1 .product .number, #Prod2 .product .number,
#Prod3 .product .number, #subProd .product .number {color:#666; font-size:11px;}
#Prod1 .product .price, #Prod2 .product .price,
#Prod3 .product .price, #subProd .product .price {
    font-size:20px;
    font-weight:bold;
    margin-bottom:3px;
    line-height:20px;
}

#close {margin-top:-15px;}
#close a {float:right; margin:0; padding:0; text-decoration:none;}

#Prod1, #Prod2, #Prod3 {border:1px solid #ccc; height:110px; cursor:pointer;}
#prodDoll INPUT, #prodOutfit INPUT, #prodAcc INPUT {display:none;}
#Prod4 {float:left; margin:0; padding:0; width:130px; height:110px; cursor:pointer;}
#subProd {cursor: pointer;}

JS:

$('#flyout1').hide();
$('#prodSubmit').hide();

$('#flyout1 #subProd').click(function() {
    var id1 = $(this).attr('class');
    $("#catnum1").val(id1);  
    $("#Prod1").html($("." + $(this).attr('class')).html());
    $("#Prod1").css("border", "none");
    $("#prodD #close").css("display", "block");
    $("#prodD .button, #prodD .qv").css("display", "none");
    $("#Prod1").attr('rel', 'done');
});

$("#prodD #close a").click(function() {
    $("#prodD #close").css("display", "none");
    $("#Prod1").empty();
    $("#Prod1").css("border", "1px solid #CCC");
    $("#Prod1").removeAttr("rel")
});

$("#Prod1").on("click",function(){
    $("#flyout1").slideToggle();
});

$("a.qv").click(function(e) { e.stopPropagation(); });
$("a.qv").colorbox();

and I have set up a fiddle here :)

Any help would be greatly appreciated, as I am probably missing the obvious :/


Solution

  • Agreed, you are effectively snookered since colorbox seems to rely on event bubbling, so e.preventDefault() blocks its action. Straightforwardly, you can have either colorbox or prevent the click event bubbling, but not both.

    A stackoverflow search reveals that others have suffered the same problem though I can't find a scenario that precisely matches yours.

    I tried various things and came up with the following approach (aka "hack") :

    • create an invisible dummy link for the purpose of opening the colorbox
    • append the dummy link directly to the document body so it not inside a problematic "subProd" div
    • attach an event handler to the "qv" links which does e.preventDefault(), e.stopPropagation() then transfers its href to the dummy link before triggering a click on it.

    The code is surprisingly simple :

    var $dummyLink = $("<a/>").colorbox().appendTo("body").hide();
    
    $("a.qv").on('click', function(e) {
        e.preventDefault();
        e.stopPropagation();
        $dummyLink.attr('href', this.href).trigger('click');
    });
    

    DEMO

    This seems to overcome the immediate issue.

    Depending on what you are trying to achieve, there may be further work getting the colorbox to relate to the particular "qv" that was clicked. If that's an issue, then it's maybe better handled as a separate question.