I am using this code to make stars light up when you hover over them(a rating system). It works absolutely perfectly in Chrome, but when I tried to use it in IE, it doesn't do anything. Can anyone help me make this work in IE? (Yes, I know the code looks horrible. I am very new to Javascript, which is probably why this bug is happening.) I am pretty sure it is coming from this part of the Javascript code making everything undefined:
var star_all = document.getElementsByName('stars');
for (x in star_all){
var stars = new Array();
stars[0]=childbyid(star_all[x], 'str1');
Anyways, here is all of the code:
HTML Code:
<div name="stars" class="stars">
<input name="bob" id="hid" type="hidden" />
<div id="str1" style="display: inline-block;" class="no_star"></div>
<div id="str2" style="display: inline-block;" class="no_star"></div>
<div id="str3" style="display: inline-block;" class="no_star"></div>
<div id="str4" style="display: inline-block;" class="no_star"></div>
<div id="str5" style="display: inline-block;" class="no_star"></div>
</div>
Javascript Code:
<script type="text/javascript">
function isElement(obj) {
try {
return obj instanceof HTMLElement;
}
catch(e){
return (typeof obj==="object") &&
(obj.nodeType===1) && (typeof obj.style === "object") &&
(typeof obj.ownerDocument ==="object");
}
}
function childbyid(el, str)
{
var children = el.childNodes;
for(i in children)
{
if (isElement(children[i]) === true && typeof children[i] != 'undefined')
{
if (children[i].getAttribute('id') == str)
{
return children[i];
}
}
}
}
var star_bob = new Array();
function select(arr, n)
{
star_bob[arr][2] = n;
star_bob[arr][1].setAttribute("value", n+1);
if (document.getElementById('star_post') != null)
{
document.getElementById('star_post').submit();
}
}
function highlight(arr, n)
{
if (n == -1)
{
n = star_bob[arr][2];
}
arr = star_bob[arr][0];
for (z in arr){
if (z <= n){
arr[z].setAttribute("class", "full_star")
}
else
{
arr[z].setAttribute("class", "no_star")
}
}
}
var star_all = document.getElementsByName('stars');
for (x in star_all){
var stars = new Array();
stars[0]=childbyid(star_all[x], 'str1');
stars[1]=childbyid(star_all[x], 'str2');
stars[2]=childbyid(star_all[x], 'str3');
stars[3]=childbyid(star_all[x], 'str4');
stars[4]=childbyid(star_all[x], 'str5');
for (o in stars){
if (typeof stars[o] != 'undefined')
{
stars[o].setAttribute("onmouseover", "highlight(" + x + ", " + o + ")")
stars[o].setAttribute("onmouseout", "highlight(" + x + ", -1)")
stars[o].setAttribute("onclick", "select(" + x + ", " + o + ")");
}
}
if (typeof star_all[x] == "object")
{
star_bob[x] = new Array(stars, childbyid(star_all[x],"hid"),-1);
}
}
</script>
You have a few issues:
div elements don't have a name attribute, so don't use it. If you want to group elements, use a class.
getElementsByName returns a live NodeList, better to iterate over it using indexes as it may have enumerable properties you aren't expecting.
the isElement test is rubbish, you are iterating over a NodeList so everything in it is a node. To filter elements, grab those with nodeType == 1. Browsers do not have to implement elements as ECMAScript objects, so don't expect them to.
Much better to put styles in a style sheet.
The childbyid function can be replaced by a single getElementById call since id's are unique (unless you are expecting the id to maybe not be where it should be).
Don't code HTML like it is XML, it isn't.
A replacement isElement function (cheap and nasty but effective for this case) :
function isElement(obj) {
return obj && obj.nodeType == 1;
}
A replacement childbyid function (seems pointless, should just use getElementById):
function childbyid(el, str) {
var children = el.childNodes;
var i = children.length;
while (i--){
if (children[i].id == str) {
return children[i];
}
}
}
Probably won't fix all your issues but might help. The entire thing needs to be re-written, and don't use jQuery or any other library, learn javascript first. Then you'll realise you don't need jQuery.
精彩评论