This doesn't work
var name= "#443.selected:first";
selectedEntity = $(name).attr('entityId');
This works
var name= "li.selected:first";
selectedEntity = $(name).attr('entityId');
selectedEntity is undefined but an element does exist with id="443" class="selected".
Why doesn't the first example work?
You can use the attribute selector:
$('[id="443"].selected:first')
See this jsFiddle demo
Though in HTML other than HTML5 IDs which start with a number are not allowed, your selector should work (working Demo). You must have an error elsewhere in your code and/or markup.
There are several issues you should address:
IDs must be unique otherwise your HTML is invalid
overqualifying the ID-Selector is bad for performance and due to 1) even not necessary
ID-Selectors only return the first element so using :first is useless (and also affected by point 1)
Don't use custom attributes like entityId. Instead use the data- prefix. Then you can use jQuerys data method to get/set those attributes. (Beware however that you cannot use camelCase).
Related
How can I get a collection of elements by specifying their id attribute? I want to get the name of all the tags which have the same id in the html.
I want to use ONLY getElementById() to get an array of elements. How can I do this?
I know this is an old question and that an HTML page with multiple identical IDs is invalid. However, I ran into this issues while needing to scrape and reformat someone else's API's HTML documentation that contained duplicate IDs (invalid HTML).
So for anyone else, here is the code I used to work around the issue using querySelectorAll:
var elms = document.querySelectorAll("[id='duplicateID']");
for(var i = 0; i < elms.length; i++)
elms[i].style.display='none'; // <-- whatever you need to do here.
The HTML spec requires the id attribute to be unique in a page:
[T]he id attribute value must be unique amongst all the IDs in the element's tree
If you have several elements with the same ID, your HTML is not valid.
So, document.getElementById should only ever return one element. You can't make it return multiple elements.
There are a couple of related functions that will return a list of elements: getElementsByName or getElementsByClassName that may be more suited to your requirements.
Why you would want to do this is beyond me, since id is supposed to be unique in a document. However, browsers tend to be quite lax on this, so if you really must use getElementById for this purpose, you can do it like this:
function whywouldyoudothis() {
var n = document.getElementById("non-unique-id");
var a = [];
var i;
while(n) {
a.push(n);
n.id = "a-different-id";
n = document.getElementById("non-unique-id");
}
for(i = 0;i < a.length; ++i) {
a[i].id = "non-unique-id";
}
return a;
}
However, this is silly, and I wouldn't trust this to work on all browsers forever. Although the HTML DOM spec defines id as readwrite, a validating browser will complain if faced with more than one element with the same id.
EDIT: Given a valid document, the same effect could be achieved thus:
function getElementsById(id) {
return [document.getElementById(id)];
}
document.querySelectorAll("#yourId"); returns all elements whose id is yourId
It is illegal to have multiple elements with the same id. The id is used as an individual identifier. For groups of elements, use class, and getElementsByClassName instead.
The id is supposed to be unique, use the attribute "name" and "getelementsbyname" instead, and you'll have your array.
As others have stated, you shouldn't have the same ID more than once in your HTML, however... elements with an ID are attached to the document object and to window on Internet Explorer. Refer to:
Do DOM tree elements with ids become global variables?
If more than one element with the same ID exists in your HTML, this property is attached as an array. I'm sorry, but I don't know where to look if this is the standard behavior or at least you get the same behavior between browsers, which I doubt.
Class is more than enough for refering anything you want, because it can have a naming with one of more words:
<input class="special use">
<input class="normal use">
<input class="no use">
<input class="special treatment">
<input class="normal treatment">
<input class="no special treatment">
<input class="use treatment">
that's the way you can apply different styles with css (and Bootstrap is the best example of it) and of course you may call
document.getElementsByClassName("special");
document.getElementsByClassName("use");
document.getElementsByClassName("treatment");
document.getElementsByClassName("no");
document.getElementsByClassName("normal");
and so on for any grouping you need.
Now, in the very last case you really want to group elements by id. You may use and refer to elements using a numerically similar, but not equal id:
<input id=1>
<input id="+1">
<input id="-1">
<input id="1 ">
<input id=" 1">
<input id="0x1">
<input id="1.">
<input id="1.0">
<input id="01.0">
<input id="001">
That way you can, knowing the numeric id, access and get an element by just adding extra non-invalidating numeric characters and calling a function to get (by parsing and so on) the original index from its legal string identifying value. It is useful for when you:
Have several rows with similar elements and want to handle its events
coherently. No matter if you delete one or almost all of them.
Since numeric reference is still present, you can then reuse them and
reassign its deleted format.
Run out of class, name and tagname identifiers.
Although you can use spaces and other common signs even when it's a not a requirement strictly validated in browsers, it's not recommended to use them, specially if you are going to send that data in other formats like JSON. You may even handle such things with PHP, but this is a bad practice tending to filthy programming practices.
This is my solution:
<script type="text/javascript">
$(document).ready(function () {
document.getElementsByName("mail")[0].value = "ex_mail1";
document.getElementsByName("mail")[1].value = "ex_mail2";
});
</script>
Or you can use for-loop for that.
You shouldn't do that and even if it's possible it's not reliable and prone to cause issues.
Reason being that an ID is unique on the page. i.e. you cannot have more than 1 element on the page with the same ID.
you can use
document.document.querySelectorAll("#divId")
we can use document.forms[0].Controlid
If you're using d3 for handling multiple objects with the same class / id
You can remove a subset of class elements by using d3.selectAll(".classname");
For example the donut graph here on http://medcorp.co.nz utilizes copies of an arc object with class name "arc" and there's a single line of d3, d3.selectAll(".arc").remove(); to remove all those objects;
using document.getElementById("arc").remove(); only removes a single element and would have to be called multiple times (as is with the suggestions above he creates a loop to remove the objects n times)
Here is a piece of code
<span class="balance themecolor" data-balance="2800">
I'm looking for a way to extract the value of data-balance and set it as variable x, but I have absolutely no idea how to do it. I know of the existence of .val() but I don't know if I can apply it to this code. I'm looking a for a one line long solution.
If you're using jQuery (as you've mentioned .val()):
var x = $("[data-balance]").attr("data-balance");
Or if you aren't:
var x = document.querySelector("[data-balance]").getAttribute("data-balance");
In both cases, the [data-balance] is a CSS selector for the element; adjust as needed. For instance, with that element, and assuming no other elements with either of its classes, you could use .balance, .themecolor, or even .balance.themecolor.
jQuery will find all elements matching the selector (you can change that if it's an issue, usually it isn't), but then only give you the attribute value for the first one.
querySelector will stop with the first one. If you want to find them all and get a list, use querySelectorAll (and then index into it to get the individual ones).
I'm sorry,I can't believe this question is not solved in stackoverflow but I've been searching a lot and I don't find any solution.
I want to change HTML code with regular expressions in this way:
testing anchor
to
testing anchor
Only I want to unlink a text code without use DOM functions, the code is in a string not in the document and I don't want to remove other tags that the a ones.
If you really don't want to use DOM functions (why ?) you might do
str = str.replace(/<[^>]*>/g, '')
You can use it if you're fairly confident you don't have a more complex HTML but it will fail in many cases, for example some nested tags, or > in an attribute. You might fix some of the problems with more complex regular expressions but they aren't the right tool for this job in the general case.
If you don't want to remove other tags than a, do this :
str = str.replace(/<\/?a( [^>]*)?>/g, '')
This changes
<a>testing</a> <b>a</b>nchor<div>test</div><aaa>E</aaa>
to
testing <b>a</b>nchor<div>test</div><aaa>E</aaa>
I know you only want regex, for future viewers, here is a trivial solution using DOM methods.
var a = document.createElement("div");
a.innerHTML = 'testing anchor';
var wordsOnly = a.textContent || a.innerText;
This will not fail on complicated use cases, allows nested tags and it's perfectly clear what's happening:
Hey browser! Create an element
Put that HTML in it
Give me back just the text, that's what I want now.
NOTE:
The element we're creating will not be added to the actual DOM since we're not adding it anywhere, it'll stay invisible. Here is a fiddle to illustrate how this works.
As has been mentioned, you cannot parse HTML with regular expressions. The principal reason is that HTML elements nest and regular expressions cannot handle that.
That said, with a few restrictions which I will mention, you can do the following :
string.replace (/(\b\w+\s*)<a\s+href="([^"]*)">(.*)<\/a>/g, '$1 $3')
This requires there to be a word before the tag, spacing between the word and the tag is optional, no attributes other than the href specified in the <a> tag and you accept anything between the <a> and the .
You can create a DOM object from the string, use DOM methods to parse, without having had appended said DOM object to the document
If an html element id has no period in it, then copying between elements is of course trivial, e.g.:
var theForm = document.paymentForm;
theForm.BillStreet1.value = theForm.ShipStreet1.value;
I've got a case where I need to have period in my ids, namely id="bill.street1" and id="ship.street1", and the following doesn't work :-(
theForm.bill.street1.value = theForm.ship.street1.value;
Can you please let me know how to handle the period? Does jquery make this simpler?
jQuery makes everything simplier by using css selectors to access elements. However, if you don't want to use jQuery, you can access the element this way, I believe.
theForm['bill.street1'].value = theForm['ship.street1'].value;
I haven't tested this, but it should work because periods are an alternate method to access an array, iirc.
Be sure to use theForm['bill.street1'].value = theForm['ship.street1'].value;
and not theForm.['bill.street1'].value = theForm.['ship.street1'].value;. The extra periods make the format invalid, in the same way using array.[2] instead of array[2] would invalidate it.
theForm['bill.street1'].value
theForm['ship.street1'].value
Here is my code:
var CDs=$(xml).find("CDs");
var NthChild = $(CDs).find("CD:nth-child(index)"); // nth-child 0th element starts at 1
I'm using the find method here; I have to specify the child node name, which is noted as "CD". Is there are a faster or shorter method, perhaps one that doesn't need me to specify the name of the child node (i.e. "CD") to find the nth child node?
Thank you.
UPDATE
I found a format that doesn't need to specify the child node by name:
var NthChild = $(CDs).children(":nth-child(index)");
$(xml).find("CDs CD").eq(index);
According to jQuery docs
Because :eq() is a jQuery extension and not part of the CSS
specification, queries using :eq() cannot take advantage of the
performance boost provided by the native DOM querySelectorAll()
method. For better performance in modern browsers, use
$("your-pure-css-selector").eq(index) instead.
$(xml).find("CDs CD:eq(0)")
Put the desired index inside of the parens following eq
Or, if CD elements only live under CDs and you aren't worried about getting the wrong ones:
$(xml).find("CD:eq(0)")