0 前言
在 完善JavaScript代码,给水果随机赋色 _PurpleEndurer@5lcto的技术博客_51CTO博客 中,我们使用系统随机数来生成随机的颜色代码来赋予用户输入的水果 ,增加了网页的视觉效果和灵动性。
同时我们也提出了另一种给水果有序赋色的方法:
添加一个颜色数组来存放一些预定义好的颜色,然后按照水果在列表的顺序依次赋予颜色,当颜色使用到数组的最后一个元素后又重头开始使用,这样虽然不同的水果可能会具有相同的颜色,但水果列表中水果名称将以具有一定顺序规律的颜色来显示,从用户的角度看起来,也是令人赏心悦目的。
现在我们就来改进代码,实现给水果有序赋色。
1 选择颜色表示方法
在 完善JavaScript代码,给水果随机赋色 _PurpleEndurer@5lcto的技术博客_51CTO博客 中,我们介绍了网页中表示颜色的三种方法。这三种方法都可以存储到数组中,并且具有不同的优点和缺点。
对于使用颜色名称的英文单词表示这种方式,优点是看名字就能识别颜色,缺点是在 W3C 的 HTML 4.0 标准中只支持 16 种颜色名,数量较少。
对于使用RGB格式 和 在css中使用HSL 这两种表示颜色的方法, 优点是可以表示的颜色数量非常多,缺点就是不够直观,不能直接识别出对应的颜色。
2 改进代码,给水果有序赋色
我们以 用HTML DOM实现有条件地渲染网页元素(下)_PurpleEndurer@5lcto的技术博客_51CTO博客中的代码:
<script>
function showFruit(e)
{
//var oUL = document.getElementById('ulFruit');
//alert(oUL.childElementCount);
var coLi = document.getElementById('ulFruit').children;
//alert(coLi.length);
for (var i = 0; i < coLi.length; i++)
{
//alert(coLi[i].title);
coLi[i].style.display = (e.target.value==coLi[i].innerText ? "list-item" : "none");
} // for
} // showFruit(v)
var aFruits = new Array(['苹果', 'Apple', 'red'],
['桔子', 'Orange', 'orange'],
['葡萄', 'Grape', 'purple'],
['芒果','Mango','yellow'],
['其它', 'Other', 'blue']);
function genFruitOption()
{
var oDivFruit = document.getElementById('divFruit');
oDivFruit.innerHTML = '';//清空原有水果选项
var oP;//<p>对象
var oIn;// <input>对象
var oLa;// <label>对象
for (var i=0; i<aFruits.length; i++)
{
//创建<p>
oP = document.createElement("P");
//创建<input type="raido">
oIn = document.createElement("input");
oIn.type = 'radio'; //类型
oIn.name = "fruit"; //
oIn.id = 'ra' + aFruits[i][1]; //id
oIn.value = aFruits[i][0]; //值
oIn.addEventListener("click", showFruit); //增加click事件监听器
//创建<label>
oLa = document.createElement('label')
oLa.htmlFor = 'ra' + aFruits[i][1];
oLa.appendChild(document.createTextNode(aFruits[i][0]));
//向<div>容器追加网页元素<P><input><label>对象
oDivFruit.appendChild(oP);
oDivFruit.appendChild(oIn);
oDivFruit.appendChild(oLa);
} //for
} //genFruitOption()
function genFruitLi()
{
var oUL = document.getElementById('ulFruit');
oUL.innerHTML = ''; //清空原有水果列表项
var oLi;
//添加水果列表项
for (var i=0; i<aFruits.length; i++)
{
oLi = document.createElement("li");
oLi.appendChild(document.createTextNode(aFruits[i][0]));
oLi.style.color = aFruits[i][2]; //设置颜色
oUL.appendChild(oLi);
} //for
} //genFruitLi()
function addFruit()
{
//获取用户添加的水果名称
var sFruit = document.getElementById('itFruit').value;
//aFruits.unshift([sFruit, ('fruit'+aFruits.length) , 'black']);//把用户添加的水果名称加入数组头部,成为第1个元素
aFruits.push([sFruit, ('fruit'+aFruits.length) , 'black']);//把用户添加的水果名称加入数组尾部,成为最后一个元素
genFruitOption();//更新用户可选水果的列表
genFruitLi(); //更新展示用户选择水果的列表
}
</script>
<p>用JavaScript响应click事件有条件地渲染网页元素</p>
<p>(允许用户添加自己喜欢的水果)</p>
<p style="margin-left:20%; color:purple; font-weight:bold;">
by PurpleEndurer
</p>
<p>你喜欢哪种水果?</p>
<div id="divFruit">
<script>
genFruitOption();
</script>
</div>
<p style="color:#0033ff">
温馨提示:如果以上没有您喜欢的水果,您可以输入和添加喜欢的水果名称到列表中:
<input type="text" id="itFruit" value="水果名称" />
<input type="button" value="添加" onclick="addFruit()" />
</p>
<p>你喜欢的是:</p>
<ul id="ulFruit">
<script>
genFruitLi();
</script>
</ul>
为基础进行改进。
2.1 定义颜色数组
我们选择 使用颜色名称的英文单词表示这种方式 来进行演示。
我们定义一个名为aColors的数组,数组的元素就是W3C 的 HTML 4.0 标准中所支持 16 种颜色名的英文单词,由于网页背景色一般默认为白色(white),所以我们水果名称使用白色来显示的话,就看不出来,所以我们把数组中的"while"注释掉,这样aColors数组包含15个元素,包括了除了白色外的其余15种颜色。
const aColors = new Array("aqua", //浅绿色
"black", //黑色
"blue", //蓝色
"fuchsia", //紫红色
"gray", //灰色
"green", //绿色
"lime", //酸橙色
"maroon", //栗色
"navy", //海军蓝
"olive", //橄榄色
"purple", //紫色
"red", //红色
"silver", //银色
"teal", //蓝绿色
//"white", //白色
"yellow" //黄色
);
2.2 修改aFruits数组
在原始的aFruits数组中:
var aFruits = new Array(['苹果', 'Apple', 'red'],
['桔子', 'Orange', 'orange'],
['葡萄', 'Grape', 'purple'],
['芒果','Mango','yellow'],
['其它', 'Other', 'blue']);
每行存储一种水果信息,其中最后一个元素存储的是水果的颜色,我们是直接指定了颜色,比如‘red''purple'等。
现在我们定义了 颜色数组aColors,那么我们从头开始就使用颜色数组aColors中的颜色来作为水果的颜色 ,用aColors[0]代替'red',用用aColors[1]代替'orange'……
替换完成后的aFruits数组代码如下:
var aFruits = new Array(['苹果', 'Apple',aColors[0]],
['桔子', 'Orange', aColors[1]],
['葡萄', 'Grape', aColors[2]],
['芒果','Mango',aColors[3]],
['其它', 'Other', aColors[4]]);
2.3 修改 addFruit函数
原先的addFruit函数代码如下:
function addFruit()
{
//获取用户添加的水果名称
var sFruit = document.getElementById('itFruit').value;
//aFruits.unshift([sFruit, ('fruit'+aFruits.length) , 'black']);//把用户添加的水果名称加入数组头部,成为第1个元素
aFruits.push([sFruit, ('fruit'+aFruits.length) , 'black']);//把用户添加的水果名称加入数组尾部,成为最后一个元素
genFruitOption();//更新用户可选水果的列表
genFruitLi(); //更新展示用户选择水果的列表
}
其中:
aFruits.push([sFruit, ('fruit'+aFruits.length) , 'black']);//把用户添加的水果名称加入数组尾部,成为最后一个元素
在这行代码的功能是我们是把用户输入的水果名称加入水果信息数组aFruits的末尾,其中指定水果颜色是'black'(黑色),现在我们要把'black' 改为 颜色数组 aColors中的颜色名称aColors[x]。
这样修改的话,对于其中用来选择颜色的数组下标x,我们还需要考虑两个问题。
第一个问题,x的值是多少?也就是说, 我们要如何来计算它的值呢?
由于我们是从头开始就使用颜色数组aColors中的颜色来作为水果的颜色,用户输入的水果将会加入到数组aFruits的末尾,那么我们可以使用数组aFruits的长度(aFruits.length)作为x的值。
第二个问题,当水果数组aFruits的元素个数超过 颜色数组aColors的元素个数怎么办?
例如, 颜色数组aColors的元素个素是15个(数组下标取值范围是0~14),对于水果数组aFruits的第16个元素,它的颜色怎么获取呢?
我们可以重头开始使用数组aColors的颜色。
如何实现使用到数组aColors的最后一个颜色后又从头开始呢?我们可以使用%进行取模运算(取余运算),比如:14%15=14, 15%15=0,16 %15=1。
这样,我们计算aColors[x]中x值的表达式为:aFruits.length % aColors.length。
因此,我们把 'black'修改为 aColors[ aFruits.length % aColors.length ]。
进行以上改造后的addFruit函数代码如下:
function addFruit()
{
//获取用户添加的水果名称
var sFruit = document.getElementById('itFruit').value;
/*
//把用户添加的水果名称加入数组头部,成为第1个元素
aFruits.unshift([sFruit, //水果名称
('fruit'+aFruits.length) , //id
aColors[aFruits.length % aColors.length ] //颜色
]);
*/
//把用户添加的水果名称加入数组尾部,成为最后一个元素
aFruits.push([sFruit, //水果名称
('fruit'+aFruits.length), //id
aColors[ aFruits.length % aColors.length ] //颜色
]);
genFruitOption();//更新用户可选水果的列表
genFruitLi(); //更新展示用户选择水果的列表
}
2.4 修改网页元素描述代码
我们需要修改3个地方。
2.4.1 修改技术改进说明
即将
<p>(允许用户添加自己喜欢的水果)</p>
改为
<p>(允许用户添加自己喜欢的水果并依次赋色)</p>
为了方便查看代码运行的效果,我们还要修改 用户可选水果列表 和 显示用户选择结果的水果名称列表 ,为两个水果列表设置长度、宽度,并使用滚动条。
2.4.2 修改用户可选水果列表
将
<p>你喜欢哪种水果?</p>
<div id="divFruit">
改为
<p>你喜欢哪种水果?</p>
<div id="divFruit" style="height:200px; width:300px; overflow-y:auto;">
在这里,我们通过 style属性指定列表的高度(height)为200象素,宽度(width)为300象素,垂直滚动条(overflow-y)根据需要显示(auto)。
2.4.3 修改显示用户选择结果的水果名称列表
我们参照 2.4.2 修改用户可选水果列表 来 修改显示用户选择结果的水果名称列表,即将:
<p>你喜欢的是:</p>
<ul id="ulFruit">
改为
<p>你喜欢的是:</p>
<ul id="ulFruit" style="height:200px; width:300px; overflow-y:auto;">
3 改造后的最终代码
综合以上修改后的最终代码如下:
<script>
function showFruit(e)
{
//var oUL = document.getElementById('ulFruit');
//alert(oUL.childElementCount);
var coLi = document.getElementById('ulFruit').children;
//alert(coLi.length);
for (var i = 0; i < coLi.length; i++)
{
//alert(coLi[i].title);
coLi[i].style.display = (e.target.value==coLi[i].innerText ? "list-item" : "none");
} // for
} // showFruit(v)
const aColors = new Array("aqua", //浅绿色
"black", //黑色
"blue", //蓝色
"fuchsia", //紫红色
"gray", //灰色
"green", //绿色
"lime", //酸橙色
"maroon", //栗色
"navy", //海军蓝
"olive", //橄榄色
"purple", //紫色
"red", //红色
"silver", //银色
"teal", //蓝绿色
//"white", //白色
"yellow" //黄色
);
var aFruits = new Array(['苹果', 'Apple',aColors[0]],
['桔子', 'Orange', aColors[1]],
['葡萄', 'Grape', aColors[2]],
['芒果','Mango',aColors[3]],
['其它', 'Other', aColors[4]]);
function genFruitOption()
{
var oDivFruit = document.getElementById('divFruit');
oDivFruit.innerHTML = '';//清空原有水果选项
var oP;//<p>对象
var oIn;// <input>对象
var oLa;// <label>对象
for (var i=0; i<aFruits.length; i++)
{
//创建<p>
oP = document.createElement("P");
//创建<input type="raido">
oIn = document.createElement("input");
oIn.type = 'radio'; //类型
oIn.name = "fruit"; //
oIn.id = 'ra' + aFruits[i][1]; //id
oIn.value = aFruits[i][0]; //值
oIn.addEventListener("click", showFruit); //增加click事件监听器
//创建<label>
oLa = document.createElement('label')
oLa.htmlFor = 'ra' + aFruits[i][1];
oLa.appendChild(document.createTextNode(aFruits[i][0]));
//向<div>容器追加网页元素<P><input><label>对象
oDivFruit.appendChild(oP);
oDivFruit.appendChild(oIn);
oDivFruit.appendChild(oLa);
} //for
} //genFruitOption()
function genFruitLi()
{
var oUL = document.getElementById('ulFruit');
oUL.innerHTML = ''; //清空原有水果列表项
var oLi;
//添加水果列表项
for (var i=0; i<aFruits.length; i++)
{
oLi = document.createElement("li");
oLi.appendChild(document.createTextNode(aFruits[i][0]));
oLi.style.color = aFruits[i][2]; //设置颜色
oUL.appendChild(oLi);
} //for
} //genFruitLi()
function addFruit()
{
//获取用户添加的水果名称
var sFruit = document.getElementById('itFruit').value;
/*
//把用户添加的水果名称加入数组头部,成为第1个元素
aFruits.unshift([sFruit, //水果名称
('fruit'+aFruits.length) , //id
aColors[aFruits.length % aColors.length ] //颜色
]);
*/
//把用户添加的水果名称加入数组尾部,成为最后一个元素
aFruits.push([sFruit, //水果名称
('fruit'+aFruits.length), //id
aColors[ aFruits.length % aColors.length ] //颜色
]);
genFruitOption();//更新用户可选水果的列表
genFruitLi(); //更新展示用户选择水果的列表
}
</script>
<p>用JavaScript响应click事件有条件地渲染网页元素</p>
<p>(允许用户添加自己喜欢的水果并依次赋色)</p>
<p style="margin-left:20%; color:purple; font-weight:bold;">
by PurpleEndurer
</p>
<p>你喜欢哪种水果?</p>
<div id="divFruit" style="height:200px; width:300px; overflow-y:auto;">
<script>
genFruitOption();
</script>
</div>
<p style="color:#0033ff">
温馨提示:如果以上没有您喜欢的水果,您可以输入和添加喜欢的水果名称到列表中:
<input type="text" id="itFruit" value="水果名称" />
<input type="button" value="添加" onclick="addFruit()" />
</p>
<p>你喜欢的是:</p>
<ul id="ulFruit" style="height:200px; width:300px; overflow-y:auto;">
<script>
genFruitLi();
</script>
</ul>
4 代码运行效果
可以看到,水果16的颜色和列表中第1种水果苹果的颜色相同,水果17的颜色和列表中第2种水果桔子的颜色相同,说明我们又重头开始使用颜色了。
5 小结
我们把 W3C 的 HTML 4.0 标准中所支持的16 种颜色名的英文单词存储到颜色数组,从头依次把颜色数组中颜色分配给水果,实现了水果有序赋色。
由于 颜色数组 只有15种颜色 ,当水果种类超过15种之后,我们需要回头重新从头开始分配颜色。
如果我们把RGB格式 或HSL 这两种方法表示的颜色存储到颜色数组,那么颜色数组中的颜色数量可以大幅增加,只要存储的颜色足够多,就可以实现不同的水果具有不同的颜色。