Home | | Internet & World Wide Web HOW TO PROGRAM | | Internet Programming | | Web Programming | Using JavaScript for Event Handling and DOM Manipulation

Chapter: Internet & World Wide Web HOW TO PROGRAM - Rich Internet Application Client Technologies - Microsoft ilverlight and Rich Internet Applications

Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail

Using JavaScript for Event Handling and DOM Manipulation

The JavaScript code-behind file, Page.xaml.js (Fig. 19.13), defines the event handlers for the various elements in the XAML.

4.Using JavaScript for Event Handling and DOM Manipulation

 

The JavaScript code-behind file, Page.xaml.js (Fig. 19.13), defines the event handlers for the various elements in the XAML. In the event handlers, we use JavaScript to manip-ulate the Silverlight DOM, similar to how we manipulated the XHTML DOM in Chap-ter 12 and the XML DOM in Chapter 14. To edit the JavaScript code files, use your preferred text editor.

 

1    // Fig. 19.13: Page.xaml.js

 

2    // JavaScript code-behind for Movie Viewer.

3              

4    // variables for accessing the Silverlight elements

 

5    var host; // allow access to host plug-in

 

6    var Page;

 

7    var movieMediaElement;

 

8    var downloadProgressRectangle;

 

9    var timeText;

 

10  var timelineRectangle;

 

11  var playHead;

 

12  var timelineTimer;

 

13  var playButton;

 

14  var pauseButton;

 

15  var playOverlayCanvas;

 

16  var timelineTimer;

 

17  var volumeCanvas;

 

18  var volumeHead;

 

19  var crazyDogButton;

 

20  var gravityButton;

 

21  var apollo15Button;

 

22  var f35Button;

 

23  var controls;

 

24  var fullscreenButton;

 

25  var timeCanvas;

 

26  var titleText;

 

27  var playOverlayCanvasListener; // token for event listener

28          

29  function canvasLoaded( sender, eventArgs )

30  {

 

31         // set variables to more easily access the Silverlight elements

 

32         host = sender.getHost(); // allow access to host plug-in

 

33         Page = sender.findName( "Page" );

 

34         movieMediaElement = sender.findName( "movieMediaElement" );

 

35         downloadProgressRectangle = sender.findName(

 

36               "downloadProgressRectangle" );

 

37         timeText = sender.findName( "timeText" );

 

38         timelineRectangle = sender.findName( "timelineRectangle" );

 

39         playHead = sender.findName( "playHead" );

 

40         timelineTimer = sender.findName( "timelineTimer" );

 

41         playButton = sender.findName( "playButton" );

 

42         pauseButton = sender.findName( "pauseButton" );

 

43         playOverlayCanvas = sender.findName( "playOverlayCanvas" );

 

44         volumeCanvas = sender.findName( "volumeCanvas" );

 

45         volumeHead = sender.findName( "volumeHead" );

 

46         crazyDogButton = sender.findName( "crazyDogButton" );

 

47         gravityButton = sender.findName( "gravityButton" );

 

48         apollo15Button = sender.findName( "apollo15Button" );

 

49         f35Button = sender.findName( "f35Button" );

 

50         controls = sender.findName( "controls" );

 

51         fullscreenButton = sender.findName( "fullscreenButton" );

 

52         timeCanvas = sender.findName( "timeCanvas" );

 

titleText = sender.findName( "titleText" );

55        // add an event handler for the onFullScreenChange event

 

56        host.content.onFullScreenChange = onFullScreenChangedHandler;

57          

58        // start the timer

 

59        timelineTimer.begin();

 

60   } // end function canvasLoaded

61          

62   // timelineTimer event handler

 

63   function updateTime()

64   {

 

65        // get the video's current position in seconds

 

66        var elapsedTime = movieMediaElement.position.Seconds;

 

67        var hours = convertToHHMMSS( elapsedTime )[ 0 ]; // saves hours

 

68        var minutes = convertToHHMMSS( elapsedTime )[ 1 ]; // saves minutes

 

69        var seconds = convertToHHMMSS( elapsedTime )[ 2 ]; // saves seconds

70          

71        // set text of timeText to current time in hh:mm:ss format

 

72        timeText.text = hours + ":" + minutes + ":" + seconds;

73

74        // set width of downloadProgressRectangle

 

75        downloadProgressRectangle.width = movieMediaElement.downloadProgress *

 

76               timelineRectangle.width;

77

78        // if the movie is playing, place the playHead at a

 

79        // position representing the playback progress

 

80        if ( movieMediaElement.position.Seconds &&

 

81               movieMediaElement.naturalDuration )

82        {

 

83                 playHead[ "Canvas.Left" ] = ( ( movieMediaElement.position.Seconds /

 

84                      movieMediaElement.naturalDuration.Seconds ) *

 

85                      timelineRectangle.Width ) + timelineRectangle[ "Canvas.Left" ];

 

86        } // end if

87

88        // if movie is not playing, place the playHead at the beginning

89        else

90        {

 

91               playHead[ "Canvas.Left" ] = timelineRectangle[ "Canvas.Left" ];

 

92        } // end else

93

94        // if download is incomplete or movie is playing

 

95        if ( movieMediaElement.downloadProgress != 1 ||

 

96               movieMediaElement.CurrentState == "Playing" )

97        {

 

98               timelineTimer.begin();  // run timelineTimer again

 

99        } // end if

100  } // end function updateTime

101

102     // handle play and pause buttons

 

103     function playAndPauseButtonEventHandler( sender, eventArgs )

104     {

 

105     // check the CurrentState of the movie;

 

// pause if playing, play if paused or stopped

107     if ( movieMediaElement.CurrentState == "Playing" )

108     {

 

109            movieMediaElement.pause();

110

111            playButton.Visibility = "Visible"; // show play button

 

112            pauseButton.Visibility = "Collapsed"; // hide pause button

113     } // end if

114     else

115     {

 

116            movieMediaElement.play();

 

117            timelineTimer.begin(); // start timelineTimer again

 

118            pauseButton.Visibility = "Visible"; // show pause button

 

119            playButton.Visibility = "Collapsed"; // hide play button

 

120              playOverlayCanvas.Visibility = "Collapsed"; // hide "Play" overlay

121     } // end if

 

122     } // end function playAndPauseButtonEventHandler

123

124     // handle stop button

 

125     function stopButtonEventHandler( sender, eventArgs )

126     {

 

127     movieMediaElement.stop(); // stop the movie

 

128     playButton.Visibility = "Visible"; // show play button

 

129     pauseButton.Visibility = "Collapsed"; // hide pause button

130      

131     // show "Play" overlay

 

132     playOverlayCanvas.Visibility = "Visible";

 

133     updateTime();

 

134     } // end function stopButtonEventHandler

135      

136     // handle MediaOpened event

 

137     function movieOpenedHandler( sender, eventArgs )

138     {

 

139     timelineTimer.begin();

140

141     // show "Play" overlay

 

142     playOverlayCanvas.Visibility = "Visible";

 

143     } // end function movieOpenedHandler

144

145     // handle when movie has reached end

 

146     function movieEndedHandler( sender, eventArgs )

147     {

 

148     movieMediaElement.stop(); // stop the movie

 

149     playButton.Visibility = "Visible"; // show play button

 

150     pauseButton.Visibility = "Collapsed"; // hide pause button

151      

152     // show "Play" overlay

 

153     playOverlayCanvas.Visibility = "Visible";

 

154     updateTime();

 

155     } // end function movieEndedHandler

156

157     function movieThumbHandler ( sender, eventArgs ) // a thumb was clicked

158     {

 

movieMediaElement.stop(); // stop movie

160     playButton.Visibility = "Visible"; // show play button

 

161     pauseButton.Visibility = "Collapsed"; // hide pause button

162      

163     switch ( sender.name )

164     {

 

165            case "crazyDogButton": // open Crazy Dog video

 

166                   movieMediaElement.source = "bailey.wmv";

167                   break;

 

168            case "gravityButton": // open Gravity video

 

169                   movieMediaElement.source = "featherAndHammer.wmv";

170                   break;

 

171            case "apollo15Button": // open Apollo 15 video

 

172                   movieMediaElement.source = "apollo15Launch.wmv";

173                   break;

 

174            case "f35Button": // open F35 Landing video

 

175                   movieMediaElement.source = "F35.wmv";

176                   break;

 

177     } // end switch

 

178     } // end function movieThumbHandler

179

180     // handle toggle full-screen button by toggling fullScreen state

 

181     function toggleFullScreen( sender, eventArgs )

182     {

 

183     host.content.fullScreen = !host.content.fullScreen;

 

184     } // end function toggleFullScreen

185

186     // handle onFullScreenChange event

 

187     function onFullScreenChangedHandler( sender, eventArgs )

188     {

 

189     // update layout based on current dimensions

 

190     updateLayout( host.content.actualWidth,

 

191            host.content.actualHeight );

192

193     // update time and timeline

 

194     updateTime();

 

195     } // end function onFullScreenChangedHandler

196      

197     // reposition and resize elements based on new dimensions

 

198     function updateLayout( width, height )

199     {

 

200     // resize and reposition the elements based on the screen dimensions

 

201     Page.width = width;

 

202     Page.height = height;

 

203     movieMediaElement.width = width;

 

204     movieMediaElement.height = height - 220;

 

205     movieMediaElement[ "Canvas.Left" ] =

 

206            ( width / 2 ) - ( ( movieMediaElement.width ) / 2 );

 

207     movieMediaElement[ "Canvas.Top" ] =

 

208            ( ( height - 220 ) / 2 ) - ( movieMediaElement.height / 2 );

 

209     controls.width = width;

 

210     playOverlayCanvas[ "Canvas.Left" ] =

 

( width / 2 ) - ( ( playOverlayCanvas.width ) / 2 );

212     playOverlayCanvas[ "Canvas.Top" ] =

 

213            ( ( height - 220 ) / 2 ) - ( playOverlayCanvas.height / 2 );

 

214       controls[ "Canvas.Left" ] = ( width / 2 ) - ( ( controls.width ) / 2 );

 

215     controls[ "Canvas.Top" ] = height - controls.height;

 

216     timelineRectangle.width = controls.width - 235;

 

217     fullscreenButton[ "Canvas.Left" ] = controls.width - 55;

 

218     timeCanvas[ "Canvas.Left" ] = controls.width - 140;

 

219     volumeCanvas[ "Canvas.Left" ] = controls.width - 22;

 

220     titleText[ "Canvas.Left" ] =

 

221            ( width / 2 ) - ( ( titleText.width ) / 2 );

 

222     } // end function updateLayout

223

224     // handle timelineCanvas's MouseLeftButtonDown event

 

225     function timelineHandler( sender, eventArgs )

226     {

 

227     // determine new time from mouse position

 

228     var elapsedTime = ( ( eventArgs.getPosition( timelineRectangle ).x ) /

 

229            timelineRectangle.Width ) *

 

230            movieMediaElement.NaturalDuration.seconds;

 

231     var hours = convertToHHMMSS( elapsedTime )[ 0 ]; // Saves hours

 

232     var minutes = convertToHHMMSS( elapsedTime )[ 1 ]; // Saves minutes

 

233     var seconds = convertToHHMMSS( elapsedTime )[ 2 ]; // Saves seconds

 

234     movieMediaElement.Position = hours + ":" + minutes + ":" + seconds;

 

235     updateTime();

 

236     } // end function timelineHandler

237

238     // handle volume's MouseLeftButtonDown event

 

239     function volumeHandler( sender, eventArgs )

240     {

 

241     movieMediaElement.volume = 1 - ( ( eventArgs.getPosition(

242            volumeCanvas ).y ) / 30 );

 

243     volumeHead[ "Canvas.Top" ] =

 

244            eventArgs.getPosition( volumeCanvas ).y;

 

245     } // end function volumeHandler

246

247     // get the hours, minutes and seconds of the video's current position

 

248     // Date object converts seconds to hh:mm:ss format

 

249     function convertToHHMMSS( seconds )

250     {

 

251     var datetime = new Date( 0, 0, 0, 0, 0, seconds );

 

252     var hours = datetime.getHours(); // saves hours to var

 

253     var minutes = datetime.getMinutes(); // saves minutes to var

 

254     var seconds = datetime.getSeconds(); // saves seconds to var

255

256     // ensure hh:mm:ss format

257     if ( seconds < 10 )

258     {

 

259               seconds = "0" + seconds;

260     } // end if

261

262     if ( minutes < 10 )

{

264               minutes = "0" + minutes;

265      } // end if

266

267      if ( hours < 10 )

268      {

 

269             hours = "0" + hours;

270      } // end if

271

272      return [ hours, minutes, seconds ]

 

273    } // end function convertToHHMMSS

 

Fig. 19.13 | JavaScript code-behind file for Movie Viewer.

 

 

Handling Events and Accessing XAML Elements in JavaScript

 

Lines 5–27 declare variables that our event handler functions use to access the XAML el-ements in our video player. In the canvasLoaded function (lines 29–60), which handles the Page Canvas’s Loaded event (Fig. 19.12, line 6), these variables are set to reference their corresponding XAML elements using the sender’s findName method (lines 33–53). Every event handler receives sender and eventArgs parameters. The sender parameter is a reference to the element with which the user interacted, and the eventArgs parameter passes information about the event that occurred. Line 32 sets the host variable to the Sil-verlight plug-in object using the getHost method. This allows us to access properties of the Silverlight plug-in, such as its screen dimensions, throughout the program. Line 56 registers an event handler for the plug-in’s onFullScreenChange event. Line 59 calls the timelineTimer Storyboard’s begin function, to start the Storyboard that we are using as a timer. When this Storyboard’s Completed event (Fig. 19.12, line 8) occurs—i.e., its 0.1-second-long animation completes (Fig. 19.12, lines 9–14)—the event handler update-Time (lines 63–100) is invoked.

 

Creating a Timer

The updateTime function (lines 63–100) updates the timeText, the downloadProgress-Rectangle, the playHead, and starts the timelineTimer again if necessary. It uses the con-vertToHHMMSS function (lines 249–273) to convert the movieMediaElement’s position.Seconds—its elapsed time in seconds—to hours, minutes and seconds (lines 66–69), then displays that time in hh:mm:ss format in the timeText textBlock (line 72). The updateTime function also updates the download progress indicator (lines 75–76) by setting the width of the downloadProgressRectangle to the width of the timelineRect-angle multiplied by the movieMediaElement’s downloadProgress, which is a value from 0 to 1 representing the fraction of the video that has downloaded so far. Lines 80–81 check whether movieMediaElement’s naturalDuration and position.Seconds properties exist.

 

If they do, lines 83–85 set the playHead’s position to the current playback position in the video. This is accomplished by setting the playHead’s Canvas.Left attribute to the sum of the timelineRectangle’s Canvas.Left attribute and the width of the timelineRect-angle multiplied by the ratio of current time (movieMediaElement.position.Seconds) and total time (movieMediaElement.naturalDuration.Seconds). Left is a dependency property of Canvas, meaning that the Left value is relative to that of the Canvas. Since the Canvas.Left dependency property already has a dot in its notation, we must enclose the attribute name in quotes and square brackets, as in element["attributeName"]. If mov ieMediaElement’s naturalDuration and position.Seconds attributes do not exist, line 91 sets the playHead’s Canvas.Left attribute to be equal to the timelineRectangle’s to indicate that the movie has not started playing. Finally, lines 95–99 check whether the download is not finished or the movie is playing, in which case it calls timelineTimer’s begin function to run the timer again. This way, the downloadProgressRectangle and playHead will be updated.

 

Handling Button Events

 

The playAndPauseButtonEventHandler function (lines 103–122) handles the play and pause buttons’ MouseLeftButtonDown events (Fig. 19.12, lines 71 and 139). Line 107 checks whether the movieMediaElement is currently playing. If it is, the video should be paused and the play button should be shown. If not, lines 116–120 play the video, start the timelineTimer, show the pause button and hide the playOverlayCanvas.

 

The stopButtonEventHandler function (lines 125–134) handles the stop button. It stops the video (line 127), then shows the play button and the Play overlay button (lines 128–132). Finally, it calls the updateTime function to ensure that the timeText Text-Block displays 00:00:00.

 

Function movieThumbHandler (lines 157–178) handles the movie thumbnail buttons. Lines 159–161 stop the video and show the play button. Lines 163–177 contain a switch statement that checks the sender element’s name attribute (the name of the button that was clicked) and sets the Source of movieMediaElement to the corresponding video file.

 

Adding a Full-Screen Feature

Function toggleFullScreen (lines 181–184) handles the full-screen button. Line 183 sets the Silverlight plug-in’s fullScreen attribute to the opposite of its previous value. This means that if the plug-in was previously in full-screen mode, it will switch to windowed mode, and if it was previously in windowed mode, it will switch to full-screen mode.

 

The onFullScreenChangeHandler function (lines 208–216) handles the onFull- ScreenChange event. Lines 190–191 uses the updateLayout function to update the layout of the application based on its current width and height. Then, line 194 calls the updateTime function.

 

Dynamically Changing XAML Layout

Function updateLayout (lines 198–222) repositions the user interface elements relative to the width and height parameters. Lines 201–202 set the width and height of the Page Canvas to the width and height parameters. Lines 203–204 set the width and height of movieMediaElement to the width parameter and the height parameter minus 220 (leaving room for the controls). Lines 205–208 move the movieMediaElement in the application.

 

Line 209 sets the width of the controls Canvas. Lines 210–213 center the playOverlay-Canvas over the movieMediaElement. Lines 214–215 center the controls at the bottom of the application. Line 216 sets the width of the timelineRectangle to be the width of the controls Canvas minus 235, to allow room for the other controls. Lines 217–219 move the full-screen button, timeCanvas and volumeCanvas to the right side of the controls Canvas. Finally, lines 220–221 center titleText at the top of the application.

 

The movieOpenedHandler function (lines 137–143) handles movieMediaElement’s MediaOpened event (Fig. 19.12, line 205). Line 139 starts the timelineTimer to update the loading progress rectangle, and line 142 shows the playOverlayCanvas.

The movieEndedHandler function (lines 146–155) handles the movieMediaElement’s MediaEnded event (Fig. 19.12, line 204). It stops the video (line 148), which resets the playback position to the beginning, then shows the play button and hides the pause button (lines 149–150). Lines 153 shows the playOverlayCanvas. Finally, line 154 calls the

updateTime function to ensure that the timeText textBox displays 00:00:00.

 

Creating a Timeline for a MediaElement

 

The timelineHandler function (lines 225–236) handles the downloadProgressRectan-gle’s MouseLeftButtonDown event (Fig. 19.12, line 132). Lines 228–234 set elapsedTime to the position that was clicked on the timeline, convert the number of seconds to hh:mm:ss format using the convertToHHMMSS function and set the Position of the movieMediaElement to that time string. Finally, line 235 calls the updateTime function to show the new position.

 

Controlling Volume of a MediaElement

Function volumeHandler (lines 239–245) handles the volumeCanvas’s MouseLeftButtonDown event (Fig. 19.12, line 118). Lines 241–242 set movieMediaElement’s volume prop-erty based on the position the user clicked on the volumeCanvas. We convert the y-coordinate of the mouse relative to the volume rectangle to a value between 0 and 1 (0 being muted and 1 being full volume). Lines 243–244 move the volumeHead to the new position.


Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail


Copyright © 2018-2020 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.