Easiest way to get element parent - javascript

Suppose i have this structure of elements:
<div class="parent">
<div class="something1">
<div class="something2">
<div class="something3">
<div class="something4"></div>
</div>
</div>
</div>
</div>
And code like this:
$(".something4").click(function(){
//i could do it like this...
$(this).parent().parent().parent().parent().parent();
});
But that seems to be stupid, is there a better way to do this?
also i can't just say $(.parent) because there are many divs like this with class parent in my page.

Use .closest(selector). This gets the first element that matches the selector, beginning at the current element and progressing up through the DOM tree.
$('.something4').click(function() {
$(this).closest('.parent');
});

Use .closest():
$('.something4').click(function() {
$(this).closest('.parent');
});

I think you should try this
$(this).parents(".parent");
But I don't know where on the page are the other divs with this class :)

You could always use .parentNode (standard JavaScript). It's generally a bad idea to use class names that coincide with function/variable names from the library you're using (this goes for any language). Making your class names more unique is a better approach (for instance, "scparent" instead of "parent", if the name of your application was "Super Calculator" or something). This avoids conflicts such as the one you're describing.
I would caution using .closest(), simply because you may create a function like this:
function getParentElem() {
return $(this).closest('div');
}
And it would grab the parent div's in your code just fine, but if down the road you add a table for displaying data, and you run the function through a child element of the table, you will have to create another implementation that selects the table element, because that's what you now want:
<div id="tableParent">
<table id="dataTable">
<tr id="target1">
<td>Some data.</td>
</tr>
</table>
</div>
By using your function getParentElem() on the tr element, you'll end up grabbing the div with id="tableParent", rather than the actual parent, which is the table element. So, unless you've delineated your parent classes appropriately all the way through your code (which can be a pain and isn't always efficient), you may run into problems. Especially if at any point you're creating elements programmatically, or reading in data from another 3rd-party library or script.
Not saying it's not good to use .closest()... just pointing out a possible "gotcha".

i would suggest adding to the div parent an id like 'parent_1' etc. and in every son you keep the id in the rel attr
<div id="parent_1" class="parent">
<div rel="1" class="something1">
<div rel="1" class="something2">
<div rel="1" class="something3">
<div rel="1" class="something4"></div>
</div>
</div>
</div>
</div>
$(".something4").click(function(){
//i could do it like this...
$('#parent_' + $(this).attr('rel'));
});

Related

passing variables on jquery

just having some issues with this jQuery thing.
What i'm trying to do is:
i have some audio control buttons that look like this:
<p>Play audio</p>
but there are too many on the page so i'm trying to optimise the code and make a little function that checks for the div id on the button and adds tells the player what track to play.
so i've done this:
<div id="audioControlButtons-1">
<div class="speaker"> </div>
<div class="play"> </div>
<div class="pause"> </div>
</div>
<script>
$(document).ready(function() {
$("[id^=audioControlButtons-] div.play").click(function() {
var id = new Number;
id = $(this).parent().attr('id').replace(/audioControlButtons-/, '');
//alert(id);
player1.loadAudio(id);
return false;
});
});
</script>
my problem is:
the id is not passing to the the player1.loadAudio(id)
if i hardcode player1.loadAudio(1)
it works! but the moment i try to pass the variable to the function it doesn't work...
however if you uncomment the alert(id) thing you will see the id is getting generated...
can someone help?
cheers,
dan
I think I see your problem. The variable id is a string. Try;
player1.loadAudio(parseInt(id));
Yah and the initialise line isn't necessary. Just use;
var id = $(this).parent().attr('id').replace(/audioControlButtons-/, '');
I'm actually kind of confused with your example because you originally have this:
<p>Play audio</p>
but then you don't reference it again. Do you mean that this html:
<div id="audioControlButtons-1">
<div class="speaker"> </div>
<div class="play"> </div>
<div class="pause"> </div>
</div>
Is what you are actually creating? If so, then you can rewrite it like this:
<div class="audio-player">
<div class="speaker"> </div>
<div class="play" data-track="1"> </div>
<div class="pause"> </div>
</div>
Then in your script block:
<script>
$(document).ready(function() {
$(".audio-player > .play").click(function() {
var track = $(this).data('track');
player1.loadAudio(+track);
return false;
});
});
</script>
So a few things are going on here.
I just gave your containing div a class (.audio-player) so that it's much more generic and faster to parse. You don't want to do stuff like [id^=audioControlButtons-] because it is much slower for the javascript to traverse and parse the DOM like that. And if you are going to have multiples of the same element on the page, a class is much more suited for that over IDs.
I added the track number you want to the play button as a data attribute (data-track). Using a data attribute allows you to store arbitrary data on DOM elements you're interested on (ie. .play button here). Then this way, you don't need to this weird DOM traversal with a replace method just to get the track number. This saves on reducing unnecessary JS processing and DOM traversing.
With this in mind now, I use jQuery's .data() method on the current DOM element with "track" as the argument. This will then get the data-track attribute value.
With the new track number, I pass that along into your player1.loadAudio method with a + sign in front. This is a little javascript trick that allows you to convert your value into an actual number if that is what the method requires.
There are at least a couple of other optimizations you can do here - event delegation, not doing everything inside the ready event - but that is beyond the scope of this question. Hell, even my implementation could be a little bit optimized, but again, that would require a little bit more in depth explanation.

jQuery click function affecting multiple divs

I'm trying to use jQuery's click function to apply a hover state to a selected div, without differentiating the div's in the JavaScript. I'm currently using:
$(document).ready(function(){
$(".project").click(function() {
$("a.expand").removeClass("hovered");
$("a.expand").addClass("hovered");
$(".project_full").hide();
var selected_tab = $(this).find("a").attr("href");
$(selected_tab).fadeIn();
return false;
});
With the HTML:
<div class="project first project_gizmoscoop">
<div class="title">
GizmoScoop!
<div class="date">2012</div>
</div>
<a class="expand" title="(Caption)" href="#project_1">GizmoScoop!</a>
</div>
<div class="project project_sc">
<div class="title">
Striking Code
<div class="date">2011</div>
</div>
<a class="expand" title="(Caption)" href="#project_2">Striking Code</a>
</div>
The .hovered class is applied to the clicked link (specific styles from an external CSS file). However, everything is being chosen. (See http://www.codeisdna.com for an example).
I know what I'm doing wrong (I should be specifying the individual ID's or using HTML5 data attributes), but I'm stuck unnecessarily. I feel like a complete newb right now, that I can't do something this simple (although I've done more advanced stuff).
You simply need to take advantage of jQuery's flexibility (and good programming practice) and reduce your scope accordingly. You're already doing something similar with your variable definition. For example, to target only those a.expand elements inside the instance of .project that's clicked:
$(".project").click(function() {
$(this).find("a.expand").removeClass("hovered");
...
});
$(".expand").click(function() {
$(this).addClass("hovered");
..
});

JQuery. Remove a previous sibling in the DOM tree

I have the next code dynamically created using JQuery. Theere are multiple row class divs placed one under the other.
<div class="row">
....
</div>
<div class="row">
<div class="line_type"></div>
<div class="download_value"></div>
<div class="flag"></div>
<div class="email"></div>
<div class="prize"></div>
</div>
<div class="row">
....
</div>
After i create these divs I have a "pointer" to a specific div which is of class row. In JQuery, how do i make it so I go down the DOM tree, until i reach the div of class line_type and download_value and remove them both, and also I'd like to go one more node down, at the div of type email and change some of it's CSS attributes.
I was not able to find anything on the web, maybe it's cause i'm a noob at these still.
I have a "pointer" to a specific div which is of class row ->
Assuming that you have the this object of the corresponding div with class row.. then you can use .find to get the line_type and download_value inside that div.
$(this).find('.line_type').remove();
$(this).find('.download_value').remove();
Then you can use the same .find to get the div with class email and access the .css
$(this).find('.email').css(/* You code*/);
Assuming row_pointer points to the row in question:
$('.line_type, .download_value', row_pointer).remove();
$('.email', row_pointer).css(...);
check this out
$('div.row').bind('click', function() {
$this = $(this);
$('div.line_type, div.download_value', $this).remove();
$('div.email', $this).css('background-color', 'red');
});
http://jsfiddle.net/YvyE3/

How to send a form to a javascript function

I need your help to understand how I can send information from a form to a javascript function.
I've created a basic function here : http://jsfiddle.net/nZhR8/5/
The purpose of this function is to hide/display a div.
In fact, I'll have a table with a few contacts (between 0 and 20). There will be a selectlist per contact. For each contact, I'll have to display 1 special div in function of 1 own particularity. So, for contact1, I may have to display div3, and for contact2, display div1.
I'll also use the javascript function to send to the database wich div has to be displayed. It will be a kind of advancement.
If I'm doing it wrong, please tell me why.
I don't see the idea behind this but that could do the trick: http://jsfiddle.net/YCPM7/
That must be a simple draft of a much bigger project.
Also, I would suggest that you either use a common class for each DIVs
<div class="message 1">1</div>
<div class="message 2">1</div>
<div class="message 3">1</div>
...
So you can simply do:
$(".message").hide();
Enjoy.
Firstly, remove the $(...) from where you define the function showDiv, as you don't want to execute showDiv when the page has loaded.
Apart from that, your problem seems to be jsFiddle. It didn't work there, but when I copy+pasted exactly what you posted on jsFiddle into a file, fixed what I mentioned above and tried it in FF, it worked.
There are of course things you can do better about your code, but it works. Suggestions: Give all divs the same class and distinguish them by id, then hide everything with that class and show the one with the correct ID. For the onload, instead of copying the whole code just execute showDiv(1).
You need something like this jsFiddle?
<div id="1" class="1">1</div>
<div id="2" class="2">2</div>
<div id="3" class="3">3</div>
<div id="4" class="4">4</div>
<div id="5" class="5">5</div>
$('div').hide();
$('#StateSelection').change(function() {
var $this = $(this);
$('div').filter('.'+$this.val()).show();
});

Is there a simple Javascript command that targets another object?

I have a page with two divs in it, one inside the other like so:
<div id='one'>
<div id='two'></div>
</div>
I want div one to change class when it is clicked on, then change back when div two is selected.
I'm completely new to javascript, but I've managed to find a simple command that makes div one change when I click it.
<div id='one' class='a' onclick="this.className='b';">
<div id='two'></div>
</div>
Now I just need an equally simple way to change div one back when number two is clicked.
I've tried changing "this.className" to "one.classname," and for some reason that worked when I was working with images, but it doesn't work at all with divs
<div id='one' class='a' onclick="this.className='b';">
<div id='two' onclick="one.className='a';">
This does not work.
</div>
</div>
Essentially I'm wondering if there is a substitute for the javascript "this" that I can use to target other elements.
I've found several scripts that will perform the action I'm looking for, but I don't want to have to use a huge, long, complicated script if there is another simple one like the first I found.
You can use document.getElementById
<div id='two' onclick="document.getElementById('one').className='a'; return false;">
This does not work.
</div>
This would work:
document.getElementById('one').className = 'a';
you could get the element by id with:
document.getElementById("one")

Categories

Resources