65.9K
CodeProject 正在变化。 阅读更多。
Home

一个 Shoutcast 电台侧边栏小工具

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.33/5 (6投票s)

2007年5月31日

CPOL

24分钟阅读

viewsIcon

72754

downloadIcon

831

关于编写侧边栏小工具

Screenshot - ScreenShot002.jpg

引言

在这篇文章中,我想向人们介绍侧边栏小工具开发艺术。本文面向初学者,所以我尽力使代码保持简单,但需要基本的 Javascript 知识。我们将使用最基本的三个部分:小工具、弹出窗口和设置窗口。这是我第一次尝试为 codeproject 撰写文章。英语不是我的母语,所以我希望您不要太介意我的语言。

为什么选择收音机小工具

和大多数安装 Windows Vista 的人一样,我首先注意到的是侧边栏。作为 Shoutcast 收音机的拥有者,我萌生了为其设计一个特殊小工具的想法。最初的小工具变成了一个单电台应用程序,但为了这篇文章,我制作了一个你可以用于所有你喜欢的 Shoutcast 服务器的小工具。

Shoutcast 由 nullsoft 制作,所以大多数人将其与 winamp 结合使用。它也与 Windows Media Player 运行良好,所以我们将使用 ActiveX 来播放小工具中的流媒体。但在我们开始之前,让我们简单列出我们的侧边栏小工具必须要做的事情。最重要的是,标记出我们在创建它时可能遇到的问题。

  1. 该小工具必须能够连接到所有您喜欢的 Shoutcast 广播电台。为此,我们将使用设置以添加、删除和选择电台的方式。
  2. 为了文章的简洁,我将控件限制在播放、停止和音量控制。
  3. 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);
} 

请注意,我们使用 widthheight 属性来设置我们的小工具在侧边栏中的大小。width 设置为 Microsoft 建议的最大值 120 像素。您可以将其设置得更小。但当我们都使用相同的 width 时,我们的侧边栏将具有一个整齐有序的外观。如果您喜欢,可以将 height 设置得更大。一条黄金法则是“不要使用超出您实际需要的空间”。
接下来,我们将 padding 设置为0,以便我们的小工具在侧边栏中占据正确的位置。另外请注意,我们在背景图片中设置了我们的收音机图形,我们的图形大小为 120 x 96 像素,所以它不会重复。

回到 htm 文件中,我们为媒体播放器创建了一个 ID 对象。我们稍后会在 JavaScript 中使用它。
现在我们创建一些用于处理控制按钮的div标签。对于初学者来说,请注意我是如何使用onmouseoveronmouseout事件来改变图像的。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.htmSettings.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,并使用PlayControleinnerHTML将按钮更改为stop按钮。
state0时,我们使用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。音量属性是一个介于 0100 之间的整数。我以 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 文件中的例程就结束了。您可以随意尝试并让您的版本更高级。

Screenshot - ScreenShot003.jpg

制作弹出窗口

现在是时候制作我们的弹出窗口和播放列表了。这部分的 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”。这个canvasdiv用于使播放列表可见。大部分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 分割成我们制作播放列表所需的addressport。首先,我们使用 replace 方法从 URL 中删除 http://。现在我们有一个工作字符串,可以将其分割成服务器addressport。分割方法之后,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窗口。

Screenshot - ScreenShot004.jpg

设置 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()函数。另一列将处理AddEditDelete按钮。这些部分的 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是否为trueedtrue值由edit()例程设置,并告知我们用户更改了记录。在这种情况下,我们需要在radioRecords数组中创建record字符串,以便保存更改。这些记录的结构很容易理解,我们使用HTML中输入字段的值,并用|字符在字符串中分隔它们。我们将在稍后描述的splitRec函数中使用此字符来分隔它们。在编辑记录的情况下,我们执行的最后一个任务是将ed全局变量重置为false
现在是保存activeradioCountselectedradioname的时候了。使用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开始,记录的数量也是下一个空索引,因此我们可以使用它来创建下一个radiorecordradioRecord的创建方式与我在前一个函数中描述的完全相同,所以我不需要再次解释。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,这将是小工具的可安装版本。将其上传到您的网站或与他人分享!

正如我之前提到的,我将这个小工具保持得非常有限和基础。现在是您活跃起来,根据自己的需求进行更改的时候了。例如,制作一个音量条,或者一个在小工具图形中显示当前歌曲的文本滚动条。

© . All rights reserved.