Dela via


Part 1: Create a "Hello, world" app (HTML)

[ This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation ]

This tutorial teaches you how to create a simple "Hello, world" Windows Store app using JavaScript. It's the first tutorial in a series of 5 that teaches you what you need to know to build Windows Store apps.

In this tutorial, you learn how to:

  • Create a new project
  • Add HTML content to your start page
  • Handle touch, pen, and mouse input
  • Switch between the light and dark style sheets
  • Create your own custom styles
  • Use a Windows Library for JavaScript control

We show you how to create a Windows Store app using HTML, JavaScript, and CSS.

Tip  

If you want to skip the tutorial and go straight to the code, see Getting started with JavaScript: Complete code for the tutorial series.

 

Before you start...

  • To complete this tutorial, you need Windows 8.1 and Microsoft Visual Studio Express 2013 for Windows. To download them, see the Downloads page.
  • You also need a developer license. For instructions, see Get a developer license.

Step 1: Create a new project in Visual Studio

Let's create a new app named HelloWorld. Here's how:

  1. Launch Visual Studio Express 2013 for Windows.

    The Visual Studio Express 2013 for Windows start screen appears.

    (Going forward, we refer to Visual Studio Express 2013 for Windows as just "Visual Studio".)

  2. On the File menu, select New Project.

    The New Project dialog appears. The left pane of the dialog lets you pick the type of templates to display.

  3. In the left pane, expand Installed, then expand Templates, then expand JavaScript and select the Windows Store template type. (If you’re using Visual Studio 2013 with Update 2 or later, expand JavaScript > Store Apps and select the Windows Apps template type.) The dialog's center pane displays a list of project templates for JavaScript.

    For this tutorial, we use the Blank App template. This template creates a minimal Windows Store app that compiles and runs, but contains no user interface controls or data. We'll add controls and data to the app over the course of these tutorials.

  4. In the center pane, select the Blank App template.

  5. In the Name text box, enter "HelloWorld".

  6. Uncheck the Create directory for solution checkbox.

  7. Click OK to create the project.

    Visual Studio creates your project and displays it in the Solution Explorer.

Although the Blank App is a minimal template, it still contains a handful of files:

  • A manifest file (package.appxmanifest) that describes your app (its name, description, tile, start page, splash screen, and so on) and lists the files that your app contains.
  • A set of large and small logo images (logo.png and smalllogo.png) to display in the start screen.
  • An image (storelogo.png) to represent your app in the Windows Store.
  • A splash screen (splashscreen.png) to show when your app starts.
  • CSS and code files for the WinJS (inside the References folder).
  • A start page (default.html) and an accompanying JavaScript file (default.js) that run when your app starts.

To view and edit the files, double-click the file in the Solution Explorer.

These files are essential to all Windows Store apps using JavaScript. Any project that you create in Visual Studio contains them.

Step 2: Launch the app

At this point, we created a very simple app. If you want to see what it looks like, press F5 to build, deploy, and start your app. A default splash screen appears first. The splash screen is defined by an image (splashscreen.png) and a background color (specified in our app's manifest file). We don't cover it here, but it's easy to customize your splash screen. (To find out how, see Adding a splash screen.)

The splash screen disappears, and then our app appears. It contains a black screen with the text "Content goes here".

There is no button or command to close the app. To close the app, slide from the top edge toward the bottom edge of the screen or press Alt+F4. Go to the Start screen; notice that deploying the app adds its tile to the last group on the Start screen. To run the app again, tap or click its tile on the start screen or press F5 in Visual Studio to run the app in the debugger.

It doesn't do much—yet—but congratulations, you've built your first Windows Store app!

To stop debugging the app, press Alt+Tab to return to Microsoft Visual Studio. In Visual Studio, click Debug > Stop debugging to close the app. You can't edit in Visual Studio while you're debugging.

For more info about different ways to launch your app in Visual Studio, see Running Windows Store apps from Visual Studio.

Step 3: Modify your start page

One of the files that Visual Studio created for us is default.html, our app's start page. When the app runs, it displays the content of its start page. The start page also contains references to the app's code files and style sheets. Here's the start page that Visual Studio created for us:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>HelloWorld</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.2.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.2.0/js/ui.js"></script>

    <!-- HelloWorld references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body>
    <p>Content goes here</p>
</body>
</html>

Let's add some new content to your default.html file. Just as you would add content to any other HTML file, you add your content inside the body element. You can use HTML5 elements to create your app (with a few exceptions). That means you can use HTML5 elements like h1, p, button, div, and img.

To modify your start page

  1. Replace the existing content in the body element with a first-level heading that says "Hello, world!", some text that asks the user's name, an input element to accept the user's name, a button, and a div element. Assign IDs to the input, the button, and the div.

    <body>
        <h1>Hello, world!</h1>
        <p>What's your name?</p>
        <input id="nameInput" type="text" />
        <button id="helloButton">Say "Hello"</button>
        <div id="greetingOutput"></div>
    </body>
    
  2. Run the app.

    You can write in the input element, but right now, clicking the button doesn't do anything. Some objects, such as button, can send messages when certain events occur. These event messages give you the opportunity to take some action in response to the event. You put code to respond to the event in an event handler method.

    In the next steps, we create an event handler for the button that displays a personalized greeting. We add our event handler code to our default.js file.

Step 4: Create an event handler

When we created our new project, Visual Studio created a /js/default.js file for us. This file contains code for handling your app's life cycle, a concept that we explain in Part 2: Manage app lifecycle and state. It's also where you write additional code that provides interactivity for your default.html file.

Open the default.js file.

Before we start adding our own code, let's take a look at the first and the last few lines of code in the file:

(function () {
    "use strict";

     // Omitted code 

 })(); 

You might be wondering what's going on here. These lines of code wrap the rest of the default.js code in a self-executing anonymous function.

Now that you know what it does, you're probably wondering why we wrap our code in a self-executing anonymous function. It's because this makes it easier to avoid naming conflicts or situations where you accidently modify a value that you didn't intend to modify. It also keeps unnecessary identifiers out of the global namespace, which helps performance. It looks a little strange, but it's a good programming practice.

The next line of code turns on strict mode for your JavaScript code. Strict mode provides additional error checking for your code. For example, it prevents you from using implicitly declared variables or assigning a value to a read-only property.

Take a look at the rest of the code in default.js. It handles your app's activated and checkpoint events. We go into more detail about these events later. For now, just know that the activated event fires when your app starts.

Let's define an event handler for your button. Our new event handler gets the user's name from the nameInputinput control and uses it to output a greeting to the greetingOutputdiv element that you created in the last section.

Using events that work for touch, mouse, and pen input

With Windows 8.1, you don’t need to worry about the differences between touch, mouse, and other forms of pointer input. You can just use events that you know, like click, and they work for all forms of input.

Tip   Your app can also use the new MSPointer* and MSGesture* events, which work for touch, mouse, and pen input and can provide additional info about the device that triggered the event. For more info, see Responding to user interaction and Gestures, manipulations, and interactions.

 

Let's go ahead and create the event handler.

To create the event handler

  1. In default.js, after the app.oncheckpoint event handler and before the call to app.start, create a click event handler function named buttonClickHandler that takes a single parameter named eventInfo.

        function buttonClickHandler(eventInfo) {
    
        }
    
  2. Inside our event handler, retrieve the user's name from the nameInputinput control and use it to create a greeting. Use the greetingOutputdiv to display the result.

        function buttonClickHandler(eventInfo) {
            var userName = document.getElementById("nameInput").value;
            var greetingString = "Hello, " + userName + "!";
            document.getElementById("greetingOutput").innerText = greetingString; 
        }
    

We added our event handler to default.js. Now we need to register it.

Step 5: Register the event handler when your app launches

The only thing we need to do now is register the event handler with the button. The recommended way to register an event handler is to call addEventListener from our code. A good place to register the event handler is when our app is activated. Fortunately, Visual Studio generated some code for us in our default.js file that handles our app's activation: the app.onactivated event handler. Let's take a look at this code.

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
            args.setPromise(WinJS.UI.processAll());
        }
    };

Inside the onactivated handler, the code checks to see what type of activation occurred. There are many different types of activations. For example, your app is activated when the user launches your app and when the user wants to open a file that is associated with your app. (For more info, see Application lifecycle.)

We're interested in the launch activation. An app is launched whenever it is not running and then a user activates it.

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {

If the activation is a launch activation, the code checks to see how the app was shut down the last time it ran.


            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }

Then it calls WinJS.UI.processAll.


            args.setPromise(WinJS.UI.processAll());           
        }
    };

It calls WinJS.UI.processAll regardless of whether the app had been shut down in the past or whether this is the very first time it's being launched. The WinJS.UI.processAll is enclosed in a call to the setPromise method, which makes sure the splash screen isn't taken down until the app's page is ready.

Tip   The WinJS.UI.processAll function scans your default.html file for WinJS controls and initializes them. So far, we haven't added any of these controls, but it's a good idea to leave this code in case you want to add them later. To learn more about WinJS controls, see Quickstart: Adding WinJS controls and styles.

 

A good place to register event handlers for non-WinJS controls is just after the call to WinJS.UI.processAll.

To register your event handler

  • In the onactivated event handler in default.js, retrieve helloButton and use addEventListener to register our event handler for the click event. Add this code after the call to WinJS.UI.processAll.

        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
                }
                args.setPromise(WinJS.UI.processAll());
    
                // Retrieve the button and register our event handler. 
                var helloButton = document.getElementById("helloButton");
                helloButton.addEventListener("click", buttonClickHandler, false);
    
            }
        };
    

Here's the complete code for our updated default.js file:

// For an introduction to the Blank template, see the following documentation:
// https://go.microsoft.com/fwlink/p/?linkid=232509
(function () {
    "use strict";

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize
                // your application here.
            } else {
                // TODO: This application has been reactivated from suspension.
                // Restore application state here.
            }
            args.setPromise(WinJS.UI.processAll());

            // Retrieve the button and register our event handler. 
            var helloButton = document.getElementById("helloButton");
            helloButton.addEventListener("click", buttonClickHandler, false);
        }
    };

    app.oncheckpoint = function (args) {
        // TODO: This application is about to be suspended. Save any state
        // that needs to persist across suspensions here. You might use the
        // WinJS.Application.sessionState object, which is automatically
        // saved and restored across suspension. If you need to complete an
        // asynchronous operation before your application is suspended, call
        // args.setPromise().
    };

    function buttonClickHandler(eventInfo) {

        var userName = document.getElementById("nameInput").value;
        var greetingString = "Hello, " + userName + "!";
        document.getElementById("greetingOutput").innerText = greetingString;
    }

    app.start();
})();

Run the app. When you enter your name in the text box and click the button, the app displays a personalized greeting.

Note   If you're curious as to why we use addEventListener to register our event in code rather than setting the onclick event in our HTML, see Coding basic apps for a detailed explanation.

 

Step 6: Style your start page

It's easy to customize the look and feel of your app. Windows Store apps let you use Cascading Style Sheets, Level 3 (CSS3), much like you would for a website.

The default.html that Visual Studio created for us contains a reference to the WinJS style sheet:

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />

What does this style sheet do? Quite a bit! It provides these benefits:

  • A set of styles that automatically give our app the Windows 8 (and later) look and feel. Just including the style sheet will make our controls look great and they'll work with touch-based displays, too.
  • Automatic support for high-contrast modes. These styles were designed with high contrast in mind, so when our app runs on a device in high-contrast mode, it displays properly.
  • Automatic support for other languages. The WinJS style sheets automatically select the correct font for every language that Windows 8 supports. You can even use multiple languages in the same app and they are displayed properly.
  • Automatic support for other reading orders. It automatically adjusts HTML and WinJS controls, layouts, and styles for languages that read from right to left.

By default, each HTML page in your project contains a reference to the dark style sheet. The WinJS also provides a light style sheet. Let's try it out and see what it looks like.

To switch to the light style sheet

  1. In your default.html file, replace the reference to the dark style sheet:

        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
    

    With this one:

        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.2.0/css/ui-light.css" rel="stylesheet" />
    
  2. Run your app. It now uses the light style sheet.

Which style sheet should you use? Whichever one you want. For apps that mostly display images or video, we recommend using the dark style sheet, and for apps that contain a lot of text, we recommend using the light style sheet. (If you're using a custom color scheme, use the style sheet that goes best with your app's look and feel.)

Creating your own styles

If you want to customize the look and feel of your app, you don't have to throw out the WinJS styles and start over from scratch. It's easy to make incremental changes by overriding the styles you want to change.

In fact, it's better to override the WinJS styles rather than creating your own styles. When your app runs in high-contrast mode, any changes to the colors in the default styles are automatically overridden by a color scheme that supports high contrast.

You can override any style in the default style sheet by creating your own style sheet and including it after the WinJS style sheet. The Blank App template does this for you. It creates a style sheet named default.css that you can use to create your own styles.

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.2.0/css/ui-light.css" rel="stylesheet" /> 
    <script src="//Microsoft.WinJS.2.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.2.0/js/ui.js"></script>

    <!-- HelloWorld references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>

Let's create some of our own styles.

  1. First, lets add some div elements and classes to our HTML to make it easier to style.

    1. In Visual Studio, open the default.html file.

    2. Set your page header's class attribute to "headerClass". Create a div element and use it to contain your page's main content. Give it a class setting of "mainContent".

      <body>
          <h1 class="headerClass">Hello, world!</h1>
          <div class="mainContent">
              <p>What's your name?</p>
              <input id="nameInput" type="text" />
              <button id="helloButton">Say "Hello"</button>
              <div id="greetingOutput"></div>
          </div>
      </body>
      
  2. Now lets define our styles. Open the default.css file.

    Right now it's mostly blank:

    body {
    }
    
  3. The heading has a top margin of 45 pixels and a left margin of 120 pixels. The content area also has a left margin of 120 pixels, a top margin of 31 pixels, and a bottom margin of 50 pixels.

    Define the headerClass and mainContent classes and set their margins to follow these guidelines. Also, create a style for the greetingOutputdiv that sets its height to 20 pixels and its bottom margin to 40 pixels. For more info, see Lay out an app page.

    body {
    }
    
    .headerClass {
        margin-top: 45px;
        margin-left: 120px; 
    }
    
    .mainContent {
        margin-top: 31px;
        margin-left: 120px;
        margin-bottom: 50px; 
    }
    
    #greetingOutput {
        height: 20px; 
        margin-bottom: 40px;
    }
    
  4. Run the app. Notice the change in spacing.

Windows Store apps support CSS3, so there's a lot you can do to customize your app. (For more info about styling your app, see Quickstart: Styling controls.)

Step 7: Add a Windows Library for JavaScript control

In addition to standard HTML controls, your Windows Store apps using JavaScript can use any of the new controls in the WinJS, such as the WinJS.UI.DatePicker, WinJS.UI.FlipView, WinjS.UI.ListView, and WinJS.UI.Rating controls.

Unlike HTML controls, WinJS controls don't have dedicated markup elements: you can't create a Rating control by adding a <rating /> element, for example. To add a WinJS control, you create a div element and use the data-win-control attribute to specify the type of control you want. To add a Rating control, you set the attribute to "WinJS.UI.Rating".

Let's add a Rating control to our app.

  1. In your default.html file, add a label and a Rating control after the greetingOutputdiv.

    <body>
        <h1 class="headerClass">Hello, world!</h1>
        <div class="mainContent">
            <p>What's your name?</p>
            <input id="nameInput" type="text" />
            <button id="helloButton">Say "Hello"</button>
            <div id="greetingOutput"></div>
            <label for="ratingControlDiv">
                Rate this greeting: 
            </label>
            <div id="ratingControlDiv" data-win-control="WinJS.UI.Rating">
            </div>
        </div>
    </body>
    

    For the Rating to load, your page must call WinJS.UI.processAll. Because our app is using one of the Visual Studio templates, our default.js already includes a call to WinJS.UI.processAll, as described earlier in Step 5, so you don't have to add any code.

  2. Run the app. Notice the new Rating control.

Right now, clicking the Rating control changes the rating, but it doesn't do anything else. Let's use an event handler to do something when the user changes the rating.

Step 8: Register an event handler for a Windows Library for JavaScript control

Registering an event handler for a WinJS control is a little different than registering an event handler for a standard HTML control. Earlier, we mentioned that the onactivated event handler calls WinJS.UI.processAll method to initialize WinJS in your markup. The WinJS.UI.processAll is enclosed in a call to the setPromise method.

            args.setPromise(WinJS.UI.processAll());           

If Rating were a standard HTML control, you could add your event handler after this call to WinJS.UI.processAll. But it's a little more complicated for a WinJS control like our Rating. Because WinJS.UI.processAll creates the Rating control for us, we can't add the event handler to Rating until after WinJS.UI.processAll has finished its processing.

If WinJS.UI.processAll were a typical method, we could register the Rating event handler right after we call it. But the WinJS.UI.processAll method is asynchronous, so any code that follows it might run before WinJS.UI.processAll completes. So, what do we do? We use a Promise object to receive notification when WinJS.UI.processAll completes.

Like all asynchronous WinJS methods, WinJS.UI.processAll returns a Promise object. A Promise is a "promise" that something will happen in the future; when that thing happens, the Promise is said to have completed.

Promise objects have a then method that takes a "completed" function as a parameter. The Promise calls this function when it completes.

By adding your code to a "completed" function and passing it to the Promise object's then method, you can be sure your code executes after WinJS.UI.processAll is complete.

  1. Let's output the rating value when the user selects a rating. In your default.html file, create a div element to display the rating value and give it the id "ratingOutput".

    <body>
        <h1 class="headerClass">Hello, world!</h1>
        <div class="mainContent">
            <p>What's your name?</p>
            <input id="nameInput" type="text" />
            <button id="helloButton">Say "Hello"</button>
            <div id="greetingOutput"></div>
            <label for="ratingControlDiv">
                Rate this greeting: 
            </label>
            <div id="ratingControlDiv" data-win-control="WinJS.UI.Rating">
            </div>     
            <div id="ratingOutput"></div>
        </div>
    </body>
    
  2. In our default.js file, create an event handler for the Rating control's change event named ratingChanged. The eventInfo parameter contains a detail.tentativeRating property that provides the new user rating. Retrieve this value and display it in the output div.

        function ratingChanged(eventInfo) {
    
            var ratingOutput = document.getElementById("ratingOutput");
            ratingOutput.innerText = eventInfo.detail.tentativeRating; 
        }
    
  3. Update the code in our onactivated event handler that calls WinJS.UI.processAll by adding a call to the then method and passing it a completed function. In the completed function, retrieve the ratingControlDiv element that hosts the Rating control. Then use the winControl property to retrieve the actual Rating control. (This example defines the completed function inline.)

                args.setPromise(WinJS.UI.processAll().then(function completed() {
    
                    // Retrieve the div that hosts the Rating control.
                    var ratingControlDiv = document.getElementById("ratingControlDiv");
    
                    // Retrieve the actual Rating control.
                    var ratingControl = ratingControlDiv.winControl;
    
                    // Register the event handler. 
                    ratingControl.addEventListener("change", ratingChanged, false);
    
                }));
    
  4. While it's fine to register event handlers for HTML controls after the call to WinJS.UI.processAll, it's also OK to register them inside your completed function. For simplicity, let's go ahead and move all our event handler registrations inside the then event handler.

    Here's our updated onactivated event handler:

        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
                }
                args.setPromise(WinJS.UI.processAll().then(function completed() {
    
                    // Retrieve the div that hosts the Rating control.
                    var ratingControlDiv = document.getElementById("ratingControlDiv");
    
                    // Retrieve the actual Rating control.
                    var ratingControl = ratingControlDiv.winControl;
    
                    // Register the event handler. 
                    ratingControl.addEventListener("change", ratingChanged, false);
    
                    // Retrieve the button and register our event handler. 
                    var helloButton = document.getElementById("helloButton");
                    helloButton.addEventListener("click", buttonClickHandler, false);
    
                }));
    
            }
        };
    
  5. Run the app. When you select a rating value, it outputs the numeric value below the Rating control.

Note   This section and the last one just touched on what you need to know to start using WinJS controls. To learn more and to see a list of controls, see Quickstart: Adding WinJS controls and styles.

 

Summary

Congratulations, you're done with the tutorial! You learned how to add content to a Windows Store app. You also learned how to add interactivity and how to style the app.

Download the sample

Did you get stuck, or do you want to check your work? If so, download the Getting started with JavaScript sample.

Next steps

In the next part of this tutorial series, you learn more about how the app life cycle works and how to save your app's state. Go to Part 2: Manage app lifecycle and state.

Getting started with JavaScript: Complete code for the tutorial series

Programming Windows 8 Apps with HTML, CSS, and JavaScript (ebook)