站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Javascript 专题Javascript高级教程-第2日

Javascript高级教程-第2日

摘要: Javascript高级教程-第2日
<textarea readonly style="border:none;font-family:Courier New;line-height:150%;width:760px;overflow-y:visible"> 第一页:Javascript高级教程-第2日

今天我们将学习一项很有用而且很有趣的内容:cookies - 这
是用来记录访问过你的网页的人的信息。利用Cookies你能记录
访问者的姓名,并且在该访问者再次访问你的站点时向他发出
热情的欢迎信息。你还可以利用cookie记忆用户端的特点 - 如
果访问者的所接入的网线的速度慢,cookie可以自动告诉你在
给其发送网页的时候只发送尽可能少的图片内容。

只要你在合理的范围内使用cookies(不要用它探询用户的个人
隐私),cookies还是相当实用得。所以我要向你们介绍cookies
的工作原理,但是在正式开始之前,我们先谈两个JavaScript
内容:有趣的字符串处理以及相关数组。

第二页:神奇的字符串处理

为什么必须在开始cookies世界漫游之前必须先学习神奇的字符
串处理呢?因为cookies也是字符串。要保存访问者的信息,你
必须首先建立一个特殊的cookie字符串。然后在访问者又返回
你的站点时读取该信息,而此时你必须对该cookie字符串进行
解码。要生成和解释这些字符串你必须了解JavaScript的字符
串工作原理。所以我们必须先要了解字符串。如果你是一个新
手,你应该先阅读一下上次的javascript教程第2日的内容,一
下是一个例子:

var normal_monkey = "I am a monkey!
";

document.writeln("Normal monkey " + normal_monkey);

var bold_monkey = normal_monkey.bold();

document.writeln("Bold monkey " + bold_monkey);

这里的声明:

var bold_monkey = normal_monkey.bold();

和下面对声明是等同的:

var bold_monkey = "" + normal_monkey + "";

第1个版本的声明看起来要简明得多。这里用到了字符串对象中
的bold对象,其他的字符串对象还有indexOf, charAt,
substring, 以及split, 这些方法可以深入字符串的组成结构。
首先我们研究一下indexOf。

indexOf
indexOf用于发现一系列的字符在一个字符串中等位置并告诉你
子字符串的起始位置。如果一个字符串中部包含该子字符串则
indexOf返回returns "-1." 这里是一个例子:

var the_word = "monkey";

让我们从单词 "monkey"开始。

var location_of_m = the_word.indexOf("m");

location_of_m(字母m的位置)将为0,因为字母m位于该字符串
的起始位置。var location_of_o = the_word.indexOf("o");
location_of_o(字母o的位置)将为1。

var location_of_key = the_word.indexOf("key");

location_of_key(key的位置)将为3因为子字符串“key”以字母
k开始,而k在单词monkey中的位置是3。

var location_of_y = the_word.indexOf("y");
location_of_y)字母y的位置)是5。
var cheeky = the_word.indexOf("q");
cheeky值是-1,因为在单词“monkey”中没有字母q。

indexOf更实用之处:
var the_email = prompt("What's your email address?", "");

var the_at_is_at = the_email.indexOf("@");

if (the_at_is_at == -1)

{

alert("You loser, email addresses must
have @ signs in them.");

}

这段代码询问用户的电子邮件地址,如果用户输入的电子邮件
地址中不包含字符 则 提示用户"@你输入的电子邮件地址
无效,电子邮件的地址必须包含字符@。"

charAt
chatAt方法用于发现一个字符串中某个特定位置的字符。这里
是一个例子:


var the_word = "monkey";

var the_first_letter = the_word.charAt(0);

var the_second_letter = the_word.charAt(1);

var the_last_letter = the_word.charAt(the_word.length-1);

the_first_letter(第1个字符)是"m"
the_second_letter(第2个字符)是"o"
the_last_letter(最后一个字符)是 "y"

注意利用字符串的length(长度)属性你可以发现在包含多少个
字符。在本例中,the_word是"monkey",所以the_word.length
是6。不要忘记在一个字符串中第1个字符的位置是0,所以最后
一个字符的位置就是length-1。所以在最后一行中用了
the_word.length-1。

第三页:子字符串

子字符串(substring)和charAt有些象,不同之处在于它能够
从一个单词中抓取整个的子字符串,而不只是字母,这里是其
格式:

var the_substring = the_string.substring(from, to);

"From"指的是子字符串中第1个字母的位置,"to"有点奇特,
它是该子字符串中比最后一个位置大1的位置.使用这种神奇
的方法你可以标记子字符串的起始和结束位置,用"to"的位置
减去"from"的位置就会得出该子字符串的长度:

var the_string = "monkey";

var clergy = the_string.substring(0,4);

var tool = the_string.substring(3,6);

运行该段代码后变量clergy的值为"monk"; 变量tool的值为
"key"。

子字符串常和indexOf一起使用,将字符串分成若干块.例如,
你可以从一个给定的URL中抽取出其域名:

var the_url = prompt("What's the URL?","");

var lead_slashes = the_url.indexOf("//");

var domain_start = lead_slashes + 2;

var without_resource = the_url.substring(domain_start, the_url.length);

var next_slash = without_resource.indexOf("/");

var domain = without_resource.substring(0, next_slash);

这段代码的意思是:如果你输入
"http://www.webmonkey.com/javascript/index.html",则域
名就是"www.webmonkey.com" .如果这个方法对你来说有些麻
烦,我将向你介绍如何使用split方法简化其执行过程.但是首
先我们作一些分析.

基本的技巧是将第1个斜杠和第2个斜杠之间的内容分离出来:
var the_url = prompt("What's the URL?","");
这行代码向用户询问一个URL.假设用户输入了
"http://www.webmonkey.com/javascript/index.html."
var lead_slashes = the_url.indexOf("//");
这行代码确定第一个双斜杠的位置.在本例中lead_slashes
的值是5,因为双斜杠的位置从5开始.

你可能会想,通常德URL都是以http://开始,所以双斜杠的位
置肯定是在5开始,为什么还要加入indexOf这一段多余的代
码呢?但是问题的关键在于你不知道用户在填入URL时是否一定
填入http:,他们也许会不小心多键入了一个空格,也许他们所
键入的URL在一个加密服务器上,其URL是
"https://www.whatever.com/" .在编程你必须预料到种种可能
发生的问题.所以我们必须用indexOf方法确定双斜杠的确切的
起始位置.

var domain_start = lead_slashes + 2;

这行代码用于计算该域名的第1个字母的起始位置.由于这里
有一个双斜杠,所以域名第1个字母的起始位置应该在双斜杠
所在位置加2的位置.

var without_resource = the_url.substring(domain_start, the_string.length);

这段代码将域名起始位置往后的所有字符都提取出来.所以执
行完这行代码后without_resource是
"www.webmonkey.com/javascript/index.html."

var next_slash = without_resource.indexOf("/");

这行代码计算出该字符串中下一个斜杠的位置,而从该字符串
起始位置到这个斜杠之间的内容就是域名.在本例中下一个斜
杠的位置是17。

var domain = without_resource.substring(0, next_slash);

最后一步是提取出该字符串起始位置到下一个斜杠之间的所有
内容.在本例中使得域名等同于"www.webmonkey.com"。

这样做确实很麻烦,利用split方法则可以使该过程容易很多.

第四页:分割方法(splitting method)

你可以使用split方法用限位器来分割一系列的名称,然后将其
放在一个数组中.例如:

var my_friends =
"trixie,moxie,sven,guido,hermes";

var friend_array =
my_friends.split(",");

for (loop=0; loop < friend_array.length;
loop++)

{

document.writeln(friend_array[loop] + " is my
friend.
");

}

这段代码将字符串my_friends分割成包含5个元素的数组.
JavaScript可以为你自动建立一个数组,所以你无需使用
new Array().

将字符串分割成数组之后,我们使用了循环语句写出每一个
名称.我们可以利用split方法简化前面所讲到的域名提取:

var the_url = prompt("What's the URL?","");

var first_split = the_url.split("//");

var without_resource = first_split[1];

var second_split = without_resource.split("/");

var domain = second_split[0];

这段代码简化了很多而且也更容易理解.我们来分析一些这段
代码:

var the_url = prompt("What's the URL?","");

提示用户输入一个URL,假设用户输入
"http://www.webmonkey.com/javascript/index.html" .
var first_split = the_url.split("//");
将用户输入的字符串分割成两块:first_split[0]是"http:",
first_split[1]是
"www.webmonkey.com/javascript/index.html."
var without_resource = first_split[1];
提取出数组中的第2个元素,所以现在without_resource是
"www.webmonkey.com/javascript/index.html."
var second_split = without_resource.split("/");
将without_resource分割成3块:www.webmonkey.com,
javascript, 和index.html.现在你可以看到split的用途了吧?
var domain = second_split[0];
现在我们提取出新数组中的第1个元素就可得出域名.

接下来我们将学习相关数组的概念,然后我们就正式开始学习
神奇的cookie.

第五页:相关数组

数组可以使你存储各种元素的列表,而且使你能够访问图象、
表单以及表单元素.在上次的Javascript教程中我讲解了如何
生成和控制按照索引号编排的数组例如:

var an_array = new
Array("hickory","dickory");

var element_one = an_array[0];

var element_two = an_array[1];

an_array[2] = "doc";

这里生成一个新数组,并用两个字符串进行了初始化.第1个
元素可以用其索引号0进行访问,而第2个元素则可以用其索
引号1进行访问an_array[1].你可以通过添加数组索引号加长
数组的长度.在本例中我加入了第3个元素,使其值等于 "doc".
现在该数组中包含"hickory,dickory, doc"3个元素.

相关数组和上面的数组相同,但它不使用数字做索引,而是用
单词来做索引.

var phone_book = new
Array();

phone_book["sleepy"] = "(203) 555-1234";

phone_book["happy"] = "(203) 555-2345";

这段代码生成一个电话号码簿,你输入"happy"就可以访问相应
的电话号码:

var happy_number = phone_book["happy"];

执行下一页的相关数字的例子看看它如何工作,同时再温习一
下javascript中表单的使用方法.

第六页:相关数组的一个例子

电话号码本

<form name=the_form>

Name: <select onchange="displayNumber(phone_book, this.options[selectedIndex].value);" size=1> <option value=happy>Happy</option> <option value=sleepy>Sleepy</option> <option value=sneezy selected>Sneezy</option> <option value=sleazy>Sleazy</option> <option value=sneery>Sneery</option> <option value=bleary>Bleary</option> <option value=tweaked>Tweaked</option></select>

Number: <input name=number_box>

</form>

 

这个例子比较复杂,我们来慢慢研究它.首先我们看一看电话
号码簿本身.它在文件头中定义为phone_book,有7条输入项:

每条记录的关键字是小矮人的名字,而每条记录的值就是该小
矮人的电话号码.假设我们需要找到某个小矮人的电话号码,
例如Sneezy的电话号码,我们这样写:

现在我们看看这个表单:

注意表单和表单内的元素都有名称,这样以来便于我们读取和
写入表单元素.

注意select标签中的onChange处理器的用法:当所选择的选项
变化时,它就调用函数displayNumber,该函数在文件头中已做
了定义.如果我在下拉选单中选择了sneezy,则表达式
this.options [selectedIndex].value 返回"sneezy",如果你
对该部分的内容不熟悉,请先阅读上次的javascript教程-第5日
的内容.

确定了用户所选择的选项之后,我们进入函数displayNumber:

它使用了两个参数-一个电话号码簿和一个名称,在函数第1
行中,

观察一下电话号码簿上的名字,然后进入下一行,

填入表单元素的数字命名为number_box.

你可以看到相关数组是将一个字符串连接到另一个字符串的好
办法.你可以利用相关数组将名字连接到电话号码,密码,生
日以及其他各种资料.在之后的课程中我将向你们介绍利用相
关数组可以做的各种有用的技巧.

第七页:介绍cookie

现在你已经掌握了先进的字符串处理和相关数组概念,该是我
们打开神奇的cookie魔瓶的时候了.cookie是记录访问你的站
点的人的信息,它其实驻留在用户的硬盘上,即使用户已经离
开你的站点,cookie在用户的硬盘上仍然存在,如果该用户再
次返回你的站点,则该cookie就会被一起发回到你的服务器中,
便于你统计和处理重复到访者的信息.

但是有一点需要注意:Cookies被引入Netscape 2.0和MSIE 3.0,
但是MSIE 3.0对cookies的应用不是太完善.你可以利用cookies
在别的用户的计算机上保存和读取信息,但却不能将cookie保
存在自己的计算机上,所以给cookie的测试造成一定的困难.
所以如果你使用的是MSIE 3.0,你最好将其升级为MSIE 4.0或
者改用Netscape.

下面我们看一看一个cookie应用的典型例子,我们在一个网页
中设置cookie,然后通过别的网页读取它.在使用该例子的
时候,想想如果没有cookie,你如何做到这一点.

第八页:深入了解cookies

由于cookies牵扯到向用户的硬盘写盘和读取信息,所以就涉及
一个保密性的问题.如果你需要大量什么cookies,你应该阅读
一下Marc Slayton写的cooikies揭密以及重新考察cookies.这
些文章将告诉你cookie的实质和作用范围以及其内在的局限性.
其最重要的局限性在于:不是每个人的浏览器都欢迎cookies.
即便是用户的浏览器欢迎cookies,但用户也有可能拒绝cookies
的访问(大部分人还是欢迎的)每个域名只分配20个cookies,
所以要节省着什么它们.Cookies不得大于4 KB,当然4,000字
节的容量是足够的了.

了解了这些局限性之后我们开始学习如何设置cookies设置一个
基本的cookie很容易.你所需做的只是在一个cookie_name=value
表单中生成一个字符串,然后设置document.cookie属性.唯一
的技巧:cookie值中不能有空格,逗号或分号.好在你无需担
心这些问题,因为有一系列的函数可以帮你对cookies属性编码
和解码:

escape()和unescape().

下面的简单例子中将你的姓名保存为一个cookie:

function setCookie()
{

var
the_name = prompt("What's your name?","");

var the_cookie =
"wm_javascript=username:" + escape(the_name);

document.cookie =
the_cookie;

alert("Thanks, now go to the next
page.");

}

函数中间的两行是关键:
var the_cookie = "wm_javascript=username:" + escape (the_name);

如果我在提示框中输入了"dave thau",该行代码将生成一个字
符串wm_javascript=username:dave%20thau.这就是说我将把
一个名为wm_javascript的cookie保存到硬盘.该cookie的值
是username:dave%20thau - 函数 escape()将"dave" 和"thau"
之间的空格用%20做了替换.

当我们读取cookie时,我们寻找名为wm_javascript的cookie,
然后提取username:dave%20thau,将其用 unescape()解码,去
掉username:.

document.cookie = the_cookie;

cookie现在就设置好了,很简单.下面我们学习如何读取
cookie.

第九页:读取cookies

一旦你在某用户的硬盘上设置了cookie,读取是件很容易的
事.下面是读取cookie范例的代码:

function readCookie()

{

var the_cookie = document.cookie;

var broken_cookie = the_cookie.split(":");

var the_name = broken_cookie[1];

var the_name = unescape(the_name);

alert("Your name is: " + the_name);

}

第1行很重要.当你的浏览器打开一个网页时,它调用任何和
该网页有关的cookie然后将其载入document.cookie属性.

读取cookie的技巧在于从中抽取出你需要的信息.注意在我们
所设置的cookie是这样的:wm_javascript=username:dave%
20thau.在该函数第1行之后的所有用于从该cookie中提取出
用户名(username).

var broken_cookie = the_cookie.split(":");

将cookie在分号处分割成两部分.
var the_name = broken_cookie[1];

抓取分号后面的内容dave%20thau.
var the_name = unescape(the_name);
取消函数escape()的编码替换.在本例中重新用空格替换了%20.
alert("Your name is: " + the_name); 显示你的姓名.

这个例子使用的cookie只保存了很少的信息:用户名,cookie
最多可以保存多达4kb的信息。

第十页:复杂的cookies读取

如果你想让你的cookie包含更多的信息,你可以将cookie的值
设得很长.假设我们要保存某人的姓名,年龄和电话号码:

var the_cookie = "username:thau/age:older than the hills/phone:411";

document.cookie="my_happy_cookie=" + escape(the_cookie);

我用斜杠/来分割属性名称,用分号区别不同的属性名称及其
属性值.斜杠/和分号是不是绝对的选择,你可以使用任何的
字符做分割的标志:

var the_cookie = "username=thau&age=older than the hills&phone=
411";

document.cookie="my_happy_cookie=" + escape(the_cookie);

你可以自行选择限位器.只要你注意在对cookie解码时也使用
同样的限位器即可.

设置复杂的cookie时方法要复杂一些.我们建议你使用相关数
组来保存所有的信息,假设我们将该cookie保存到某人的硬
盘上:

my_happy_cookie=username:thau/age:older than the hills/phone:411


你可以将这些信息放到一个方便的相关数组中:

function readTheCookie(the_info)

{

// load the cookie into a variable and unescape it

var the_cookie = document.cookie;

var the_cookie = unescape(the_cookie);

// separate the values from the cookie name

var broken_cookie = the_cookie.split("=");

var the_values = broken_cookie[1];

// break each name:value pair into an array

var separated_values = the_values.split("/");

// loop through the list of name:values and load
// up the associate array

var property_value = "";

for (loop = 0; loop


如果在你的JavaScript中有上面这段代码,你可以这样调用它:

var cookie_information = new Array();

readTheCookie(cookie_information);

然后你就会正确设置了cookie_information["username"],
cookie_information["age"], 和cookie_information["phone"].

这些看起来可能有些难以理解,但实际上并不是很难.我们一
步步分析:
var the_cookie = document.cookie;
将cookie赋值给一个变量.
var the_cookie = unescape(the_cookie);
取消escape()的编码
var broken_cookie = the_cookie.split("=");
var the_values = broken_cookie[1];
使the_values等同于username:thau/age:older than the hills/phone:411.
var separated_values = the_values.split("/");
生成一个包含3个元素名为separated_values的数组:
separated_values[0] = "username:thau"
separated_values[1] = "age:older than the hills"
separated_values[2] = "phone:411"

for (loop = 0; loop
循环调用separated_values的3个元素.
property_value = separated_values[loop];
提取当前的name:value配对,第1个配对是username:thau.
var broken_info = property_value.split(":");
将该配对分成名为broken_info的数组中的两个元素:
broken_info[0] = "username"
broken_info[1] = "thau"

var the_property = broken_info[0];
第1次经过这个循环是,the_property是"username"
var the_value = broken_info[1];
其值是"thau"
the_info[the_property] = the_value;
这里开始发回相关数组的便捷功能.它使得the_info
["username"] = "thau",所以现在当你需要从cookie中查找
username时你只需:
var the_name = the_info["username"];

每次经过这个循环时,就在the_info中加入一个新元素.循
环到最后时, the_info["username"] = "thau", the_info
["age"] = "old as the hills" ,而 the_info["phone"] = 411.

有些烦琐,但是当你需要从cookie中输出入大量信息时这是一
个很好的办法.当然还有别的办法.

第十一页:读取和编写多重cookies

上一篇中我们学习了如何将大量的学习包含在一个cookie中.
另一种方法是使用多重cookies.

保存多重cookies的方法很直观.每一个cookie都有一个名称.
上一个例子中的cookie的名称是my_happy_cookie,我们可以
这样:
var the_cookie ="my_happy_cookie=happiness_and_joy";

document.cookie =the_cookie;

要保存多重cookie,只需给每个cookie一个不同的名字.如果
你要加入一个新的cookie,设置document.cookie 时并不会删
除前面已经设置了的cookies,所以:

var the_cookie ="my_happy_cookie=happiness_and_joy";

document.cookie = the_cookie;

var another_cookie= "my_other_cookie=more_joy_more_happiness";

document.cookie = another_cookie;

现在你需要访问这两个cookies,有些复杂,所以你需要明了整
个过程.假设你执行了上面的代码,现在想访问
my_happy_cookie.如果你查看document.cookie的内容,你会
看到:

my_happy_cookie=happiness_and_joy;
my_other_cookie=more_joy_more_happiness;

这样很直观,但是如果你想访问某个特定的cookie则有些困难.
下面的代码可以帮助你找出某个特定的cookie:
function WM_readCookie(name)
{

//如果没有cookie则返回false或者取得值并返回该值
if(document.cookie == '')
return false;
else
return
unescape(WM_getCookieValue(name));
}



function WM_getCookieValue(name)
{

// Declare variables.

var firstChar,lastChar;

// Get the entire cookie string.
// (This may have other
name=value pairs in it.)

var theBigCookie = document.cookie;

// Grab
just this cookie from theBigCookie string.

// Find the start of
'name'.

firstChar = theBigCookie.indexOf(name);

// If you found it,


if(firstChar != -1)
{

// skip 'name' and '='.

firstChar +=
name.length + 1;

// Find the end of the value string (i.e. the next
';').

lastChar = theBigCookie.indexOf(';', firstChar);


if(lastChar == -1) lastChar = theBigCookie.length;

// Return the
value.

return theBigCookie.substring(firstChar, lastChar);

} else
{

// If there was no cookie, return false.

return false;



}

}

下面我们将学习一下cookies可以做的真正酷的内容。

第十二页:再次深入了解cookies

现在你已经学会了如何设置和读取基本的cookie.然而基本
的cookie常常在用户关闭他的浏览器时会被自动删除.有时候
这样最好因为通常的域只允许在用户的机器上保留20个cookie.
但是如果你希望将cookie保存在用户的机器上你需要设置一
个cookie失效的时间,它的格式是一种叫做GMT的特殊格式.
例如:

Mon, 27-Apr-1998 00:00:00 GMT

要正确设置GMT不是一件容易的事,你需要计算好某个日期是星
期几.好在Javascript有一个日期的方法叫做toGMTString可以
帮助你.下面是设定远期的某个时间的一个例子:
var the_date = new Date("December 31, 2023");

var the_cookie_date =the_date.toGMTString();

一旦你设置了你的cookie的失效期,你在必须在cookie设置的
前面加入这条信息.因此你的cookie应该如下:

cookie_name=blah_blah;expires=date

通常你只需在cookie字符串中加入expires=date,然后用分号
分割不同的cookie.

下面是一个如何建立有效期直至Mayan日历末尾的函数:


function
setCookie()

{

// get the information

//

var the_name = prompt("What's your name?","");

var the_date = new Date("December 31, 2023");

var the_cookie_date =the_date.toGMTString();

// build and save the cookie

//

var the_cookie = "my_cookie=" + escape(the_name);

the_cookie = the_cookie +";expires=" + the_cookie_date;

document.cookie = the_cookie;

}

最后cookie应该如下所示:

my_cookie=thau;expires=Fri,31-Dec-2023 00:00:00 GMT

设置好cookie之后,它将在用户的机器中国存在直到失效期.
如果你将某个cookie的失效期设置得比当前时间还早,该cookie
实际上不能在用户的机器上存活.

此外,还有两个只要的事项:路径(path)和域(domain)。

第十三页:cookie路径和域

这是掌握cookie最后的一个障碍:缺省情况下cookie只能被在
同一个Web服务器上同一个路径下设置了该cookie的网页读取.
例如,如果在
"http://chimp.webmonkey.com/food/bananas/banana_puree.htm"
有一段Javascript询问了用户的姓名,你可能需要在你的另一
个网页例如主页中访问一个给定的名字.所以你必须设定该
cookie的路径.路径"path"用于设置可以读取一个cookie的最
顶层的目录.将cookie的路径设置为你的网页最顶层的目录可
以让该该目录下的所有网页都能访问该cookie.

方法:在你的cookie中加入path=/; 如果你只想让"food" 目录
中的网页可以使用该cookie,则你加入path=/food;.还有一点:
有些网站有许多小的域名,例如网猴可能还在
"chimp.webmonkey.com," "gorilla.webmonkey.com," 和
"ape.webmonkey.com." 域名下有网页.缺省情况下只有
"chimp.webmonkey.com" 域下的网页可以读取该cookie.如果
你向让"webmonkey.com"下的所有机器都可以读取该cookie,我
们必须在cookie中加入 "domain=webmonkey.com" .

要将一个cookie设置在
"http://chimp.webmonkey.com/food/bananas/banana_puree.htm"
并且让所有网猴的网页都可以利用它,我们可以这样:
function setCookie()

{

var
the_name = prompt("What's your name?","");

var the_cookie =
"cookie_puss=" + escape(the_name) + ";" ;

var the_cookie = the_cookie
+ "path=/;";

var the_cookie = the_cookie + "domain=webmonkey.com;";


document.cookie =
the_cookie;

}

现在我们已经学习完了cookie的内容.希望你能够多加练习。





</textarea>
↑返回目录
前一篇: Javascript高级教程 - 第三课
后一篇: 小技巧:(javascript)如何让用户自由控制html页面大段文字的行间距和背景颜色