一步一步学Silverlight 2系列(21):如何在Silverlight中调用JavaScript

概述

Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, Ironpython,对JSON、Web Service、WCF以及Sockets的支持等一系列新的特性。《一步一步学Silverlight 2系列》文章将从Silverlight 2基础知识、数据与通信、自定义控件、动画、图形图像等几个方面带您快速进入Silverlight 2开发。

Silverlight中内置了对于HTML、客户端脚本等的支持。很多情况下,我们编写的Web应用程序中用了一些JavaScript或者AJAX框架,我们希望能够在Silverlight调用某些脚本方法,或者说在Silverlight中触发某个脚本的执行,这时就需要用到在Silverlight中调用JavaScript,本文将简单介绍这一内容。

使用GetProperty获取脚本对象

先来看一个简单的例子,在Silverlight测试页面中放入一个div用作显示信息:

<div id="result"></div>

编写一段简单的JavaScript代码:

<script type="text/javascript">
    function Hello(message)
    {
        var resultSpan = $get("result");
        resultSpan.innerText = "Hello " + message;
    }
</script>

再编写一个简单的输入信息界面:

<StackPanel Background="#CDFCAE" Orientation="Vertical">
    <StackPanel Height="40">
        <TextBlock Text="Calling Browser Script from Silverlight"
                   Foreground="Red"></TextBlock>
    </StackPanel>
    <StackPanel Orientation="Horizontal">
        <TextBox x:Name="input" Width="340" Height="40" Margin="20 0 20 0"></TextBox>
        <Button x:Name="submit" Width="120" Height="40" Background="Red"
            Content="调 用" FontSize="20" Foreground="Red" Click="submit_Click"></Button>
    </StackPanel>
</StackPanel>

实现对脚本的调用:

private void submit_Click(object sender, RoutedEventArgs e)
{
    ScriptObject hello = HtmlPage.Window.GetProperty("Hello") as ScriptObject;
    hello.InvokeSelf(this.input.Text);
}

ScriptObject提供了任何客户端脚本的封装,不仅仅是JavaScript,使用其他的AJAX框架也可以,如jQuery等。然后调用InvokeSelf()方法,传入参数,这里ScriptObject总共提供了两个方法,Invoke和InvokeSelf,如果我们只调用脚本对象的自身,就可以使用InvokeSelf,如果脚本对象中还有其它的函数等,可以使用Invoke传入名称进行调用,两个方法的定义如下:

[SecuritySafeCritical]
public virtual object Invoke(string name, params object[] args);

[SecuritySafeCritical]
public virtual object InvokeSelf(params object[] args);

运行上面的示例:

 TerryLee_Silverlight2_0097

输入TerryLee后点击调用,可以看到确实调用了客户端脚本:

TerryLee_Silverlight2_0098 

使用CreateInstance创建脚本对象

除了使用上面所说的使用HtmlPage.Window.GetProperty方法获取脚本对象之外,还有一种替代方法,即使用HtmlPage.Window属性的CreateInstance方法。还是使用上面的示例,我们在测试页中加入如下一段脚本,使用prototype为myHello添加了显示的功能:

<script type="text/javascript">
    myHello = function(message)
    {
        this.Message = message;
    }
    myHello.prototype.Display = function()
    {
        var resultSpan = $get("result");
        resultSpan.innerText = "Hello " + this.Message;
    }
</script>

使用HtmlPage.Window.CreateInstance创建脚本对象

private void submit_Click(object sender, RoutedEventArgs e)
{
    ScriptObject script = HtmlPage.Window.CreateInstance("myHello",this.input.Text);

    object result = script.Invoke("Display");
}

运行后的效果跟上面的示例是一样的,如:

TerryLee_Silverlight2_0097

输入文本信息后:

TerryLee_Silverlight2_0099 

使用HtmlPage.Window.Eval()

最后还有一种机制,就是使用HtmlPage.Window.Eval()方法,只要我们给该方法传入一段字符串,它都会作为JavaScript来执行。做一个简单的测试,我们再修改一下上面的示例代码:

private void submit_Click(object sender, RoutedEventArgs e)
{
    HtmlPage.Window.Eval(this.input.Text);
}

运行后我们在文本框中输入一段脚本alert('TerryLee');,效果如下所示:

TerryLee_Silverlight2_0100

既然HtmlPage.Window.Eval()可以执行一段脚本,并且将执行的结果以对象形式返回,我们可以使用它来获取DOM元素。如下面这段代码:

private void submit_Click(object sender, RoutedEventArgs e)
{
    HtmlElement result = HtmlPage.Window.Eval("document.getElementById('result')") as HtmlElement;

    string message = result.GetAttribute("innerHTML");
    HtmlPage.Window.Alert(message);
}

运行后效果如下,获取的result确实就是我们定义的div。

TerryLee_Silverlight2_0101 

对AJAX框架的支持

前面说过,ScriptObject不仅仅是对JavaScript的封装,也支持其它的AJAX框架,现在我们用jQuery来测试一下,编写一小段代码:

<script type="text/javascript">
    function myHello(message)
    {
        $("#result").text("Hello " + message);
    }
</script>

调用脚本

private void submit_Click(object sender, RoutedEventArgs e)
{
    ScriptObject script = HtmlPage.Window.GetProperty("myHello") as ScriptObject;

    script.InvokeSelf(this.input.Text);
}

运行后的结果与前面的示例是一样的:

TerryLee_Silverlight2_0102 

结束语

本文介绍了在Silverlight中调用JavaScript的几种方法,下一篇我将介绍如何在JavaScript中调用Silverlight。

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
Tag标签: Silverlight
posted @ 2008-03-12 18:24 TerryLee 阅读(9971) 评论(45)  编辑 收藏 所属分类: [03]  银光点亮世界

  回复  引用    
#1楼2008-03-12 20:00 | jejwe[未注册用户]
js能没操作SL
  回复  引用  查看    
#2楼2008-03-12 20:04 | 菜菜灰      
哈哈,等了一天终于等到了,另外问下怎么制作动画。
  回复  引用  查看    
#3楼[楼主]2008-03-12 20:18 | TerryLee      
@jejwe
什么意思?:)
没看懂

  回复  引用  查看    
#4楼[楼主]2008-03-12 20:19 | TerryLee      
@菜菜灰
制作动画,用Expression Blend吧:)

  回复  引用  查看    
#5楼2008-03-12 20:21 | 菜菜灰      
Expression Blend 也没有看明白怎么制作动画
  回复  引用  查看    
#6楼[楼主]2008-03-12 20:23 | TerryLee      
@菜菜灰
呵呵,那这就是工具使用的问题了

  回复  引用    
#7楼2008-03-12 20:38 | jejwe[未注册用户]
--引用--------------------------------------------------
TerryLee: @jejwe
什么意思?:)
没看懂
--------------------------------------------------------
我是想问,能不能通过JS直接操作SL,比如触发一个SL的按纽事件


  回复  引用  查看    
#8楼[楼主]2008-03-12 20:42 | TerryLee      
@jejwe
太让我伤心了,呵呵,本文的最后一句话:

“下一篇我将介绍如何在JavaScript中调用Silverlight”

  回复  引用  查看    
#9楼2008-03-12 21:39 | 王德水      
学了一段时间的 silverlight1.0现在看来是白学了,silverlight2.0真是方便,最重要的是有智能提示,再次支持TerryLee给我们带来深入浅出的文章,幸苦了
  回复  引用  查看    
#10楼[楼主]2008-03-12 21:45 | TerryLee      
@王德水
呵呵,对Silverlight中的一些东西的理解还是有用的,呵呵,感谢你的支持:)

  回复  引用  查看    
#11楼2008-03-13 09:25 | Clark Zheng      
great work!
  回复  引用  查看    
#12楼2008-03-13 09:28 | Tristan(Guozhijian)      
不错,比之1.1 alpha方便多了

不知道 javascript调后台cs代码怎么样

  回复  引用  查看    
#13楼2008-03-13 10:19 | 小庄      
我感觉既然sl这么牛,要是用来做系统的话就没有必要用那个js了吧,用户登录以后就sl全屏模式,再来个sl的多窗口管理,都是异步模式,自然就多窗口多任务了,就像个系统的样子了;就是想问一下sl怎么管理多窗口,而且窗口中的功能操作逻辑和界面代码可以从服务器自动下载并运行?
  回复  引用  查看    
#14楼2008-03-13 10:23 | 小庄      
@Tristan(Guozhijian)
您说的cs代码指的是sl里的cs代码还是服务上的?要是sl里的当然可以,服务器端运行的cs代码应该实现不了。sl只是一个客户端技术。

  回复  引用  查看    
#15楼[楼主]2008-03-13 13:00 | TerryLee      
@Clark Zheng
谢谢:)

  回复  引用  查看    
#16楼[楼主]2008-03-13 13:00 | TerryLee      
@Tristan(Guozhijian)
您说的是在JS中调用Silverlight中的CS代码吧?今天我将会发布这部分内容:)

  回复  引用  查看    
#17楼[楼主]2008-03-13 13:02 | TerryLee      
@小庄
调用js有时候还是有用的

多窗口管理不太了解。。。

  回复  引用  查看    
#18楼2008-03-13 13:02 | Tristan(Guozhijian)      
@TerryLee
嗯,是的 :)

  回复  引用  查看    
#19楼[楼主]2008-03-13 13:04 | TerryLee      
@Tristan(Guozhijian)
晚上就发布,其实很简单,跟在ASP.NET AJAX调用WebMethod一样,呵呵,也是通过特性暴露一些方法:)

  回复  引用  查看    
#20楼2008-03-13 17:13 | Scott Xu(南方小鬼)      
添加[Scriptable]标记的吧
  回复  引用  查看    
#21楼2008-03-13 17:17 | Scott Xu(南方小鬼)      
WebApplication.Current.RegisterScriptableObject("PipeLineControl", this);
  回复  引用  查看    
#22楼[楼主]2008-03-13 17:23 | TerryLee      
@Scott Xu(南方小鬼)
对应于类型和成员分别有两个特性:ScriptableType和ScriptableMember

  回复  引用    
#23楼2008-07-14 08:14 | student_sun[未注册用户]
不错的文章!一口气看完。
  回复  引用    
#24楼2008-08-18 15:09 | Joe Zhang[未注册用户]
不错的文章,期待下一章。
  回复  引用  查看    
#25楼[楼主]2008-08-20 10:21 | TerryLee      
@student_sun
:)

  回复  引用  查看    
#26楼[楼主]2008-08-20 10:21 | TerryLee      
@Joe Zhang
下一篇好像早就有了^_^

  回复  引用  查看    
#27楼2008-10-13 12:17 | threeG      
innerText好像不行啊!!我改成innerHTML还可以!!
  回复  引用  查看    
#28楼2008-10-15 12:10 | threeG      
原来是浏览器的问题!在IE上可以,
在firefox 上都不行!!

  回复  引用  查看    
#29楼2008-11-18 17:27 | laurel's blog      
HtmlPage.Window.GetProperty("Hello")
我这句取到的是空,function是写在aspx页吧.
不知道哪错了,

  回复  引用  查看    
#30楼[楼主]2008-11-19 09:30 | TerryLee      
@laurel's blog
是的,写在aspx页面中

  回复  引用    
#31楼2008-12-02 16:44 | Z-Suker[未注册用户]
楼主是我的偶像...膜拜啊~~~~~~对楼主的景仰犹如滔滔江水连绵不绝啊~哈哈....
  回复  引用  查看    
#32楼[楼主]2008-12-08 10:28 | TerryLee      
@Z-Suker
呵呵,太客气了:)

  回复  引用    
#34楼2009-02-24 15:59 | aerolk[未注册用户]
火狐下无效 怎么解决
  回复  引用    
#35楼2009-03-19 21:45 | wolfalcon[未注册用户]
李老师
javascript的代码 是在哪个文件里写的啊?.xaml?.html?.aspx?还是哪个地方?如果单独在工程中add一个 .js文件 那么如何调用这个.js文件中的函数呢?
迷惑中.......

  回复  引用    
#36楼2009-03-19 22:17 | wolfalcon[未注册用户]
再问个问题!李老师:
能不能给写一个在silverlight中动态生成一个表格行的代码
就是有一个按钮 点一下表格就自动生成一行 表格的每个cell中内嵌一些不同的控件 比方botton textbox之类的 简单给写一个就行
万分感谢

  回复  引用    
#37楼2009-04-30 23:44 | 破浪
跟着利老师一步一步的学习,发现silverlight真的很强大。
  回复  引用    
#38楼2009-05-05 17:31 | LoveSilverlight[未注册用户]
调用这个函数:
function myHello(message)
{
$("#result").text("Hello " + message);
}
老是有问题,不知道为什么。把它修改成普通JavaScript函数就可以正常,why?

  回复  引用  查看    
#39楼2009-05-20 15:05 | xihongshibeibei      
@LoveSilverlight
把jQuery引用进去就可以了




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1102578




相关文章:

相关链接: