在之前的一篇文章中,介绍了jLight,这是一个可以帮助开发者在Silverlight中更轻松地操作DOM的库。jQuery提供了在运行时修改CSS的强大方法,而Silverlight虽然可以访问DOM,但并不像jQuery那样容易。本文中展示的所有示例都可以在这个在线演示中查看,并且代码可以从这里下载。
选择和更改属性是非常直接的。例如,使用以下代码可以设置所有标签的文本颜色为红色:
jQuery.Select("b").Css("color", "red");
Css()方法是一个扩展方法,它作用于由jQuery.Select()方法返回的jQueryObject。Css()方法接受两个参数:第一个是CSS样式属性,所有在CSS中使用的属性都可以在字符串中输入;第二个参数是想要赋予该属性的值。在这个例子中,属性是“color”,并且它被更改为“red”。
要指定想要选择的元素,可以向Select()方法添加一个:selector参数,如下一个例子所示:
jQuery.Select("b:first").Css("font-family", "sans-serif");
“:first”伪类选择器仅选择第一个元素。这个例子将第一个元素的“font-family”属性更改为“sans-serif”。
为了在Visual Studio中使用智能感知,添加了扩展方法来帮助处理伪类。在下面的示例中,将每个“Even”的“font-weight”设置为“bold”:
jQuery.Select("li.Even()").Css("font-weight", "bold");
因为Css()扩展方法返回一个jQueryObject,所以可以链式调用Css()。以下示例展示了一次性设置所有标题的“color”、“background-color”和“font-size”:
jQuery.Select(":header").Css("color", "#12FF70").Css("background-color", "yellow").Css("font-size", "25px");
在少数情况下,可能只需要更改一个样式属性。更多时候,可能想要一次性更改整个一组样式属性。可以链式调用许多Css()方法。更好的方法是向样式表中添加一个类,并在其中定义所有属性。使用AddClass()方法,可以为一组元素设置一个样式类。以下示例展示了如何将“demostyle”类添加到文档中的所有:
jQuery.Select("b").AddClass("demostyle");
移除类的操作方式相同:
jQuery.Select("b").RemoveClass("demostyle");
jLight是为了从Silverlight使用jQuery与DOM交互而构建的。jQueryObjectCss对象可以用来在Silverlight中定义不同的样式属性集。jQueryObjectCss类中定义了超过60个最常见的CSS样式属性。可以使用字符串索引器来访问所有样式属性(CssObject1[“background-color”]等于CssObject1.BackgroundColor)。在下面的代码中,定义并实例化了两个jQueryObjectCss对象:
private jQueryObjectCss CssObject1; private jQueryObjectCss CssObject2; public Demo2() { CssObject1 = new jQueryObjectCss { BackgroundColor = "Lime", Color = "Black", FontSize = "12pt", FontFamily = "sans-serif", FontWeight = "bold", MarginLeft = 150, LineHeight = "28px", Border = "Solid 1px #880000" }; CssObject2 = new jQueryObjectCss { FontStyle = "Italic", FontSize = "48", Color = "#225522" }; InitializeComponent(); }
现在,不需要链式设置所有不同的属性,只需要将一个jQueryObjectCss对象传递给Css()方法即可。在这种情况下,所有元素都设置为匹配此对象:
jQuery.Select("li").Css(CssObject1);
当使用jQueryObjectCss对象时,仍然可以进行链式操作。在以下示例中,所有标题都被赋予了蓝色背景色,最后一个设置为匹配CssObject2:
jQuery.Select(":header").Css(new jQueryObjectCss { BackgroundColor = "Blue" }).Eq(-1).Css(CssObject2);
让Silverlight调用JavaScript,然后让JavaScript调用Silverlight需要大量的管道代码。一切都必须注册,字符串来回传递以执行JavaScript。jLight使得这种操作变得如此简单,以至于变得有趣。在许多情况下,jQuery可以调用一个函数来决定要做什么,例如根据复杂表达式设置样式类。jLight也可以做到这一点,但回调方法在Silverlight中定义。
以下示例为每个元素调用function()方法。回调方法必须接受一个jQueryObject,一个整数和一个字符串作为参数。在这种情况下,jLight与实际的jQuery实现有所不同。jQuery仅使用index和className参数。jQueryObject被添加以简化访问元素的属性和属性。
private void button1_Click(object sender, RoutedEventArgs e) { jQuery.Select("li").AddClass(function); } private string function(jQueryObject obj, int index, string className) { if (obj.Text[0] == 'D' || obj.Text[0] == 'M') return "demostyle"; return null; }
想展示的最后一件事使用了更多的Silverlight和更少的jLight,但它展示了组合的强大。使用带有缓动函数的Storyboard动画一个样式属性。首先定义一个依赖属性。在这种情况下,它是一个名为Intensity的double。通过处理更改事件,使用jQuery设置颜色。
public double Intensity { get { return (double)GetValue(IntensityProperty); } set { SetValue(IntensityProperty, value); } } public static readonly DependencyProperty IntensityProperty = DependencyProperty.Register("Intensity", typeof(double), typeof(Demo3), new PropertyMetadata(0.0, IntensityChanged)); private static void IntensityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var i = (byte)(double)e.NewValue; jQuery.Select("span").Css("color", string.Format("#{0:X2}{0:X2}{0:X2}", i)); }
必须创建一个动画。这段代码定义了一个Storyboard,它使用一个关键帧,并使用弹跳缓动函数作为缓动函数。动画设置为目标是之前定义的Intensity依赖属性。
private Storyboard CreateAnimation(double value) { Storyboard storyboard = new Storyboard(); var da = new DoubleAnimationUsingKeyFrames(); var d = new EasingDoubleKeyFrame { EasingFunction = new BounceEase(), KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1.0)), Value = value }; da.KeyFrames.Add(d); Storyboard.SetTarget(da, this); Storyboard.SetTargetProperty(da, new PropertyPath(Demo3.IntensityProperty)); storyboard.Children.Add(da); return storyboard; }
public Demo3() { InitializeComponent(); Intensity = 128; } private void button2_Click(object sender, RoutedEventArgs e) { CreateAnimation(255).Begin(); } private void button3_Click(object sender, RoutedEventArgs e) { CreateAnimation(0).Begin(); }