Target element nearest to where event was fired

Hi again…hopefully a simple one for those in the know. I’ve had a google and play around with this, but feel I’m wasting time…

I have 4 top panels that have an open button and share the class name (.step-arrow-c)
Each panel has a hidden bottom panel and share the class name (.bottom) with unique ids

The .step-arrow-c class fires a JQ .Toggle (“blind”) . As there’s 4 different panels, I’m trying to make it fire the blind in the relevant panel… Played with (this) - but I think closest() may do it…not sure… any advice plzzzz?

<script>
$(".step-arrow-c").click(function(event) {
$( event.target ).closest( "#s1-bottom, #s2-bottom, #s3-bottom, #s4-bottom"  ).toggle( "blind" );
});
</script>

<span id ="s4-arrow-c" class="step-arrow-c">
  <label id="step4-edit" class="step-edit">EDIT</label>
  <label id="step4-arrow" class="step-arrow">^</label>
</span>


<div id ="s4-bottom" class="bottom";>
    <div id="s4-content-c" class="content-c"></div>
  </div><!--end s4 bottom-->

I’m sort of confused with the question, can you rephrase it?

Anyways, the reason that code doesn’t work is that .closest() only checks upward through it’s ancestors, while #s1-bottom...#s4 are siblings.

Like I said, I’m not super sure what you’re asking, but this should at least get the above working:

$(".step-arrow-c").click(function(event) {
    $(this).siblings('#s1-bottom, #s2-bottom, #s3-bottom, #s4-bottom').toggle('bline')
})

Oh! One other thing, you also have a weird semicolon that might cause validation issues down the line: <div id ="s4-bottom" class="bottom";>

Good spotting thanks.

Will try rephrase. I have 4 panels each with a button and a content panel. The buttons have class .step-arrow-c. Now I need to find which content panel to open, so I was looking for the nearest (thinking nearest to the button clicked). But yes, the closest() goes up the tree, so this wont do it.

Maybe I’ll just need to write functions for each id and not on class click

If you are just trying to toggle the next div in sequence only then .next() would do it.

$(".step-arrow-c").click(function(event) {
    $(this).next().toggle('blind')
})

Of course that depends on the html never changing so is a little fragile.

hmm ye that could do it - thanks again. Suppose if I need to put more divs inbetween I could add spans with display block and that won’t affect the next() function right?

You would be better off making the target more solid by identifying it with a data attribute.

Something roughly like this:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
.step-arrow-c {
    cursor:pointer;
    margin:20px 0 0;
    background:#f9f9f9;
    position:relative;
}
.step-arrow-c:after{
    content:"";
    width: 0; 
    height: 0; 
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    border-top: 10px solid #f00;
    display:inline-block;
    margin:0 0 0 5px;
}
.open:after{
    border-top: none;
    border-bottom: 10px solid #f00;    
}
.content-c {
    padding-bottom:10px;
    border-bottom:1px solid #000;
}
</style>
</head>

<body>
<div data-target="#s1-bottom" class="step-arrow-c">Edit </div>
<div id="s1-bottom" class="bottom">
        <div class="content-c"> test test <br>
                test test <br>
                test test <br>
                test test <br>
        </div>
</div>
<div data-target="#s2-bottom" class="step-arrow-c">Edit </div>
<div id="s2-bottom" class="bottom">
        <div class="content-c"> test test <br>
                test test <br>
                test test <br>
                test test <br>
        </div>
</div>
<div data-target="#s3-bottom" class="step-arrow-c">Edit </div>
<div id="s3-bottom" class="bottom">
        <div class="content-c"> test test <br>
                test test <br>
                test test <br>
                test test <br>
        </div>
</div>
<div data-target="#s4-bottom" class="step-arrow-c">Edit </div>
<div id="s4-bottom" class="bottom">
        <div class="content-c"> test test <br>
                test test <br>
                test test <br>
                test test <br>
        </div>
</div>
<script src="http://code.jquery.com/jquery-latest.min.js"></script> 
<script>
$(".step-arrow-c").click(function(event) {
    var myTarget = $(this).data('target');
        $(this).toggleClass('open');
        $(myTarget).toggle('blind');
})
</script>
</body>
</html>

Great stuff…didnt know about data-target :flushed: and can use along the lines of the open toggle to set some transition on an arrow change

:thumbsup:

The ‘data-’ attribute allows you to embed custom data attributes. The ‘target’ portion is just a name I made up so that it can be referenced. It could be anything:

e.g. ‘data-myElementThatIneedtoFind="#some-id

The value can be any snippet of data that you might find useful and therefore can be accessed with js. It’s like a little storage place for data. The link above explains it better than I can :smile:

As an aside note in your example you were using spans and I changed my example to a div as that is more semantic as you should not run inline elements immediately into block elements (although its valid).

Also ‘label’ elements are to associate form controls and shouldn’t be used for any other function - unless of course you were using some form controls in your real example.

It’s all about semantics :smile:

Notice how I added an arrow after the text (using :after) rather than using an element in the html. The arrow is then toggled up and down with the class I added and cuts down on code. Simpler is better in most cases.

1 Like

Got the data attribute…if I run into any problems, I’ll be sure to check the link out…
Semantics noted…

To make the html easier to read, i’d often break up the divs with span elements that have display block… wrong I know, but works.

And same reason for the incorrect use of the label tag. I know a label is used to direct person to the input element…and thought it wont hurt using them as labels as it makes the html easier to read (and prettier with the yellow!!!) :princess:

Never used the css :after - something I need to look into… before I set a class toggle with css rotate transitions…imagine :after will create the same effect with no js…so happy days

But yet again, thanks for feedback Paul. Your help here has been top-notch

@PaulOB I think I learn something new every single time you post

Thanks. I learn a lot from the posts of others also so its a two way thing :slight_smile:

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.