How do I change the ID of a HTML element with JavaScript? - javascript

I am modifying the ID of an HTML div element client side with JavaScript. The following code works OK in Internet Explorer but not in Firefox/2.0.0.20. It does work in more recent versions of Firefox.
document.getElementById('one').id = 'two';
Can anyone tell me:
Why this doesn't work in FireFox.
How to make this work in FireFox.
To clarify, I'm changing the element ID to reference a different style in an external style sheet. The style is applied in IE but not in FF.

It does work in Firefox (including 2.0.0.20). See http://jsbin.com/akili (add /edit to the url to edit):
<p id="one">One</p>
Link2
The first click changes the id to "two", the second click errors because the element with id="one" now can't be found!
Perhaps you have another element already with id="two" (FYI you can't have more than one element with the same id).

That seems to work for me:
<html>
<head><style>
#monkey {color:blue}
#ape {color:purple}
</style></head>
<body>
<span id="monkey" onclick="changeid()">
fruit
</span>
<script>
function changeid ()
{
var e = document.getElementById("monkey");
e.id = "ape";
}
</script>
</body>
</html>
The expected behaviour is to change the colour of the word "fruit".
Perhaps your document was not fully loaded when you called the routine?

You can modify the id without having to use getElementById
Example:
<div id="One" onclick="One.id = 'Two'; return false;">One</div>
You can see it here: http://jsbin.com/elikaj/1/
Tested with Mozilla Firefox 22 and Google Chrome 60.0

Related

What's the difference between how firefox clicks and chrome clicks?

I'm having to write a scraper using nightmare. On one the links the website is using a div for the user to navigate away from the page. In order to follow the navigation flow, I would like my nightmare instance to "click" the div. However, nothing happens when I'm on chrome, and obtain the element and call click. Unlike Firefox, where this works fine.
The script
let elem = document.getElementByClassName('is-a-div-element')[0];
elem.click()
Works fine on firefox, nothing happens on chrome! Any ideas? The site causing issue is using React. Not sure if that helps or not.
The HTML structure looks like this.
<div class="nav-element">
<div class="is-a-div-element">
<div roll="button">
<span roll="presentation">Hello World</span>
<span class="Exit">Exit</span>
</div>
</div>
</div>
I'm not sure how Nightmare relates to this issue since you mention Chrome and Firefox and appear to be using standard browser Javascript, but I'll try answer anyway.
Since you've edited your question with more specific information I'll edit my answer. Now the main issue I can see is that you're using getElementByClassName, which isn't a function (missing the s).
Do this instead:
let elem = document.getElementsByClassName('is-a-div-element')[0];
Tested working in Chrome and Firefox:
window.addEventListener('load', function() {
let elem = document.getElementsByClassName('is-a-div-element')[0];
elem.click();
});
<div class="nav-element">
<div class="is-a-div-element" onclick="alert('this was clicked frens');">
<div roll="button">
<span roll="presentation">Hello World</span>
<span class="Exit">Exit</span>
</div>
</div>
</div>

What does each line of this code do?

I'm new to Javascript coding and I've come across this TryIt page on w3schools. I understand that the code creates two buttons, which turn a bulb on and off when clicked, but I'd like some more detailed explanation from some Javascript experts on what each line in this code exactly does.
For example, does
<button onclick="document.getElementById('myImage').src='pic_bulbon.gif'">
just create a button and make the image titled bulbon.gif appear when clicked? I'm slightly confused. Here is the code:
<!DOCTYPE html>
<html>
<body>
<h2>What Can JavaScript Do?</h2>
<p>JavaScript can change HTML attributes.</p>
<p>In this case JavaScript changes the src (source) attribute of an image. </p>
<button onclick="document.getElementById('myImage').src='pic_bulbon.gif'">Turn on the light</button>
<img id="myImage" src="pic_bulboff.gif" style="width:100px">
<button onclick="document.getElementById('myImage').src='pic_bulboff.gif'">Turn off the light</button>
</body>
</html>
Thanks.
Let's have a look at the code :
onclick="document.getElementById('myImage').src='pic_bulbon.gif'"
OnClick bind an event on the button, which will be fired when the button is clicked.
There are various events, depending on the kind of element you are using. Like, onKeyUp, onKeyDown, onSelect etc
document.getElementById('myImage') tells the browser to retrieve the DOM element which ID is "myImage" (/!\ remember IDs must be unique in your code, if not the behaviour is unknown and your code won't work as expected. getElementsByName will give back an array with the DOM elements matching the given name. People tend to be confused between the 2 functions, yet pay attention at the ending S: getElement/getElements)
.src = "pic_bulbon.gif" replace the previously found element source with the new picture and so force the redraw of that element.
So, no it does not create a new element but change the property of an existing one

getElementsByClassName doesn't work properly at Element nodes [duplicate]

(I ask my question again after the first one was terribly formulated)
I face the following problem:
<div class="testA" id="test1"></div>
The above written element is predefined. I now load a xml tree via XMLHttpRequest & Co. delivering the following response:
<response>
<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>
</response>
I now append the first div using
request.responseXML.getElementsByTagName("response")[0]
.getElementsByTagName("div")[0]
into the predefined div
<div class="testA" id="test1">
The final document looks like this (checked using development tools):
<div class="testA" id="test1">
<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>
</div>
When I now try to get the element <div class="colorSelector" id="0-0"> using getElementById("0-0") I get the expected result.
But using getElementsByClassName("colorSelector") returns [].
Did I miss something? Is it probably a leftover of the fact the nodes were of type Element and not HTMLElement?
colorSelector is commented out. JavaScript only works within the DOM, and commented out portions aren't in the DOM.
Since you said that your getElementById("0-0") is successful, then clearly you don't actually have the nodes commented out.
I'm guessing you're doing:
document.getElementById("0-0").getElementsByClassName('colorSelector');
...which will not work because the element selected by ID does not have any descendants with that class.
Since you show HTML comments in the markup, I'd also wonder if you have some different element on the page with the ID "0-0". Take a look for that.
If your nodes are actually commented out, you'll need to first select the comment, and replace it with the markup contained inside:
var container = document.getElementById('test1'),
comment = container.firstChild;
while( comment && comment.nodeType !== 8 ) {
comment = comment.nextSibling;
}
if( comment ) {
container.innerHTML = comment.nodeValue;
}
...resulting in:
<div class="testA" id="test1">
<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>
</div>
...but there again, this doesn't seem likely since your getElementsById does work.
Here's a way to do it for Firefox, Opera, Chrome and Safari. Basically, you just do div.innerHTML = div.innerHTML to reinterpret its content as HTML, which will make that class attribute from the XML file be treated as an HTML class name.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<script>
window.addEventListener("DOMContentLoaded", function() {
var div = document.getElementsByTagName("div")[0];
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
var doc = this.responseXML;
div.appendChild(document.importNode(doc.getElementsByTagName("response")[0].getElementsByTagName("div")[0], true));
div.innerHTML = div.innerHTML;
alert(document.getElementsByClassName("colorSelector").length);
}
};
req.open("GET", "div.xml");
req.send();
}, false);
</script>
</head>
<body>
<div class="testA"></div>
</body>
</html>
Remove the this.status === 200 if you're testing locally in browsers that support xhr locally.
The importNode() function doesn't seem to work in IE (9 for example). I get a vague "interface not supported" error.
You could also do it this way:
var doc = this.responseXML;
var markup = (new XMLSerializer()).serializeToString(doc.getElementsByTagName("response")[0].getElementsByTagName("div")[0]);
div.innerHTML = markup;
as long as the markup is HTML-friendly as far as end tags for empty elements are concerned.
<!--<div class="colorSelector" id="0-0">
<div class="gbSelector" id="1-0">
<table style="none" id="2-0"></table>
</div>
</div>-->
The above code is gray for a reason: it's a comment. Comments aren't parsed by the browser at all and have no influence on the page whatsoever.
You'll have to parse the HTML, read the comments, and make a new DOM object with the contents of the comment.
Please describe what you are doing with the returned results. There is a significant difference between a nodeList and a node, nodeLists are LIVE.
So if you assign a nodeList returned by getElementsByClassName() (or similar) to a variable, this variable will change when you remove the nodes inside the nodeList from the DOM.
I now append the first div
How do you do that? What you have in the responseXML are XML elements, and not HTML elements.
You shouldn't be able to appendChild them into a non-XHTML HTML document;
actually you shouldn't be able to appendChild them into another document at all, you're supposed to use importNode to get elements from one document to another, otherwise you should get WRONG_DOCUMENT_ERR;
even if you managed to insert them into an HTML due to browser laxness, they're still XML elements and are not semantically HTML elements. Consequently there is nothing special about the class attributes; just having that name doesn't make the attribute actually represent a class. getElementsByClassName won't return elements just because they have attributes with the name class; they have to be elements whose language definition associates the attributes with the concept of classness (which in general means HTML, XHTML or SVG).
(The same should be true of the id attributes; just having an attribute called id doesn't make it conceptually an ID. So getElementById shouldn't be working. There is a way to associate arbitrary XML attributes with ID-ness, which you don't get with class-ness, by using an <!ATTLIST declaration in the doctype. Not usually worth bothering with though. Also xml:id is a special case, in implementations that support XML ID.)
You could potentially make it work if you were using a native-XHTML page by putting suitable xmlns attributes on the content to make it actual-XHTML and not just arbitrary-XML, and then using importNode. But in general this isn't worth it; it tends to be simpler to return HTML markup strings (typically in JSON), or raw XML data from which the client-side script can construct the HTML elements itself.

jQuery returning value 3 times in Chrome

I'm using jQuery to get the contents of a <strong> tag. A sample of the code is:
Trip ID: <strong name="tripID">10</strong>
...
<script type="text/javascript">
...
var tripID = $('strong[name=tripID]').text();
alert(tripID);
</script>
Firefox correctly alert()s "10". Chrome, however, alert()s "101010". Has anyone come across this or does anyone have any insights?
Edit
Changing the <strong name="tripID"> to a <span class="tripID" style="font-weight:bold;"> and changing the corresponding selector in my javascript made it work as expected. I'm still interested in what caused that behavior though!
Edit 2
I'm going to chock this up to some other part of my code interfering (it's a highly ajax-driven pages). Switching the <strong> to a <span> with a style applied corrected the issue, so I guess it's a non-problem now.
This seems to work just fine. Also as Jed asked, What's the strong tag?
http://jsfiddle.net/NiceGuy4263/MjGKL/
<span name="xxx"> is not standard. Try using <span id="xxx"> instead.
Do you mean
var tripID = $('strong[name=tripID]').text();
or
var tripID = $('span[name=tripID]').text();
jQuery returns all the elements $('span[name=tripID]') and foreach compute the text, so if you have 3 $('span[name=tripID]') all with 10 in it, it will return 101010.
I would suggest to give a class, or, even better, an ID
Trip ID: <span name="tripID" id="tripID">10</span>
...
<script type="text/javascript">
...
var tripID = $('#tripID').text();
alert(tripID);
</script>

jquery selectors problem and efficiency

Hi I have a problem(not exactly problem, I have solved it, but it is at least very interesting) with differet bahaviour of jquery selectors in IE(7-8) mobile Opera, and other browsers..
Here is my example
<div id="galleryEl"><link href="http://designclub.cz/plugins/content/plugin_jw_sig/sig.css" rel="stylesheet" type="text/css">
<style type="text/css">.sig_cont {width:30px;height:20px;}</style>
<script type="text/javascript" src="http://designclub.cz/plugins/content/plugin_jw_sig/mootools.js"></script>
<script type="text/javascript" src="http://designclub.cz/plugins/content/plugin_jw_sig/slimbox.js"></script>
<div class="sig"><div class="sig_cont"><div class="sig_thumb"><a href="http://designclub.cz/images/stories/hp/hp-falper.jpg" rel="lightbox[sig0]" title="<b>hp-falper.jpg</b>" alt="hp-falper.jpg" target="_blank"><img src="http://designclub.cz/plugins/content/plugin_jw_sig/showthumb.php?img=hp/hp-falper.jpg&width=0&height=0&quality=0">
Sorry about the formatting:)
The problem is following..When I use this selector jQuery("#galleryEl .sig_thumb a").eq(index); (index is really an integer) in major modern browsers it just works..
but in IE(7-9) (6 ia haven't tested) it doesn't..When I look into IE developer console, it looks like the result object is some kind of plain dom object???I am really not sure, not so skilled in js, but it seems so:)
When I change the jQuery(".sig_thumb a").eq(index); it selects the right dom element..The markup is so weird because of it's a joomla plugin, I am using it to dynamicaly creating background slideshows accroding to folder structure..So does anybody know wherefrom comes this weird behaviour?
And second question..I really want to make it efficient, so which kind of selector is the best one in this case?I know that when selecting over id, jQuery uses js native method, the same in case of tagName and so on, but I am really not sure how about the combinations if this selectors(whether is better to use id-tag-class-someOtherStuff, or id-class-someOtherStuff, id-someOtherStuff {in case that between id and the result object are many other DOM elements})
Thank for your help
Be sure that there is only 1 element with the ID "galleryEl" . If there are more than one, it depends on the IE-Version and the compatibility-mode if the first or the last be selected.
example for testing:
<script type="text/javascript">
jQuery(
function($)
{
alert('Found:'+jQuery("#someID .someclass").eq(1).text());
}
);
</script>
<div id="someID"><span class="someclass">1</span></div>
<div id="someID"><span class="someclass">2</span><span class="someclass">3</span></div>

Categories

Resources