I am trying to make a bookmarklet that will return a user id for a website i am registered for. When logged into the website there is a piece of code as follows:
<input id="memberID" name="00V85345345343ugFFC" type="hidden" value="3959721"/>
This is the JavaScript i am using but it doesnt do anything. AmI doing something wrong here?
javascript:alert("Your member ID is\n"+document.getElementById("memberID")[0].value);
document.getElementById returns a HTMLElement or null if no element was found matching that ID.
Because element ID's are supposed to be unique, it makes no sense to return an Array; a maximum of one element should be matched.
javascript:alert("Your member ID is\n"+document.getElementById("memberID").value);
document.getElementsByTagName however, for example (note the plural of elements, rather than element), returns an array of elements; as it makes perfect sense to have more than one element of the same tag in a page.
var divElements = document.getElementsByTagName("div");
if (divElements.length) {
var firstElement = divElements[0];
};
getElementById returns single element, not array of elements.
So this:
getElementById("memberID")[0].value
Must become just:
getElementById("memberID").value
Maby this will help abit in cleaning up that error:
http://p-xr.com/jquery-like-getelementbyid-in-1-line-of-code/
Related
I'm trying to make a little interactive gallery in which people could check/select some picures. I used some to contain the pictures and add some in there to indicate selected photographs. Then I typed a little JS code to check or uncheck photographs using the className of the .
So my two problems are :
The code doesn't run as expected. Can't select any picture when I'm runnin' my navigator.
The console only returns "undefinded" as explain in the code below.
Here's some code :
It's kind of my first attempt in JS and I don't really understand what isnt's not working so I hope you'll got an answer or at least some little indications for me. :)
Thanks,
Thomas
As mentioned in previous answers the getElementsByClassName method returns a HTMLCollection of elements that have the class name that you pass to the method. If you need to access any of the items, you will need to do it like an array.
For example, getting the first element of the collection.
unselectedClass[0].className;
Otherwise you could use a for loop to access each element in the collection.
for (var i = 0; i < unselectedClass.length; i++) {
var class = unselectedClass[i].className;
}
getElementsByClassName yields a collection of elements. The className property is available on a specific element in that list. Not on the list itself.
The problem is that document.getElementsByClassName returns HTMLCollection and HTMLCollection. You should check the className of its elements.
You can loop through it then get className of each element
for(let i = 0;i<unslectedClass.length;i++){
console.log(unselectedClass[i].className);
}
Or convert the HTMLCollection to a real array using Spread Operator and use forEach()
[...unselectedClass].forEach(x => console.log(x.className))
I am currently trying to figure out a way to get the ID of an element, depending on whether its class contains something. I'm not sure if there's a better way to do it than I currently am, but having looked around nothing fits exactly the need I have. The code I currently have is, where I am looking for a div element whose class contains the string "one" but is not limited to that. Currently there is only one element containing this string but the alert provides me with [Object NodeList] (I may well be overcomplicating this):
$idToMove = document.querySelectorAll('div[class^="one"]');
alert($idToMove);
document.querySelectorAll() Returns a node list (kind of like an array), if you are sure there will only ever be one you have a couple options.
1) Use .querySelector instead:
// returns the first node that matches
var elm = document.querySelector('div[class~="one"]');
console.log(elm.id);
2) Access the first element in the returned list:
// returns all nodes that match
var elms = document.querySelectorAll('div[class~="one"]');
console.log(elms[0].id);
Make sure to null check returns of .querySelector and length check returns of .querySelectorAll.
Notice also, that I use ~= and not ^=. You can read on the MDN about the difference between all the equality operators. But for these two:
[attr~=value]
Represents an element with an attribute name of attr whose value is a whitespace-separated list of words, one of which is exactly "value".
[attr^=value]
Represents an element with an attribute name of attr and whose first value is prefixed by "value".
First get element from DOM and than from that element get id attribute:
1- If you need only first element then use querySelector like this:
let elms = document.querySelector('div[class~="one"]')[0].id
console.log(elms)
2- If you need all element those have this class then use querySelectorAll like this:
let elms = document.querySelectorAll('div[class~="one"]')
for(let i=0; i<elms.length; i++)
{
console.log(elms[i].id)
}
I think with "*" it works in more cases
document.querySelector('div[class*="words"]')
i tried it works absolutely amazing
window.frames[0].document.querySelector('td[id*="sss"]')
When using jQuery how does one return to navigating the DOM. For example, if I found the parent of an item like this:
$(this).parent()
How can you find something with an id of 'foobar'.
I've tried:
$(this).parent().$('foobar').addClass('hello')
But I get the message:
Uncaught TypeError: Object [object Object] has no method '$'
IDs must be unique, for selecting an element by ID you can use ID selector $('#foobar'), however if you want to find an element within the parent element you can use find method:
$(this).parent().find('#foobar').addClass('hello');
Which is the same as:
$('#foobar').addClass('hello');
Note that if you are using an ID for several elements, your document is invalid, you should use classes instead.
$(this).parent().find('.foobar').addClass('hello');
while id should be unique, so that you can just document.getElementById("foobar") I have had to find multiple occurrences before and used this:
/* returns an array of all elements with id */
function getElementsById(id){
var t=document.getElementsByTagName("*"),a=[]
for(var i=0;i<t.length;i++)
if(t[i].id==id)a[a.length]=t[i]
return a
}
Note: if you are writing new code, classes have a builtin getElementsByClassName (because it is expected to have multiples)
Edit: this could be reduced to document.querySelectorAll("#id")
I know that if we want to find a group of elements, getElementsByTagName is the method for us and it returns a NodeList. but if we are looking for tag name with "body" , then why we need to add [0] after the ("body") element? There is only one body tag in an HTML document.
var body = document.getElementsByTagName("body")[0];
body.className = "unreadable";
why we cant write this code without index[0] like this
var body = document.getElementsByTagName("body");
body.className = "unreadable";
If i write this code the class unreadable will not be added with body tag ...why?
Because document.getElementsByTagName allways returns NodeList. If you want find easier way to retrieve body you can use just document.body
getElementsByTagName returns a NodeList. It might have no items in it. It might have one. It might have many. You can see how many are in it by testing its .length.
It would be confusing if it sometimes returned a NodeList and sometimes returned an ElementNode.
getElementsByTagName [docs] always returns a NodeList. It does not matter whether an element with a certain tag exists only once.
It would be bad if the function behaved inconsistently.
I got a div, and there i got some childnodes in undefined levels.
Now I have to change the ID of every element into one div. How to realize?
I thought, because they have upgoing IDs, so if the parent is id='path_test_maindiv' then the next downer would be 'path_test_maindiv_child', and therefore I thought, I'd solve that by wildcards, for example:
document.getElementById('path_test_*')
Is this possible? Or are there any other ways?
Not in native JavaScript. You have various options:
1) Put a class and use getElementsByClassName but it doesn't work in every browser.
2) Make your own function. Something like:
function getElementsStartsWithId( id ) {
var children = document.body.getElementsByTagName('*');
var elements = [], child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (child.id.substr(0, id.length) == id)
elements.push(child);
}
return elements;
}
3) Use a library or a CSS selector. Like jQuery ;)
In one of the comments you say:
(...) IE is anyway banned on my page, because he doesn't get it with CSS. It's an admin tool for developer, so only a few people, and they will anyway use FF
I think you should follow a different approach from the beginning, but for what it's worth, in the newer browsers (ok, FF3.5), you can use document.querySelectorAll() with which you can get similar results like jQuery:
var elements = document.querySelectorAll('[id^=foo]');
// selects elements which IDs start with foo
Update: querySelectorAll() is only not supported in IE < 8 and FF 3.0.
jQuery allows you to find elements where a particular attribute starts with a specific value
In jQuery you would use
$('[id^="path_test_"]')
Try this in 2019 as a wildcard.
document.querySelectorAll("[id*=path_test_]")
I don't think so wildcards are allowed in getelementById.
Instead you can have all the child nodes of your respective DIV using:
var childNodeArray = document.getElementById('DIVID').childNodes;
This'll give you an array of all elements inside your DIV. Now using for loop you can traverse through all the child elements and simultaneously you can check the type of element or ID or NAME, if matched then change it as you want.
You should not change ID of element to ID of other existing element. It's very wrong, so you better re-think your core logic before going on.
What are you trying to do exactly?
Anyway, to get all elements with ID starting with something, use jQuery as suggested before, if you can't it's also possible using pure JavaScript, let us know.