一个 Shoutcast 电台侧边栏小工具






4.33/5 (6投票s)
关于编写侧边栏小工具
引言
在这篇文章中,我想向人们介绍侧边栏小工具开发艺术。本文面向初学者,所以我尽力使代码保持简单,但需要基本的 Javascript 知识。我们将使用最基本的三个部分:小工具、弹出窗口和设置窗口。这是我第一次尝试为 codeproject 撰写文章。英语不是我的母语,所以我希望您不要太介意我的语言。
为什么选择收音机小工具
和大多数安装 Windows Vista 的人一样,我首先注意到的是侧边栏。作为 Shoutcast 收音机的拥有者,我萌生了为其设计一个特殊小工具的想法。最初的小工具变成了一个单电台应用程序,但为了这篇文章,我制作了一个你可以用于所有你喜欢的 Shoutcast 服务器的小工具。
Shoutcast 由 nullsoft 制作,所以大多数人将其与 winamp 结合使用。它也与 Windows Media Player 运行良好,所以我们将使用 ActiveX 来播放小工具中的流媒体。但在我们开始之前,让我们简单列出我们的侧边栏小工具必须要做的事情。最重要的是,标记出我们在创建它时可能遇到的问题。
- 该小工具必须能够连接到所有您喜欢的 Shoutcast 广播电台。为此,我们将使用设置以添加、删除和选择电台的方式。
- 为了文章的简洁,我将控件限制在播放、停止和音量控制。
- Shoutcast 服务器我最喜欢的部分是它有一个最近播放歌曲的列表。这里的问题是,只有当你拥有服务器的管理员密码时,它才以 XML 格式提供。幸运的是,普通听众可以从 Shoutcast 服务器提供的那个丑陋的黑色 HTML 页面中读取它。对于小工具,我将读取该页面以获取播放列表信息。
准备项目
Vista 侧边栏小工具位于活动用户的小工具文件夹中。考虑到您计算机的每个用户都可以安装自己的小工具,这不会让您感到惊讶。我们将直接在这个文件夹中设计我们的小工具,这样我们就可以在侧边栏中看到我们的工作。
小工具文件夹中的每个小工具都有自己的子文件夹,格式为name.gadget
。对于我们正在制作的小工具,它将是radio.gadget
。
您可以浏览位于以下位置的小工具文件夹
%userprofile%\AppData\Local\Microsoft\Windows Sidebar\Gadgets
我们可以手动创建我们需要的文件夹。甚至可以在记事本或不同的文本编辑器中完全制作我们的小工具。我个人更喜欢使用 Visual Web Developer。正如你在我的个人资料中看到的,我的预算很小,所以我使用 Express Edition,但我确信使用完整版不会有太大问题!
因此,打开 Web Developer 并创建一个基于“空网站”模板的新网站。对于位置,您使用以下内容,但请务必将 David 替换为您自己的用户名!
:\Users\David\AppData\Local\Microsoft\Windows Sidebar\Gadgets\radio.gadget
这将打开我们将用于构建小工具的空项目。
首先要做的是创建几个文件夹。所以在解决方案资源管理器中右键单击,使用文件夹选项创建 3 个文件夹。
- css:我们将用这个来存放我们的 css 模板。
- images:我们将在这里存放用于图标和皮肤的图片。
- js:类似于css文件夹,但这是用于存放 JavaScripts。
将 ZIP 文件中的所有图像移动到您刚刚创建的 images 文件夹。
至此,我们完成了准备工作,可以开始编写我们的小应用程序了!
创建小工具的 XML 文件
小工具清单是一个 XML 文件,其中包含有关作者和小工具使用的文件的数据。这个 XML 总是被称为 gadget.xml,以便系统可以找到它,所有其他文件名您可以自己决定!
在解决方案资源管理器中右键单击项目并创建一个新项。从模板中选择 XML 文件,这样标头就已经为您创建好了。
<?xml version="1.0" encoding="utf-8" ?>
<gadget>
<name>Radio Gadget</name>
<namespace>Gevaerts.Gadgets</namespace>
<version>1.0.0.0</version>
第一行是由 Web Developer 为我们生成的。之后,我们打开 gadget XML 标签。第一个节点是<name>
,我们可以在这里给出我们作品的名称。这个名称我们可以在小工具库中找到,以及设置窗口的顶部。
对于<namespace>
,我填写了Gevaerts.Gadgets
,但您可以根据需要更改它。
我将<version>
标签设为1.0.0.0
,因为这是我们小工具的第一个发行版本。
<author name="David Gevaerts">
<info url="www.gevaerts.org" />
<logo src="images/radio.gif"/>
</author>
作者名称节点是可选的,但非常有用!您可以给它起自己的名字,它有两个可选元素。信息 URL,您可以在其中输入指向您网站的链接。以及徽标源,您可以在其中输入与您关联的图形。
<copyright>© Gevaerts Organisations 2007</copyright>
<description>Radio gadget of the article</description>
这些行是可选的,但很有用,所以最好输入它们。我认为它们不需要解释。
<icons>
<icon height="48" width="48" src="images/radio.gif"/>
</icons>
图标节点也是可选的。如果你不提供图标,Vista 会使用一个标准图标。但为什么不自己制作一个呢?你付出了所有努力来创建一个应用程序,所以花时间把它做好!对于我们的例子,我制作了一个收音机图标radio.gif,你可以在 images 文件夹中找到它。
现在是重要部分,使我们的小工具工作的代码。
<hosts>
<host name="sidebar">
<base type="HTML" apiVersion="1.0.0" src="gadget.htm" />
<permissions>Full</permissions>
<platform minPlatformVersion="1.0" />
</host>
</hosts>
我们需要的数据包含在 hosts 节点中。我们使用的第一个元素是 host。我们正在制作一个侧边栏小工具,所以对于 host name,我们使用“sidebar
”。第一个子元素是 base type,期望的类型是“HTML
”,我们使用 apiVersion “1.0.
0
”。这里最重要的部分是src
,我们在其中建立与小工具的 HTML 文件的连接。
您可以使用任何您想要的名称。但最好的策略是保持简单!我使用了 gadget.htm,这样以后很容易找到它。
主机的下一个子元素是<permissions>
。Microsoft 文档称期望值为Full
,但我没有找到更多关于此的信息。
平台子级设置为小工具所需的最低平台。在我们的例子中,这是 Version="1.0
"。这就是我们清单文件中所需的一切,现在我们只需要用以下内容关闭它
</gadget>
创建 gadget.htm
在我们的清单中,我们指向了我们的源 HTML 文件 gadget.htm。这是我们小工具的主要部分。我们将使用此文件将 CSS、HTML 和 JavaScript 连接在一起。它还包含我们在小工具栏中看到的主体。
首先,我们将创建三个文件。在小工具的根目录中,我们创建“gadget.htm”文件,在我们的 CSS 文件夹中,我们创建“gadget.css”。最后但同样重要的是,在 js 文件夹中,我们创建“gadget.js”。JavaScript 文件我们稍后处理。但 .htm 和 .css 我将一起处理,因为它们密切相关。在此部分之后,小工具将在小工具库中可见。
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Radio gadget</title>
<script type="text/javascript" src="js/gadget.js"></script>
<link type="text/css" rel="stylesheet" href="css/gadget.css" />
</head>
侧边栏小工具与网络应用程序并没有太大区别,只是它们更小。所以 htm 文件对您来说会非常熟悉。该项目的头部包含标题以及指向 CSS 文件和 JavaScript 的链接。
<body onLoad="gadgetInit();">
<object id="player" classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6"
width="0" height="0"></object>
<div id="PlayControle">
<img alt="Turn on the radio." src="images/PlayBut.png"
onmouseover="this.src='images/PlayButDark.png';"
onmouseout="this.src='images/PlayBut.png';"
onclick="startRadio();" />
</div>
<div id="playlist">
<img alt="Show the last played songs" src="images/PLBut.png"
onmouseover="this.src='images/PLButDark.png';"
onmouseout="this.src='images/PLBut.png';"
onclick="playlist();" />
</div>
<div id="vulumedown">
<img alt="Volume Up" src="images/VolMin.png"
onmouseover="this.src='images/VolMinDark.png';"
onmouseout="this.src='images/VolMin.png';"
onclick="volumeUp();" />
</div>
<div id="vulumeup">
<img alt="Volume Down" src="images/VolUp.png"
onmouseover="this.src='images/VolUpDark.png';"
onmouseout="this.src='images/VolUp.png';"
onclick="volumeDown();" />
</div>
<div id="radioname">
</div>
</body>
</html>
在 body 标签中,当我们在侧边栏加载小工具时,我们调用 JavaScript 函数 gadgetInit()
。但 body 标签处理的远不止这些。为了向您展示这一点,请看 CSS 文件
body
{
width:120;
height:96;
padding-top:0;
padding-left:0;
background-image: url(../images/RadioW.png);
}
请注意,我们使用 width
和 height
属性来设置我们的小工具在侧边栏中的大小。width
设置为 Microsoft 建议的最大值 120
像素。您可以将其设置得更小。但当我们都使用相同的 width
时,我们的侧边栏将具有一个整齐有序的外观。如果您喜欢,可以将 height
设置得更大。一条黄金法则是“不要使用超出您实际需要的空间”。
接下来,我们将 padding 设置为0
,以便我们的小工具在侧边栏中占据正确的位置。另外请注意,我们在背景图片中设置了我们的收音机图形,我们的图形大小为 120 x 96 像素,所以它不会重复。
回到 htm 文件中,我们为媒体播放器创建了一个 ID 对象。我们稍后会在 JavaScript 中使用它。
现在我们创建一些用于处理控制按钮的div
标签。对于初学者来说,请注意我是如何使用onmouseover
和onmouseout
事件来改变图像的。onclick
事件指向 JavaScript 文件中的函数。
这些div
的 CSS 几乎相同,所以我只展示一个。查看源代码以获取其他。
div#PlayControle
{
position:absolute;
width:28px;
height:28px;
top:68;
left:34;
z-index:1;
}
这就是你在 PlayControle
的 CSS 中找到的内容。位置是绝对的,所以我们可以将按钮精确地放置在我们想要的位置。我们的按钮是 28
x 28
,我们使用 top 和 left 来设置此控件的左上角位置。
我们已经完成了 HTML 和 CSS 文件,保存它们并打开小工具库。太棒了,我们的作品出现了!如果你愿意,可以把它安装到你的侧边栏。在下一节,我们将让它工作起来!
小工具 JavaScript
我们现在有了一个侧边栏,但只有一个问题!它什么也没做。我们现在要做的是连接到我们最喜欢的电台。打开上一章创建的 gadget.js 文件并输入以下函数
// The basic Javascript for the gadget
var player;
var state=1;
var radio = "http://radio.wartimememories.net:8004"
function gadgetInit()
{
// To Do : Here you can enter your code to start the gadget
player = document.getElementById('player');
player.settings.volume = 80;
// We need to do some gadget specials like creating the flyouts
System.Gadget.Flyout.file = "Flyout.htm";
System.Gadget.settingsUI = "Settings.htm";
System.Gadget.onSettingsClosed = settingsClosed;
radioname.innerHTML = System.Gadget.Settings.read("radioname");
}
我使用 3 个全局变量。一个用于保存播放器,一个用于保存状态,最后一个用于保存您想要连接的电台。我用主电台服务器初始化全局变量 radio。例如,我使用了我自己的服务器,但您可以随意更改它。
当我们在侧边栏启动小工具时,gadget.htm 会调用 gadgetInit
函数。它只处理一些初始任务。通常我们会在这里做更多的工作,但为了本教程,我最好保持简短。
我使用 getElementById
和我们在 HTML 代码中给它的 ID
将媒体播放器加载到 player 变量中。我们给它一个初始音量 80
。
我们将使用一个浮出窗口来显示最近播放列表。我们将使用设置来添加和选择电台服务器。Gadget
API 为我们提供了相关的属性。现在在项目根目录下创建两个额外的 htm 文件 Flyout.htm 和 Settings.htm。这些文件将用于小工具的设置和浮出窗口。
小工具需要知道当设置窗口关闭时该怎么做。这很重要,因为我们可能选择了一个不同的电台!我们通过将事件 System.Gadget.onSettingsClosed
指向函数 settingsClosed
来实现这一点。我稍后会解释这个函数。
最后,我们将所选电台的名称移动到小工具的电台名称窗口。如果未选择服务器,此窗口将保持为空。
function startRadio()
{
if(state == 1)
{
player.URL = radio;
state=0;
PlayControle.innerHTML = "<img alt=\"Turn off Wartime Memories radio\"
src=\"images/StopBut.png\"
onmouseover=\"this.src='images/StopButDark.png';\"
onmouseout=\"this.src='images/StopBut.png';\"
onclick=\"startRadio();\" />";
}
else
{
player.URL = "";
state=1;
PlayControle.innerHTML = "<img alt=\"Turn on Wartime Memories radio\"
src=\"images/PlayBut.png\"
onmouseover=\"this.src='images/PlayButDark.png';\"
onmouseout=\"this.src='images/PlayBut.png';\"
onclick=\"startRadio();\" />";
}
}
此函数是应用程序的核心部分。它根据状态启动和停止选定的电台。如果state
设置为1
,则小工具未播放,我们将启动它。我们通过将电台地址加载到播放器的 URL 属性中来启动流。之后,我们将state
设置为0
,并使用PlayControle
的innerHTML
将按钮更改为stop
按钮。
当state
为0
时,我们使用else
。我们通过将空字符串加载到播放器的 URL 属性中来停止流。正如我所说,为了这篇文章,我想保持简单!我们将state
改回1
,并将按钮改回play
按钮。就这么简单,这里没有花哨的例程,但它会完成工作。
function volumeUp()
{
if(player.settings.volume < 100)
{
player.settings.volume = player.settings.volume + 10;
}
}
当用户点击其中一个音量按钮时调用的函数非常基础,正如您所看到的。这里您看到的是 volumeUp
例程。音量减小函数与此相反,我相信您可以自己弄清楚。当用户点击音量增大按钮时,我们检查 player.settings.volume
属性是否小于 100。如果是这种情况,我们将其值增加 10
。音量属性是一个介于 0
和 100
之间的整数。我以 10
的步长更改它,但您可以根据自己的需求进行更改。
function playlist()
{
if(System.Gadget.Flyout.show)
{
System.Gadget.Flyout.show = false;
}
else
{
System.Gadget.Flyout.show = true;
}
}
当应用程序用户点击playlist
按钮时,我们希望呈现最近播放歌曲的列表。这个列表将在flyout
窗口中呈现给用户。在gadgetInit
函数中,我们让Flyout
指向Flyout.htm文件,所以我们在这个函数中需要做的就是检查flyout
的显示状态是true
还是false
。如果它是true
,我们就把它设为false
。这样,浮出窗口就变为非活动状态。否则,我们将其设为true
,这样浮出窗口就变得可见。
function settingsClosed(event)
{
if(event.closeAction == event.Action.commit)
{
readSettings();
}
}
在这里我们看到了我之前谈论的函数!正是这个函数,我们将 System.Gadget.onSettingsClosed
事件指向它。我们在这里所做的只是检查关闭操作是否等于 Acrion.commit
,如果是这种情况,我们调用我们的函数 readSettings
。您在这里看到的 readSettings
函数仅负责读取我们在主小工具中所需的设置。我们将电台名称直接使用 innerHTML
移动到窗口。所选服务器的 URL 地址加载到 radio 变量中。我们需要连接到服务器的全局变量。
function readSettings()
{
radio = System.Gadget.Settings.read("active");
radioname.innerHTML = System.Gadget.Settings.read("radioname");
}
现在是检查您工作的好时机。安装您的小工具并查看。当您点击播放按钮时,收音机开始播放,您可以点击停止按钮停止它,并且可以调高音量。
至此,教程中 gadget.js 文件中的例程就结束了。您可以随意尝试并让您的版本更高级。
制作弹出窗口
现在是时候制作我们的弹出窗口和播放列表了。这部分的 HTML 和 CSS 已经减少到最低限度。
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Recently played</title>
<link href="css/flyout.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="js/flyout.js"></script>
</head>
<body onload="flyoutinit();">
<div id="canvas">
</div>
</body>
</html>
头部包含flyout
的名称,并设置指向 CSS 和 JavaScript 的链接。这与我们在gadget.htm中做的完全一样。主体使用onload
事件来启动flyoutinit()
函数。我们可以在flyout.js文件中找到它。我们只需要 HTML 代码主体中的一个部分,一个div
层“canvas
”。这个canvas
div
用于使播放列表可见。大部分flyout
将在 JavaScript 中生成。我认为这里没有必要解释 CSS 部分。它非常简单,或多或少与gadget.css相同。
function flyoutinit()
{
radio = System.Gadget.Settings.read("active");
splitServer();
getpage();
}
当我们打开flyout
时,HTML body 标签中的onload
事件会调用flyoutinit()
函数。为了显示最近播放列表,我们需要我们的电台服务器地址。我们可以直接从我们的设置中读取它,就像我们在主小工具 JavaScript 中所做的那样。该函数进行两次调用。一次调用splitServer
,这是一个我们用来将电台 URL 分割成地址和端口号的函数。然后getpage
函数将处理其余部分,如解析信息,并将其呈现在画布层上。
function splitServer()
{
var re = new RegExp("^http://");
work = radio.replace(re,"");
work = work.split(":");
adress = work[0];
port = work[1];
}
在这里,我们使用两个简单的正则表达式将广播 URL 分割成我们制作播放列表所需的address
和port
。首先,我们使用 replace 方法从 URL 中删除 http://。现在我们有一个工作字符串,可以将其分割成服务器address
和port
。分割方法之后,work 将是一个数组,其中work[0]
包含address
,[1]
包含port
。我们现在拥有制作播放列表并将其呈现给用户所需的一切。这里我们遇到了几个问题!
我们需要的信息是 XML 格式,这样我们就可以使用 AJAX 来处理它。Shoutcast 服务器的问题在于,它只将此信息提供给经过身份验证的管理员。如果您为自己的服务器构建网站,这没问题。但在我们的情况下却有问题!我们没有管理员密码。即使我们为我们拥有的电台制作一个单电台版本,我们也不想将其包含在小工具中。我们不想给我们的听众对电台服务器的管理访问权限。此外,如果我们要更改密码,这样做就没有意义。
并非一切都完了!Shoutcast 为我们提供了那个包含歌曲历史的丑陋黑页。也许我们可以用这个?是的,我们可以,但这给我们带来了另一个问题!我们可以使用 AJAX 读取 HTML 页面。但这里我们遇到了 Internet Explorer 的一个小问题。许多论坛都充斥着关于 Internet Explorer 缓存问题的信息。一个很好的解决方法是在 URL 中包含时间字符串。这在普通的 HTTP 服务器上完美运行。问题是,Shoutcast 不是普通的 HTTP 服务器!它不会接受带有未知GET
参数的 URL。
我以前在为几个服务器制作带列表的网站时也遇到过同样的问题。那时我创建了一个 PHP 脚本,用于读取 Shoutcast 播放列表并以 XML 数据呈现。您可以这样使用此脚本,欢迎免费使用!
如果您想自己托管此脚本,请随时给我写信!
现在让我们编写getpage()
函数。
function getpage()
{
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
if(xmlHttp==null)
{
System.Gadget.Flyout.document.parentWindow.canvas.innerHTML =
"We found a problem with AJAX functionality!";
return;
}
var d = new Date();
url="http://wartimememories.net/shoutreader.php?adres="+adress+"
&port="+port+"&t="+d.getTime();
xmlHttp.open("GET",url,true);
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
str = "<table width='100%'><tr><td bgcolor='Gray'
style='font-size: xx-small'>";
str = str + xmlHttp.responseXML.getElementsByTagName
('played')[0].childNodes[0].nodeValue + " : ";
str = str + xmlHttp.responseXML.getElementsByTagName
('title')[0].childNodes[0].nodeValue;
str = str + "</td></tr>"
for(i=1; i<xmlHttp.responseXML.getElementsByTagName
('played').length; i++)
{
str = str + "<tr><td bgcolor='Silver' style='font-size:
xx-small'>";
str = str + xmlHttp.responseXML.getElementsByTagName
('played')[i].childNodes[0].nodeValue + " : ";
str = str + xmlHttp.responseXML.getElementsByTagName
('title')[i].childNodes[0].nodeValue;
str = str + "</td></tr>";
}
str = str + "</table>";
System.Gadget.Flyout.document.parentWindow.canvas.innerHTML = str;
}
}
xmlHttp.send();
}
这是整个源代码中最长的函数。它并不难理解。其中大部分是创建列表的 HTML 代码。我们在这里做的第一件事是将“Msxml2.XMLHTTP
”ActiveX 加载到xmlHttp
中,并检查它是否正确加载。如果未加载,我们会向浮动窗口写入错误消息并返回。如果没有 ActiveX,继续是没有用的。
接下来,我们在d
中生成一个Date()
对象,我们需要它来生成我们的 URL,以解决我之前提到的缓存问题。
现在我们已经准备好一切来创建 URL。注意我们是如何包含时间的。这很重要,否则我们会一遍又一遍地从缓存中读取同一个文件。现在我们需要打开 URL。
我们真的不知道服务器何时会报告回来。因此,我们将onreadystatechange
事件指向一个函数。当xmlHttp
的状态改变时,就会调用此函数。如果是这种情况,我们检查此状态是否等于 4(这意味着我们的文档已完全加载)。
我们启动一个字符串,用于添加我们的 HTML 代码。使用 getElementsByTagName
方法,我们找到播放的时间和标题。第一个元素 [0]
是当前正在播放的歌曲,我们在我们生成的第一个表格行中将其加深。此后启动的 for
循环处理列表中其余的歌曲。处理完所有歌曲后,我们将结果字符串写入画布。
getpage
函数的最后一条指令将向网络服务器发送请求。
现在我们只需要制作settings
窗口。
设置 HTML 和 CSS
我们的设置将处理我们想做的大部分事情。制作一个只有 1 个或更多预设 Shoutcast 服务器的小工具很容易。但这不是我们想要的!我们想要的是一个可以添加我们喜欢的服务器并选择它们的小工具。所有这些都将通过设置浮出窗口来处理。与其它部分不同,我们将完全使用 HTML 和 JavaScript 来制作这个窗口。
<body onload="loadsettings();">
<table>
<tr>
<td>
<select id="RadioList" name="RadioList" size="10"
class="rsel" unselectable=on onclick="SelectRecord();">
</select>
</td>
<td valign=top>
<input id="Add" type="button" value="Add" class="but"
onclick="AddRecord();" />
<input id="Edit" type="button" value="Edit" class="but"
onclick="edit();" disabled />
<input id="Del" type="button" value="Delete" class="but"
onclick="dele();" disabled />
</td>
</tr>
</table>
与本文中我们看到的其他 HTML 文件一样,onload
事件将调用settings.js中的初始函数。在这里,我们创建一个有两列的表格。第一列将包含我们的选择列表,其onclick
事件指向SelectRecord()
函数。另一列将处理Add
、Edit
和Delete
按钮。这些部分的 CSS 很简单,所以我在这里不做解释,但请查看源代码。
<div id="record">
<table width="100%" height="100%" border="0">
<tr height="15" valign="top">
<td bgcolor=gray class="tdesc">
Name
</td>
<td bgcolor=silver>
<input id="rname" type="text" class="textf" />
</td>
</tr>
<tr height="15" valign="top">
<td bgcolor=gray class="tdesc">
URL
</td>
<td bgcolor=silver>
<input id="url" type="text" class="textf" />
</td>
</tr>
<tr valign="top">
<td bgcolor=gray class="tdesc">
Description
</td>
<td bgcolor=silver>
<textarea id="desc" class="descf"></textarea>
</td>
</tr>
</table>
</div>
</body>
</html>
记录div
,处理所选电台记录的可视化。它也用于编辑和添加记录。我们将使用 JavaScript 来处理它。
设置 JavaScript
settings.js是项目中最大的脚本,需要大量的解释。与应用程序的其余部分相比,这部分将完成大部分工作。奇怪的是,如果你需要一个单服务器小工具,你就不需要它!如果是这样,只需将gadget.js中的初始字符串更改为你想要的电台服务器。但如果你想要一个可以让你选择和添加不同服务器的小工具,这部分代码将使其成为可能。
var radioCount;
var oldSel=-1;
var radioRecords = new Array();
var recName;
var recAdress;
var recDesc;
var ed = false;
首先,我们创建此脚本中所需的全局变量。我们需要一个变量来保存可供选择的电台服务器数量。一个全局变量来保存旧选择,我们将用于电台记录的数组,以及我们将用于选定记录的变量。
function loadsettings()
{
radioCount = System.Gadget.Settings.read("radioCount");
if(!radioCount) radioCount = 0;
for(i=0; i<radioCount; i++)
{
radioRecords[i] = System.Gadget.Settings.read("radioRecord"+i);
splitRec(radioRecords[i]);
RadioList.options[i] = new Option(recName);
}
RadioList.selectedIndex = System.Gadget.Settings.read("selected");
SelectRecord();
}
当settings
窗口未打开时,所有信息都保存在各个小工具环境中。当我们打开此窗口时,首先需要做的就是将它们加载到我们的工作环境中,这就是我们在此函数中所做的事情。
首先,我们使用System.Gadget.Settings.read
方法从小工具环境中加载radioCount
全局变量。如果之前没有保存过radioCount
,则将我们的全局变量设置为0
。
for
循环将读取我们之前保存的电台服务器。它将电台记录读取到我们的数组中。然后我们使用splitRec
函数分割此记录。现在我们使用recName
为用于选择我们电台服务器的RadioList
创建一个新选项。
循环结束后,我们读取RadioList.selectedIndex
属性中选定的电台,这样选定的电台将在listbox
中高亮显示。所有信息都到位后,我们调用selectRecord()
函数使选定的电台服务器在窗口中可见。
我们知道如何读取我们的信息,但如何写入呢?让我们看看下一个函数来解释这部分。
System.Gadget.onSettingsClosing = function(event)
{
if(event.closeAction == event.Action.commit)
{
if(ed)
{
radioRecords[RadioList.options.selectedIndex] =
rname.value + "|" + url.value + "|" + desc.value;
ed = false;
}
System.Gadget.Settings.write("active",url.value);
System.Gadget.Settings.write("radioCount",radioCount);
System.Gadget.Settings.write("selected",oldSel);
System.Gadget.Settings.write("radioname",rname.value);
for(i=0; i<radioCount; i++)
{
System.Gadget.Settings.write("radioRecord"+i,radioRecords[i]);
}
}
event.cancel = false;
}
这是设置窗口关闭时调用的函数。我们首先检查event.closeAction
是否等于Action
提交,换句话说,我们检查是否通过单击OK按钮到达这里。如果是这种情况,我们检查ed
是否为true
。ed
的true
值由edit()
例程设置,并告知我们用户更改了记录。在这种情况下,我们需要在radioRecords
数组中创建record
字符串,以便保存更改。这些记录的结构很容易理解,我们使用HTML中输入字段的值,并用|
字符在字符串中分隔它们。我们将在稍后描述的splitRec
函数中使用此字符来分隔它们。在编辑记录的情况下,我们执行的最后一个任务是将ed
全局变量重置为false
。
现在是保存active
、radioCount
、selected
和radioname
的时候了。使用for
循环,我们现在保存radioRecords
。我们在此函数中需要做的最后一项任务是将event.cancel
设置为false
。
function AddRecord()
{
if(rname.value != "" && url.value != "")
{
radioRecords[RadioList.options.length] = rname.value + "|" + url.value + "|" + desc.value;
radioCount = RadioList.options.length+1;
RadioList.options[RadioList.options.length] = new Option(rname.value);
}
}
当我们第一次启动我们的小工具时,它根本没有电台服务器信息。即使您安装一个新的小工具实例,它也会是空的,因为每个小工具都有它的设置。所以此时我们最需要的功能是添加我们最喜欢的电台。
在我们的记录中,名称和服务器 URL 是必需的,所以我们测试这两个值是否都已输入。如果不是这种情况,则添加我们的记录没有意义。用户可以根据需要添加描述,但这取决于他。
我们在这里使用RadioList.options.length
。这给我们提供了RadioList
中的选项数量。由于我们的数组从0
开始,记录的数量也是下一个空索引,因此我们可以使用它来创建下一个radiorecord
。radioRecord
的创建方式与我在前一个函数中描述的完全相同,所以我不需要再次解释。radioCount
设置为length + 1
,我们向RadioList
添加一个新选项,其值为服务器名称。
我们的下一个函数将从listbox
中选择或取消选择服务器,并在需要时创建按钮和记录活动。
function SelectRecord()
{
if(RadioList.selectedIndex == oldSel)
{
RadioList.selectedIndex = -1;
rname.value = ""; rname.disabled = false;
url.value = ""; url.disabled = false;
desc.value = ""; desc.disabled = false;
Add.disabled = false;
Edit.disabled = true;
Del.disabled = true;
}
else
{
splitRec(radioRecords[RadioList.options.selectedIndex]);
rname.value = recName; rname.disabled = true;
url.value = recAdress; url.disabled = true;
desc.value = recDesc; desc.disabled = true;
Add.disabled = true;
Edit.disabled = false;
Del.disabled = false;
}
oldSel = RadioList.selectedIndex;
}
我检查所选选项是否等于 oldSel
。如果是这种情况,我们需要取消选择该选项。这在无数 JavaScript 初学者论坛中我已经回答过。对于 JavaScript 新手来说,selectedIndex
为 -1
表示没有选项被选中。
我们现在将记录中的字段设置为空,并将 disabled 属性设置为false
。这样我们就可以在字段中输入。我们对“添加”按钮的 disabled 属性也这样做。当没有选择电台时,我们可以添加新记录。反之亦然,当没有选择电台时,我们无法编辑或删除一个电台,因此我们将这些按钮的 disabled 属性设置为true
。
如果selectedIndex
不等于oldSel
,则表示我们从列表中选择了一个新选项。在这种情况下,我们需要用选定服务器的值填充记录的字段,并禁用这些字段,以便用户无法在其中输入。
我们使用splitRec
函数获取所选数组元素中的值。然后我们将记录移动到输入字段的值中,在这种情况下,将禁用属性设置为true
。这里的按钮与我们之前所做的正好相反,因此将“添加”按钮的属性设置为true
,将“编辑”和“删除”按钮设置为f<code>
alse。我们现在需要做的就是将oldSel
全局变量设置为selectedIndex
以供以后使用。
function edit()
{
rname.disabled = false;
url.disabled = false;
desc.disabled = false;
ed = true;
}
edit
函数非常简单,正如你所看到的。我们在这里唯一需要做的就是将字段的 disabled 属性设置为false
,这样我们就可以编辑它们。然后将全局变量ed
设置为d。这样,当用户点击OK按钮时,System.Gadget.onSettingsClosing
事件将保存更改。
function dele()
{
radioRecords.splice(RadioList.options.selectedIndex,1);
RadioList.options[RadioList.options.selectedIndex] = null;
radioCount--;
}
dele()
函数使用 splice 方法从我们的radioRecord
数组中删除选定的记录。要从radioList
中删除一个选项,我们必须将其设置为null
。如果现在我们减少radiocounter
,则选定的电台服务器将被删除。
function splitRec(work)
{
work = work.split("|");
recName = work[0];
recAdress = work[1];
recDesc = work[2];
}
我们需要创建的最后一个函数是我之前提到过的。在这里我们填充全局记录变量。我们使用“|
”字符进行分割。分割后,我们会在 work 变量中得到一个数组。
现在我们完成了!收音机小工具已经创建。现在我们只需制作一个名为 radio.zip 的 ZIP 文件,并将我们小工具目录中的所有文件和文件夹移动到此 ZIP 文件中。完成后,我们将 ZIP 文件重命名为 radio.gadget,这将是小工具的可安装版本。将其上传到您的网站或与他人分享!
正如我之前提到的,我将这个小工具保持得非常有限和基础。现在是您活跃起来,根据自己的需求进行更改的时候了。例如,制作一个音量条,或者一个在小工具图形中显示当前歌曲的文本滚动条。