jQuery child elements with same ID - javascript

Imagine that I have this HTML structure:
<div id="bodyRead">
...
<div id="List"></div>
</div>
...
<div id="bodyWrite">
...
<div id="List"></div>
</div>
As you can see, I have the #List inside two different divs (bodyRead and bodyWrite). For a lighter code, I preferred to work with id instead of class (even knowing that duplicate IDs isn't valid, the code makes more sense to me), and selecting the #List on jQuery like this:
$('#bodyRead #List').off('click').on('click', function() ...
$('#bodyWrite #List').off('click').on('click', function() ...
works. I'm always taking care of make duplicate IDs only on child divs, where I can separate them by their parent div on jQuery selector.
Is this approach very wrong? I mean, this can get me in trouble?

don't duplicate your Id even in child element .. change it to class="List"
then you can use
$('.List').on('click',function(){
var getparent = $(this).parent().attr('id');
alert(getparent);
});
and if class="List" not first level child of any of #bodyRead or #bodyWrite
add class to it
<div id="bodyRead" class="mainDiv">
<div id="bodyWrite" class="mainDiv">
and then use
$('.List').on('click',function(){
var getclosest = $(this).closest('.mainDiv').attr('id');
alert(getclosest);
});

You should expect that CSS and JavaScript (including jQuery and other frameworks) behave in accordance with the HTML specifications. ID must be unique, multiple instances of the same ID is not supported. See below:
From HTML 4.01 spec:
id = name [CS] This attribute assigns a name to an element. This name
must be unique in a document.
class = cdata-list [CS] This attribute
assigns a class name or set of class names to an element. Any number
of elements may be assigned the same class name or names. Multiple
class names must be separated by white space characters.
http://www.w3.org/TR/html401/struct/global.html#h-7.5.2
This is from the HTML 5 spec:
3.2.5.1 The id attribute
The id attribute specifies its element's unique identifier (ID). [DOM]
The value must be unique amongst all the IDs in the element's home
subtree and must contain at least one character. The value must not
contain any space characters.
There are no other restrictions on what form an ID can take; in
particular, IDs can consist of just digits, start with a digit, start
with an underscore, consist of just punctuation, etc.
An element's unique identifier can be used for a variety of purposes,
most notably as a way to link to specific parts of a document using
fragment identifiers, as a way to target an element when scripting,
and as a way to style a specific element from CSS.
Identifiers are opaque strings. Particular meanings should not be
derived from the value of the id attribute.

Well i feel this is a bad approach because the browser creates the DOM(document object model) for the page, which takes into consideration that each Id has a unique value.It would be hard to play with the duplicate Id's in javascript when you want to manipulate you need to consider parent as well as child id each time. So its better to use classes instead.

Although id selectors are meant to be unique your code will work as long as you make sure to use correct nesting. In other words #bodyRead #List and #bodyWrite #List are perfectly fine as long as you don't create ambiguity by leaving out the parent selectors to #List.
Still, using multiple identical ids on the same page is just asking for trouble. You should reconsider switching to class selectors or reevaluate if it is really worth the potential trouble of sticking with your original idea.

You certainly should not use duplicate id's in an html page. If you have a similar concept within two different div's then class makes more sense anyway. So change the List ids to classes and then you can access them like this:
$('#bodyRead .List').off('click').on('click', function() ...
$('#bodyWrite .List').off('click').on('click', function() ...
Even if your code works now due to how jQuery works, because the html specifications say not to do this, you can not know for certain that your code will continue to work in the future.

Related

JQuery "#id.class" Selector Mashup

I have some bullet points which I want to show more text below them on clicking them. They are both two separate Ps that are paired together by sharing a common id. So, what I am trying to do below is to find the element with (id_same_as_this.class), so that the element with the class "expand" as well as the id that matches the clicked on P is toggled. Does that make sense?
$(document).ready(function(){
$(".expandable").click(function(){
$(this.attr('id')+"."+"expand").toggle(800);
});
});
I only ask if the above code could be made to work because it would make the expandable bullet points in my web page significantly less code intensive than a lot of the examples I have read about.
$(this.attr('id')+"."+"expand").toggle(800);
Must be
$("#" + this.id +".expand").toggle(800);
You missed the # there. That said, you shouldn't ever have a common ID. By definition IDs are meant to be unique. If you have the same ID on multiple elements, while it may work now on the browsers you try, you have no guarantee it won't break in the next rev of jQuery (or Chrome, or Konqueror, or iOS Safari). There's also no reason to do it. You could just use classes or data-* attributes.
Yes this will work but you need a # before the ID
They are both two separate Ps that are paired together by sharing a common id.
IDs are unique. Two elements can't share a common ID, as that defeats the whole purpose of having a unique identifier. JavaScript assumes that you're using valid HTML, so document.getElementById() will return only the first element with a matching id. By using non-unique IDs, things will start breaking in unpredictable ways:
$('#foo').find('.bar') // Won't search past first #foo
$('#foo .bar') // Will search past first #foo in IE8+
Try restructuring your HTML to make this task easier. Maybe you could do something like this:
<ul id="bullets">
<li>
<h2>Title</div>
<div>Text</div>
</li>
</ul>
And then use a simple event handler:
$('#bullets h2').click(function() {
$(this).next().toggle(800);
});
You don't need id values for this at all (which is good, as from the comments on hungerpain's answer, you're using the same id value on more than one element, which is invalid).
Just do this:
$(document).ready(function(){
$(".expandable").click(function(){
$(this).find(".expand").toggle(800);
});
});
That will find the element with the class expand within the expandable that was clicked. No relying on unspecified behavior of selectors.
If you really need that data on the expandable, just put it in a data-* attribute. So instead of this invalid structure:
<!-- INVALID -->
<div id="foo27" class="expandable">
<div class="expand">...</div>
</div>
<div id="foo27" class="expandable">
<div class="expand">...</div>
</div>
Do this
<!-- VALID -->
<div data-id="foo27" class="expandable">
<div class="expand">...</div>
</div>
<div data-id="foo27" class="expandable">
<div class="expand">...</div>
</div>
Use the above code to do the expansion. If you need the value, use .attr("data-id") or .data("id") to get it.

How can I select an element by id and class in javascript?

I want to know if we can select an element by using its id and class at the same time. I know in css we can do that with #x.y, but but how can it be accomplished in javascript? I tried the following code and it worked fine but then all the controls with ui-slider-handle class got affected(which is obvious). I think I need a combination of id and class both so that only that particular element will be affected.
Javascript:
$(".ui-slider-handle").text(ui.value);
A combination of ID and class for selecting elements is useless as IDs are meant to be unique.
never have multiple identifiers with the same value in one page!
If you want multiple elements with the same attributes, use a class. If not, consider an ID or a class.
If you want to have a lot of elements with the same attributes, but one with extra attributes, you can give that one an ID and assign extra attributes to the ID
You will never need to do this since the ID is unique; if you know it, you can already identify the element.
Your problem is actually that your selector matches too many elements. There are other ways to limit the "range" of a selector:
Add a parent element with a certain ID/class: .parent .ui-slider-handle matches only elements with the class ui-slider-handle that are children of all elements with the class parent
You can also limit by parent type: div .ui-slider-handle
Or only direct children: div > .ui-slider-handle
See jQuery selectors for all the goodies.
Since ids should be unique, you should be able to do your selector by only id. If are wanting to apply the same attribute to multiple elements, then you should use a class. In your scenario it seems you should be fine with just using id like this:
$("#id").text(ui.value);
What you can write is:
$("#ID.ui-slider-handle").text(ui.value);
The string inside the quotes is a normal CSS selector, which supports both classes and ids. However, the above code is redundant and slow, and unless you want to select that particular id only if it has a certain class, it would be preferable to write:
$("#ID").text(ui.value);

How to get element from template by javascript?

I dont know good method how to get DOM element from template by javascript.
Example template:
<script id = "template" type="text/template">
<div>text1</div>
<div>text2</div>
<div>text3</div>
</script>
For example i want get div with "text2"
There is ways which i know, all of them are bad:
Add "class" to all elements - it breaks semantics (class created for CSS). In big projects you must use very long names for classes, its very inconvenient.
Get element by his number (index) - when adding a new element, you must rewrite old numbers in your code.
I see a couple of options:
If you don't want to use class , you can use a data-* attribute.
Assuming you load the template once and then duplicate its contents as desired, you could put id values on the elements in the template, which you then remove when cloning them and adding them to the document (so you don't end up with the same id on more than one copy of the element, which would be invalid and probably counterproductive).
Maybe you can also create as many templates as you need.
One for each div.
If you need to get each div at a time you must set ids to them ... of course you can also browse the dom inside script element to find the one you're interested in ...
Home this helps
Regards
mimiz

Jquery doesn't apply hide() to all of the divs with the same ID

I'm making a site, and the html is displayed through php with data fetched from a database.
I have a foreach() function, so all of the things displayed have the same DIV ID's.
It ends up being like 4 DIVs with the same ID (#content), so the PHP works fine, but I have a jQuery script and when I call the jQuery("#content").hide(); it only hides ONE of the DIV's not all of them, and I want it to hide all of them. Is there something else I have to do?
Thanks.
You should use a class (.class_name), not an id--only one DOM element may have a given ID, otherwise it's invalid HTML. It's reasonable for an ID selector to return only a single element.
IDs on elements on a page should be unique. So every HTML tag you specify should have a different ID. If you want to hide all of a certain element, it might be suitable to add a class to the elements you wish to hide?
e.g.
<div class="divToHide">Content...</div>
<div class="divToHide">Content...</div>
<div class="divToHide">Content...</div>
Then your jquery would be:
$(".divToHide").hide();
That's simply because you cannot have more than one element with a specified ID. IDs are and must be unique. Only one single element with the same element may exist in a DOM.
Failing to follow this rule may result in broken scripts and other horrors.
You can use classes for this purpose.
an ID can only be used ONCE in HTML! because its a id and a id should always be Unique

repeating id's of element children

Is it ok to have id names for children of an element the same as the ids of children of another element provided the parent id is different? Any potential conflict?
No, element ids should be unique throughout the entire document. document.getElementById() won't work right with duplicate ids (obviously, as it only returns one element). Now your page will probably work fine with the duplicate ids, it's not like the browser will crash or refuse to render the page or anything, but it's not correct HTML.
If you need non-unique identifiers use the class attribute. That's exactly what it's for, to tag multiple elements with the same name.
Read the spec:
This attribute [id] assigns a name to an element.
This name must be unique in a document.
It is very bad practice and likely to cause errors. A better solution would be to use classes to distinguish the child objects and then descend from the parent ID to locate the element you are looking for.
The ID should always be unique regardless in the context of HTML or Javascript. You are much better off with an unique identifier. For example, you have multiple elements with id named "foo"; in document.getElementById("foo") will only return the first instance by that id.
If you've got different DOM elements with the same ID, it will lead to troubles at some point... don't do it even thought it might work.

Categories