EDIT: Ok, so I approached the problem the wrong way: to do what I intended to, I just needed to check if there was an overflow.
Here is the code (if it can help anyone):
<script type="text/javascript">
function textfit(){
var spans = document.body.getElementsByTagName("span");
for(var i = 0, l = spans.length; i < l; i++){
var span = spans[i];
var font = window.getComputedStyle(span, null).getPropertyValue('font-size');
var fontSize = parseInt(font);
do {
span.style.fontSize = (fontSize --) + "px";
} while (span.scrollHeight > span.clientHeight || span.scrollWidth > span.clientWidth);
}
}
$(document).ready(function() {
textfit();
});
</script>
OLD POST:
My problem is simple: I have a HTML page with a lot of span but not all of them have the same content. Regarding that, I want to adapt the fontsize of each content to fit perfectly its span; please note that I don't want to cut the textcontent, or add dots if it's too long, I just want to modify the fontSize.
JS:
function = textfit(){
var spans = document.body.getElementsByTagName("span");
for(var i = 0, l = spans.length; i < l; i++){
var maxHeight = spans[i].offsetHeight;
var maxWidth = spans[i].offsetWidth;
var textHeight = $(spans[i].textContent).height();
var textWidth = $(spans[i].textContent).width();
var fontSize = spans[i].style.fontSize;
do {
fontSize = fontSize - 1;
} while (textHeight > maxHeight || textWidth > maxWidth);
}
}
$(document).ready(function() {
textfit();
});
HTML/CSS:
<style>
span{
display: inline-block;
width: 100px;
height: 100px;
font-size: 20pt;
}
</style>
......
<body>
<div>
<span>SMALL</span>
<span>MEEEEEEEEEEEEEDIUM</span>
<span>HUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUGE</span>
</div>
</body>
As you may see, I'm using a "for" to run through every span and a "do...while" to adjust the font size of each of them.
My problems:
it looks like I'm not able to get the textcontent size (getting a "null" instead)
same thing with the fontsize (I'm getting an empty string)
Or maybe I'm approaching the problem the wrong way and I need to do it differently...
NB: JS are a little bit "new" for me so sorry if I did rookie mistakes
you are reseting a local variable by fontSize = fontSize - 1;, on a related note, textHeight and textWidth will not be update automatically by changing the fontsize, they are local variables.
On the other hand, you will need to wrap your texts in an additional element to be able to measure its dimensions.
<style>
.wrapper{
display: inline-block;
width: 100px;
height: 100px;
font-size: 20pt;
}
</style>
......
<body>
<div>
<span class='wrapper'><span>SMALL</span></span>
<span class='wrapper'><span>MEEEEEEEEEEEEEDIUM</span></span>
<span class='wrapper'><span>HUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUGE</span></span>
</div>
</body>
JS:
function = textfit(){
var spans = document.body.getElementsByClassName("wrapper");
for(var i = 0, l = spans.length; i < l; i++){
var span = spans[i];
var maxHeight = span.offsetHeight;
var maxWidth = span.offsetWidth;
var fontSize = parseInt(span.style.fontSize);
do {
var textHeight = span.firstChild.offsetHeight();
var textWidth = span.firstChild.offsetWidth();
span.style.fontSize = (fontSize --)+"pt";
} while (textHeight > maxHeight || textWidth > maxWidth);
//PS I suggest a binary-search-like algorithm to save time
}
}
$(document).ready(function() {
textfit();
});
Related
I am making a text editor, and here is the code:-
const editor = document.querySelector('#ta');
const lc = document.querySelector('#line-count');
var lcDiv = document.createElement('p');
var calculateContentHeight = function( ta, scanAmount ) {
var origHeight = ta.style.height,
height = ta.offsetHeight,
scrollHeight = ta.scrollHeight,
overflow = ta.style.overflow;
/// only bother if the ta is bigger than content
if ( height >= scrollHeight ) {
/// check that our browser supports changing dimension
/// calculations mid-way through a function call...
ta.style.height = (height + scanAmount) + 'px';
/// because the scrollbar can cause calculation problems
ta.style.overflow = 'hidden';
/// by checking that scrollHeight has updated
if ( scrollHeight < ta.scrollHeight ) {
/// now try and scan the ta's height downwards
/// until scrollHeight becomes larger than height
while (ta.offsetHeight >= ta.scrollHeight) {
ta.style.height = (height -= scanAmount)+'px';
}
/// be more specific to get the exact height
while (ta.offsetHeight < ta.scrollHeight) {
ta.style.height = (height++)+'px';
}
/// reset the ta back to it's original height
ta.style.height = origHeight;
/// put the overflow back
ta.style.overflow = overflow;
return height;
}
} else {
return scrollHeight;
}
}
var calculateHeight = function() {
var ta = document.getElementById("ta"),
style = (window.getComputedStyle) ?
window.getComputedStyle(ta) : ta.currentStyle,
// This will get the line-height only if it is set in the css,
// otherwise it's "normal"
taLineHeight = parseInt(style.lineHeight, 10),
// Get the scroll height of the textarea
taHeight = calculateContentHeight(ta, taLineHeight),
// calculate the number of lines
numberOfLines = Math.ceil(taHeight / taLineHeight);
for(let i = 1; i < numberOfLines; i++){
lcDiv = document.createElement('p');
lcDiv.id = 'lcDiv';
lcDiv.innerHTML = i;
lc.appendChild(lcDiv);
}
};
calculateHeight();
if (ta.addEventListener) {
ta.addEventListener("mouseup", calculateHeight, false);
ta.addEventListener("keyup", calculateHeight, false);
} else if (ta.attachEvent) { // IE
ta.attachEvent("onmouseup", calculateHeight);
ta.attachEvent("onkeyup", calculateHeight);
}
#ta{
resize: none;
width: 95%;
line-height: 5vh;
height: 90vh;
background-color :#4C5760;
color: #EFD09E;
font-size: 5vh;
float: left;
}
#line-count{
float: left;
}
<div id="line-count"></div>
<textarea id="ta"></textarea>
I had expected that it will add line numbers when a new line is formed. But it seems that it is not going beyond 1 and the process repeats when I add letters. Can anyone fix this problem.
I expect that it'll show line numbers in a usual way like text editors like Atom, Visual Studio Code, etc.
Help and answers accepted.
You need to clear your #line-count every time you call the calculateHeight()
const editor = document.querySelector('#ta');
const lc = document.querySelector('#line-count');
var lcDiv = document.createElement('div');
var calculateContentHeight = function(ta, scanAmount) {
var origHeight = ta.style.height,
height = ta.offsetHeight,
scrollHeight = ta.scrollHeight,
overflow = ta.style.overflow;
/// only bother if the ta is bigger than content
if (height >= scrollHeight) {
/// check that our browser supports changing dimension
/// calculations mid-way through a function call...
ta.style.height = (height + scanAmount) + 'px';
/// because the scrollbar can cause calculation problems
ta.style.overflow = 'hidden';
/// by checking that scrollHeight has updated
if (scrollHeight < ta.scrollHeight) {
/// now try and scan the ta's height downwards
/// until scrollHeight becomes larger than height
while (ta.offsetHeight >= ta.scrollHeight) {
ta.style.height = (height -= scanAmount) + 'px';
}
/// be more specific to get the exact height
while (ta.offsetHeight < ta.scrollHeight) {
ta.style.height = (height++) + 'px';
}
/// reset the ta back to it's original height
ta.style.height = origHeight;
/// put the overflow back
ta.style.overflow = overflow;
return height;
}
} else {
return scrollHeight;
}
}
var calculateHeight = function() {
var ta = document.getElementById("ta"),
style = (window.getComputedStyle) ?
window.getComputedStyle(ta) : ta.currentStyle,
// This will get the line-height only if it is set in the css,
// otherwise it's "normal"
taLineHeight = parseInt(style.lineHeight, 10),
// Get the scroll height of the textarea
taHeight = calculateContentHeight(ta, taLineHeight),
// calculate the number of lines
numberOfLines = Math.ceil(taHeight / taLineHeight);
lc.innerHTML = "";
for (let i = 1; i < numberOfLines; i++) {
lcDiv = document.createElement('p');
lcDiv.id = 'lcDiv';
lcDiv.innerHTML = i;
lc.appendChild(lcDiv);
}
};
calculateHeight();
if (ta.addEventListener) {
ta.addEventListener("mouseup", calculateHeight, false);
ta.addEventListener("keyup", calculateHeight, false);
} else if (ta.attachEvent) { // IE
ta.attachEvent("onmouseup", calculateHeight);
ta.attachEvent("onkeyup", calculateHeight);
}
#ta {
resize: none;
width: 95%;
line-height: 5vh;
height: 90vh;
background-color: #4C5760;
color: #EFD09E;
font-size: 5vh;
float: left;
}
#line-count {
float: left;
}
#line-count p {
margin: 0;
font-size: 5vh;
}
<div id="line-count"></div>
<textarea id="ta"></textarea>
I have some articles on the block. Some of them cut in the middle of their hight like on the picture:
I tried to fix this problem by using the function below, but it still doesn't work.
const setSameHeightToAll = function() {
const all = document.querySelectorAll('.text_blog')
let maxHeight = 0
var length = all.length
for (var i = 0; i < length; i++) {
if (all[i].getBoundingClientRect().height > maxHeight) {
maxHeight = all[i].getBoundingClientRect().height
}
}
for (var j = 0; j < length; j++) {
all[j].setAttribute('style', 'height:' + maxHeight + 'px')
}
}
in html:(this is pug.js)
.text_blog
!= post.content.full
p.read_more
a(href='/blog/'+post.key) leia mais >>
this is css:
.text_blog {
overflow: hidden;
height: 112px;
}
How can I change my function to work correctly.
You're setting the max-height to 0 in your javascript code.
Not knowing the full context of your code, because you only posted the javascript part, You may either have a constant height for all '.text_blog' elements or use
CSS
.text_blog{
height: auto;
overflow: scroll;
}
OR
JAVASCRIPT
const setSameHeightToAll = function() {
const all = document.querySelectorAll('.text_blog')
//GET HEIGHT OF FIRST ELEMENT AND MAKE IT UNIFORM
let maxHeight = all.firstElementChild.offsetHeight;
//SET CONSTANT HEIGHT
let maxHeight = '500px';
var length = all.length;
for (var i = 0; i < length; i++) {
all[i].setAttribute('style', 'height:' + maxHeight + 'px')
}
}
You are also forgetting to include the closing ';' at the end of some lines.
I'm trying to practice my scripting by making a Battleship game. As seen here.
I'm currently trying to make the board 2D. I was able to make a for-loop in order to make the board, however, due to testing purposes, I'm just trying to make the board, upon clicking a square, it turns red... But, the bottom square always lights up. I tried to debug it by making the c value null, but then it just stops working. I know it's not saving the c value properly, but I'm wondering how to fix this.
Do I have to make 100 squares by my self or can I actually have the script do it?
maincansize = 400;
document.getElementById("Main-Canvas").style.height = maincansize;
document.getElementById("Main-Canvas").style.width = maincansize;
document.getElementById("Main-Canvas").style.position = "relative";
var ize = maincansize * .1;
for (var a = 0; a < 10; a++) {
for (var b = 0; b < 10; b++) {
var c = document.createElement("div");
var d = c;
c.onclick = function() {
myFunction()
};
function myFunction() {
console.log("A square was clicked..." + c.style.top); d.style.backgroundColor = "red";
}
c.style.height = ize;
c.style.width = ize;
c.style.left = b * ize;
c.style.top = a * ize;
c.style.borderColor = "green";
c.style.borderStyle = "outset";
c.style.position = "absolute";
console.log(ize);
document.getElementById('Main-Canvas').appendChild(c);
} //document.getElementById('Main-Canvas').innerHTML+="<br>";
}
#Main-Canvas {
background-color: #DDDDDD;
}
<div>
<div id="header"></div>
<script src="HeaderScript.js"></script>
</div>
<div id="Main-Canvas" style="height:400;width:400;">
</div>
Here's your code with some fixes:
adding 'px' to style assignment
passing the clicked element to myFunction
var maincansize = 400;
document.getElementById("Main-Canvas").style.height = maincansize;
document.getElementById("Main-Canvas").style.width = maincansize;
document.getElementById("Main-Canvas").style.position = "relative";
var ize = maincansize * .1;
for (var a = 0; a < 10; a++) {
for (var b = 0; b < 10; b++) {
var c = document.createElement("div");
c.onclick = function(ev) {
myFunction(ev.currentTarget);
};
function myFunction(el) {
console.log("A square was clicked...");
el.style.backgroundColor = "red";
}
c.style.height = ize+'px';
c.style.width = ize+'px';
c.style.left = (b * ize)+'px';
c.style.top = (a * ize)+'px';
c.style.borderColor = "green";
c.style.borderStyle = "outset";
c.style.position = "absolute";
document.getElementById('Main-Canvas').appendChild(c);
}
}
#Main-Canvas {
background-color: #DDDDDD;
}
<div id="Main-Canvas" style="height:400;width:400;">
</div>
Here's a solution with major revamps. Since you're using a set width for the container element of your board cells you can float the cells and they will wrap to the next line. Absolute positioning tends to be a bit of a bugger. If you want 10 items per row it's as easy as:
<container width> / <items per row> = <width>
Using document fragments is faster than appending each individual element one at a time to the actual DOM. Instead you append the elements to a document fragment that isn't a part of the DOM until you append it. This way you're doing a single insert for all the cells instead of 100.
I moved some of the styling to CSS, but could easily be moved back to JS if you really need to.
function onCellClick() {
this.style.backgroundColor = 'red';
console.log( 'selected' );
}
var main = document.getElementById( 'board' ),
frag = document.createDocumentFragment(),
i = 0,
len = 100;
for ( ; i < len; i++ ) {
div = document.createElement( 'div' );
div.addEventListener( 'click', onCellClick, false );
frag.appendChild( div );
}
main.appendChild( frag );
#board {
width: 500px;
height: 500px;
}
#board div {
float: left;
box-sizing: border-box;
width: 50px;
height: 50px;
border: 1px solid #ccc;
}
<div id="board"></div>
Thanks to a really helpful user on this website (whose name I do not know, but I wish to thank and credit him!), I got the following tip on how to store area elements in an array so that when I mouse over a coordinate, I could display all of the overlay id's of the area elements that existed at that coordinate (even if the area elements were not at the same z-level):
I'm just stuck on one thing- once I have gathered all the elements that exist at the coordinate in the hoveredElements array, how do I show their overlay ids?
EDIT:
Here is an example of the full code (the overlay still does not display when I mouse over)
The file test.txt contains:
cscCSL1A15 700 359 905 318
cscCSL1A14 794 400 905 318
I use the maphilight plugin available online, and blanketaphi.png is the plot I use as a background.
<!DOCTYPE html>
<html>
<head>
<title>Detector Elements</title>
<script type="text/javascript"
src="Demo_imagemap_highlight_files/jquery-1.js"></script>
<!-- add maphilight plugin -->
<script type="text/javascript"
src="Demo_imagemap_highlight_files/jquery_002.js"></script>
</head>
<body>
<div class="content">
<div class="map"
style='display: block; background: transparent
url("Demo_imagemap_highlight_files/blanketaphi.png")
repeat scroll 0% 0%; position: relative; padding: 0px; width: 1037px;
height: 557px;'>
<canvas width="1037" height="557" style="width: 1037px; height: 557px;
position: absolute; left: 0px; top: 0px; padding: 0px; border: 0px none;
opacity: 1;"></canvas>
<img style="opacity: 0; position: absolute; left: 0px; top: 0px; padding: 0px;
border: 0px none;" src="Demo_imagemap_highlight_files/blanketaphi.png"
alt="foo" class="map maphilighted" usemap="#demo" height="557" width="1037"
border="0" />
</div>
</div>
<map name="demo" id="demo"></map>
</body>
</html>
<script type="text/javascript">
window.onload = function(){
var f = (function(){
var xhr = [];
var files = [ "test.txt"];
for (i = 0; i < 1; i++) {
(function (i){
xhr[i] = new XMLHttpRequest();
xhr[i].open("GET", files[i], true);
xhr[i].onreadystatechange = function () {
if (xhr[i].readyState == 4 && xhr[i].status == 200) {
// get text contents
j=20000*i + 50000;
var coords = xhr[i].responseText.split("\n");
coords = coords.filter(Boolean) //prevents extra rect with 0 coords
coords.forEach(function(coord) {
var area = document.createElement("area");
var att = document.createAttribute("data-maphilight");
if (i == 0) { //green
att.value = '{"strokeColor":"000000","strokeWidth":2,' +
'"fillColor":"009900","fillOpacity":0.5}';
}
area.setAttributeNode(att);
area.id = "r"+j;
area.shape = "rect";
area.coords = coord.substring(10,coord.length).trim()
.replace(/ +/g,","); // replaces spaces in txt file with commas
area.href = "#";
area.alt = "r"+j;
// create overlay with first term in string
var div = document.createElement("div");
div.id ="overlayr"+j;
div.innerHTML = coord.substring(0,10);
div.style.display = "none";
//increase j
j++;
// get map element
document.getElementById("demo").appendChild(area);
document.getElementById("demo").appendChild(div);
});
$('.map').maphilight();
//display overlay ids by mousing over
var elementPositions = [];
var hoveredElements = [];
if($('#demo')) {
$('#demo area').each(function() {
var offset = $(this).offset();
var top = offset.top;
var left = offset.left;
var bottom = $(window).height() - top - $(this).height();
var right = $(window).width() - left - $(this).width();
elementPositions.push({
element: $(this),
top: top,
bottom: bottom,
left: left,
right: right
});
//alert(top + "," + left + "," + right + "," + bottom);
});
$("body").mousemove(function(e) {
hoveredElements = [];
var yPosition = e.pageX;
var xPosition = e.pageY;
for (var i = 0; i < elementPositions.length; i++) {
if (xPosition >= elementPositions[i].left &&
xPosition <= elementPositions[i].right &&
yPosition >= elementPositions[i].top &&
yPosition <= elementPositions[i].bottom) {
// The mouse is within the element's boundaries
$("#hovers").append(elementPositions[i].element);
}
}
for (var i = 0; i < hoveredElements.length; i++) {
// The element as a jQuery object
var elem = hoveredElements[i];
var id = hoveredElements[i].attr('id');
$('#overlay'+id).show();
}
});
};
}
};
xhr[i].send();
})(i);
}
})();
};
</script>
Why not just something like this:
var elementPositions = [];
var hoveredElements = [];
if($('#demo')) {
$('#demo area').each(function() {
var offset = $(this).offset();
var top = offset.top;
var left = offset.left;
var bottom = $(window).height() - top - $(this).height();
var right = $(window).width() - left - $(this).width();
elementPositions.push({ element: $(this), top: top, bottom: bottom, left: left, right: right });
//alert(top + "," + left + "," + right + "," + bottom);
});
$("body").mousemove(function(e) {
hoveredElements = [];
var yPosition = e.pageX;
var xPosition = e.pageY;
for (var i = 0; i < elementPositions.length; i++) {
if (xPosition >= elementPositions[i].left &&
xPosition <= elementPositions[i].right &&
yPosition >= elementPositions[i].top &&
yPosition <= elementPositions[i].bottom) {
// The mouse is within the element's boundaries
hoveredElements.push(elementPositions[i].element);
$("#hovers").append(elementPositions[i].element);
}
} //end of for loop over all elements
console.log(hoveredElements);
for (var i = 0; hoveredElements.length; i++)
{ //for loop over all hovered elements
// The element as a jQuery object
var elem = hoveredElements[i];
var id = hoveredElements[i].attr('id');
console.log(id);
$('#overlay'+id).show();
// Do stuff to that jQuery element:
//??? something like elem.show();
}
You've got a lot of stuff here that doesn't make sense to me but here's what I can gather so far.
Your areas need to be in a container called demo area. Not sure how the space in the ID works so in my case I switched it to demoarea. Also somewhere in the page, there has to be another element called demo for anything to even happen.
Once that's done, the script loads demoarea into the elementPositions array. Judging from your description that's not what you want to do, you probably want to load all the elements inside demoareainto the array. So the first change is
$('#demo area').each(function() {
Becomes
$('#demoarea').children().each(function() {
Now what becomes confusing to me is that this script for whatever reason decides that you need to have another element called hover so it can move the element out of demoarea into hover when you mouse over it. If that is what you want, then you can do your show trick with some simple CSS.
<div style="display:none" id="overlayr6064"> Example Overlay ID name </div>
Becomes
<div id="overlayr6064"> Example Overlay ID name </div>
And then you add:
<style>
#demoarea div {
display: none;
}
#hover div {
display: block;
}
</style>
Assuming that is not what you wanted, what #liamEgan did to add the elements to the hoveredElements array is good, but you have an infinite loop here
for (var i = 0; hoveredElements.length; i++)
it should be
for (var i = 0; i < hoveredElements.length; i++)
Then the rest works... except one last thing, you want to load these listeners to your script when the page loads in a document ready method.
So in all it looks a bit like:
//display overlay ids by mousing over (my map is called 'demo')
var elementPositions = [];
var hoveredElements = [];
if($('#demo')) {
$('#demoarea').children().each(function() {
var offset = $(this).offset();
var top = offset.top;
var left = offset.left;
var bottom = $(window).height() - top - $(this).height();
var right = $(window).width() - left - $(this).width();
elementPositions.push({ element: $(this), top: top, bottom: bottom, left: left, right: right });
});
console.log('After Scanning demoarea elementPositions looks like:')
console.log(elementPositions);
$(document).ready(function () {
$("body").mousemove(function(e) {
hoveredElements = [];
var yPosition = e.pageX;
var xPosition = e.pageY;
for (var i = 0; i < elementPositions.length; i++) {
if (xPosition >= elementPositions[i].left &&
xPosition <= elementPositions[i].right &&
yPosition >= elementPositions[i].top &&
yPosition <= elementPositions[i].bottom) {
// The mouse is within the element's boundaries
if (typeof elementPositions[i].element != "undefined") {
hoveredElements.push(elementPositions[i].element);
$("#hovers").append(elementPositions[i].element);
}
}
} //end of for loop over all elements
for (var i = 0; i < hoveredElements.length; i++) { //for loop over all hovered elements
// The element as a jQuery object
console.log(hoveredElements[i]);
if (typeof hoveredElements[i] != "undefined") {
var elem = hoveredElements[i];
var id = elem.attr('id');
$('#overlay'+id).show();
}
// Do stuff to that jQuery element:
//??? something like elem.show();
}
});
});
}
#demoarea {
border: 2px blue dotted;
}
/* Border added so I can see where to mouse over */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="demo">
<div id="demoarea">
<area shape="rect" coords="431,499,458,491" href="#" id="r6064" alt="r6064">
<div style="display:none" id="overlayr6064"> Example Overlay ID name </div>
</div>
<div id="hovers">
</div>
</div>
Edit: sorry I added the undefined tests while fixing this because of the infinite loop but I think they're not really needed. Still nice to have though. Also since the area also gets moved into the hover area this script does try to show an element called overlayoverlayr6064r6064 which fortunately doesn't exist. But ya, again, probably not what you had in mind.
On my previous post I asked how I'd get the gradient set up. Now the problem is that the gradient "spreads" out. Here's What I'm using
function generateCSSGradient(colours) {
var l = colours.length, i;
for( i=0; i<l; i++) colours[i] = colours[i].join(" ");
return "linear-gradient( to right, "+colours.join(", ")+")";
}
var cols = [
["red","0%"],
["red","40%"],
["yellow","40%"],
["yellow","60%"],
["green","60%"],
["green","80%"]
];
yourElement.style.background = generateCSSGradient(cols);
With this. What I want to do is say you fill in one input. And the bar goes to 33%, then that could be a red color. Then the next would be a blue and so fourth. Not like this. Any ideas? I'd also avoid using div
I think you want it like this ... See the source code
HTML
I'v edited the HTML code and added another div called colors inside the div top ...
<div class="top">
<div class="colors"></div>
</div>
CSS
Also I edited the CSS of .top and added to it overflow:hidden; and create .colors style
.top{
/*background: #009dff;*/
background:linear-gradient(to right,#009dff 0,#00c8ff 100%);
position:fixed;
z-index:1031;
top:0;
left:0;
height:4px;
transition:all 1s;
width:0;
overflow: hidden;
}
.colors{
width: 100%;
height: 4px;
}
JavsScript
Then edited the JavaScript and made the CSSGradient to colors not top , and let the JavaScript set the width of colors to fit the window width , and changed the colors percentage..
document.querySelector(".colors").style.background = generateCSSGradient(cols);
var window_width = window.innerWidth + "px";
document.querySelector(".colors").style.width = window_width;
var cols = [
["red","0%"],
["red","33.3%"],
["yellow","33.3%"],
["yellow","66.6%"],
["green","66.6%"],
["green","100%"]
];
Hope this will help you ...
Update
if you want to change the color of the bar like this , See the source code ...
just edit the JavaScript to be like this
function cback(e) {
var t = [];
for (var n = inputs.length; n--;) {
if (!inputs[n].value.length) t.push(inputs[n]);
}
var r = t.length;
var i = inputs.length;
var s = document.querySelectorAll(".top");
for (var o = s.length; o--;) {
s[o].style.width = 100 - r / i * 100 + "%";
s[o].style.background = cols[i-r-1];
}
}
var forms = document.querySelectorAll(".form"),
inputs = [];
for (var i = forms.length; i--;) {
var els = forms[i].querySelectorAll("input, textarea, select");
for (var j = els.length; j--;) {
if (els[j].type != "button" && els[j].type != "submit") {
inputs.push(els[j]);
els[j].addEventListener("input", cback, false);
}
}
}
var cols = ["red","yellow","green"];