Finding part of a string using javascript
I have the following HTML set
<input name="1" title="" id="1" style="position: absolute; top: 333px; left: 760px; tabindex: 11; z-order: 99;" type="checkbox" CHECKED="checked" runat="server" value="on"/>
I want to get the value specified for tabindex
inside the attribute style
above. Things to note:
-
I know what
tabindex
is in the wrong place (it shouldn't be in the attribute textstyle
, it should be an attribute on its own). I cannot change this, it is done with a (very old) tool that I cannot change. -
I need to support IE8, and when I tried I ran into an issue where IE8 was not handling correctly
\s
in regexes (it doesn't match hard space ).
I tried to use .search()
for this, but I don't know how to return a string value when I search for my checkbox with the following string:
var test = document.getElementsByTagName("input");
The goal is to grab the value tabindex
from the attribute style
and then assign it to the element correctly.
source to share
Updated answer :
Your comment:
I know it's in the wrong place, but I can't manually move it.
So why are we using a regular expression, getcha.
So, we have two tasks:
-
Get the attribute text
style
, which should be simple but silly hard for IE8. -
Get the value
tabindex
from this text.
First, getting the style attribute text: Unfortunately, by default IE8 will render "intranet" sites in a ridiculously "unnamed" compatibility view. (That is: Compatible with old broken IE7 and earlier, not standards compliant.) And IE7 and earlier had a terrible bug: element.getAttribute("style")
provided you with an object style
, not a style attribute text; the same object you get with element.style
. Although they fixed it in IE8, it is broken in the compatibility view (to be ... "compatible").
So this:
var text = element.getAttribute("style"):
... will give us a string on any decent browser and on IE8 if not in compatibility view, but will give us an object when compatibility is shown.
So, to get the text, we have to look elsewhere. Fortunately, it was Microsoft who chose innerHTML
and outerHTML
, therefore, we can do this:
var text = element.getAttribute("style"):
if (typeof text !== "string") {
text = element.outerHTML;
}
This gives us more than just style text, of course, but it's close enough. We're still not trying to parse HTML with a regex (although we're pushing it a bit outerHTML
, but input
rightfully so), we're looking for a limited thing in a limited string.
Now from this text, we need a tabindex value: this expression matches tabindex
(case insensitive), followed by a space, :
followed by a space, followed by some number of digits, which we capture:
/\btabindex\s*:\s*(\d+)/i
We can then use a capture group to grab the value from the wrong location and set it in the right place:
var element = document.getElementById("1");
var text = element.getAttribute("style");
if (typeof text !== "string") {
// Bad IE! Bad!
text = element.outerHTML;
}
var match = /\btabindex\s*:\s*(\d+)/i.exec(text);
var index = match && match[1];
if (index) {
element.setAttribute("tabindex", index);
}
alert("Index: " + (index || "unknown"));
Live example:
var element = document.getElementById("1");
var text = element.getAttribute("style");
if (typeof text !== "string") {
// Bad IE! Bad!
text = element.outerHTML;
}
var match = /\btabindex\s*:\s*(\d+)/i.exec(text);
var index = match && match[1];
if (index) {
element.setAttribute("tabindex", index);
}
alert("Index: " + (index || "unknown"));
<input name="1" title="" id="1" style="position: absolute; top: 333px; left: 760px; tabindex: 11; z-order: 99;" type="checkbox" CHECKED="checked" runat="server" value="on"/>
Your comment:
But would the above work if I changed the first line to
document.getElementsByTagName("input");
Of course, you just do it in a loop:
var list, index, element, text, match;
list = document.getElementsByTagName("input");
for (index = 0; index < list.length; ++index) {
element = list[index];
text = element.getAttribute("style");
if (typeof text !== "string") {
// Bad IE! Bad!
text = element.outerHTML;
}
match = /\btabindex\s*:\s*(\d+)/i.exec(text);
tabindex = match && match[1];
if (tabindex) {
element.setAttribute("tabindex", tabindex);
}
}
(I named tabindex tabindex
there, since loop indices are often named index
.)
Original answer :
Yours tabindex
is in the wrong place: it's not a style property, it's a standalone attribute:
<input name="1" title="" id="1" tabindex="11" style="position: absolute; top: 333px; left: 760px; z-order: 99;" type="checkbox" CHECKED="checked" runat="server" value="on"/>
<!-- Here ----------------------^ -->
Then use the property tabindex
reflected:
var index = document.getElementById("1").tabIndex;
Live example:
alert(document.getElementById("1").tabIndex);
<input name="1" title="" id="1" tabindex="11" style="position: absolute; top: 333px; left: 760px; z-order: 99;" type="checkbox" CHECKED="checked" runat="server" value="on"/>
Side note: although in HTML, values id
starting with numbers are very difficult to work with in CSS; it is best to avoid them.
source to share
Never parse HTML elements with a regular expression. See this question for some fun .
If you have an HTML element, you can access all of its attributes either through .getAttribute
, or in the case of CSS style attributes, using for example .style.top
for attribute top
.
The problem in your case is probably that you are putting your property tabindex
on a style attribute. According to this page , you have to set it as a separate attribute to get it afterwards
document.getElementById("1").getAttribute("tabindex");
source to share