By Sergey Laptick

Hints Creation with EnjoyHint

By Sergey Laptick

The aim of this article is to cover the process of creating hints for a website. Firstly, we’ll take a look at how we can create a single hint for a proper website element. Then, we’ll create a sequence of hints to make a guided tour of a website. To create the hints I’ll use EnjoyHint. As an example, I’ve made a simple demo using the Bootstrap framework.

EnjoyHint depends on jQuery and it requires a version of the library greater than or equal to version 1.7. Another dependency is KineticJS v5.1.0 which is already included into EnjoyHint, so there’s nothing to worry about.

If you want to check out the source code of the demo, you can visit this GitHub repository.

Why Use EnjoyHint?

EnjoyHint’s main goal is to give you an opportunity to help a user in finding his way through your web pages features. It can be pretty useful in case of a big web application with tons of elements.


You can highlight a single element and add a description to it, or take a user by the hand to show him all the available features one by one. With this library is also possible to change the shape of the highlighted area or to use your own style for the hint text. Here’s a list of its key features:

  • Free to use
  • Automatic focus and highlighting of the area related to the hint
  • Different shapes of the highlighted area
  • Hint delay property
  • Possibility to resume the interrupted hint sequence
  • Cross-browser support
  • Support for Android, iOS, and Windows touch screens

With this in mind, it’s now time to write some code to see this library in action.

Creating a Hint

I’ve created this tiny model of a search engine as an example:

Turbo Search

It contains the header, the search field, and the Options button which helps to switch between different types of search results. The development of the website is very simple and it’s also outside the scope of this tutorial, so I won’t describe the details. However, you can check the source code if you want.

Once we have a basic web page in place, we can start using EnjoyHint. The first step to perform is to install it by using Bower:

bower install enjoyhint

Alternatively, you can download it from its GitHub repository.

After downloading and extracting the package, you can include it into your HTML file. As we said, this library depends on jQuery, so you have to include the latter before EnjoyHint. If you don’t want to host jQuery locally, you can use the jQuery CDN, as shown below:

<script src=""></script>

<script src="enjoyhint/enjoyhint.min.js"></script>
<link href="enjoyhint/enjoyhint.css" rel="stylesheet"/>

EnjoyHint Initialization

To initialize a new EnjoyHint instance you can write:

var enjoyhint_instance = new EnjoyHint({});

Now you can describe your first hint:

var enjoyhint_script_steps = [{
    /*hint code goes here*/

Or if you want to create a sequence of hints:

var enjoyhint_script_steps = [{
    /*first hint code*/
}, {
    /*second hint code*/

The next step is to set the description of hints as the instance config:


Everything is ready and we can run our script now:;

Hint Definition

As our first example, let’s add a new hint that will describe the Options button purpose:

'click .btn' : 'This button allows you to switch between the search results'

The result is shown below:

First Hint

click is an event that will run the next hint. In our case the event is the click of a button. .btn is the selector of an element we want to highlight (that is the Options button with the class of btn in our example). Then, after the colon, we should define the text of our hint.

Since there’s only one hint in our script, when we click the Options button or the Skip button this hint will disappear. The Skip button appears by default. EnjoyHint allows you to apply your own CSS classes and names for its built-in elements, which can be helpful if you want to describe a single element of your page.

You can change the button’s label with the skipButton property:

'click .btn' : /*hint text*/,
'skipButton' : {className: "mySkip", text: "Got It!"}

This code also adds the mySkip CSS class to it. For example, using this CSS code:

.mySkip {
    color: white;
    border-color: white;

You can get this result:

Got It

You can even remove the Skip button by specifying showSkip: false.

Now that you know how to create a single hint, it’s time to create a couple of them. They will run one after another creating a guide.


Hint Sequence

In order to start creating a sequence of hints, we should rewrite all the code of hint definition from the beginning.

Hint one. The “next” event

The first hint will be specified as follows:

'next .navbar-brand' : /*hint text*/

This time I’ve used the next event and here’s what I’ve got as a result:

Guide Step One

As you can see, our website title is highlighted now. Now, we have two buttons. The Next button will run the next hint and the Skip one will abort the script. You can change the Next button in the same way we did with the Skip button in our previous example:

'nextButton' : {className: "myNext", text: "Sure"},
'skipButton' : {className: "mySkip", text: "Nope!"}

Here’s how these buttons look like now:

Redefined Next Button

Hint two. The “key” event

The next hint will tell a user how to use the search field. We’ll use the key event for this purpose. It will run the next hint after we push a certain key:

'key #mySearch' : /*hint text*/,
'keyCode' : 13

Note that this time we’ve used the ID as a selector. The keyCode property defines the code of a button which triggers the next hint. In this case it’s equal to the Enter button.

Let’s check how it looks like:

Key Property

After the Enter button is clicked, the next hint will be invoked.

Hints Three and Four. Changing the Shape

In this third step we’ll use the previously defined hint for the Option button (see the “Hint Definition” section for details):

'click .btn' : /*hint definition*/

When you click this button, the fourth hint will run. And now we’ll change the default highlight shape, using the shape property for that purpose:

'next .about' : /*hint definition*/,
'shape': 'circle'

This code will highlight the About section as it’s shown below:

Circle Highlight

The Final Step

If the default circle size is not big enough for you, you can change its size using the radius property. We’ll now create the last of our hints using this feature. Since this is the final step of our guide, we don’t need the Skip button anymore and we can disable it using the showSkip property.

So, here’s my code for the final hint:

'next .contact' : 'Your feedback will be appreciated',
'shape': 'circle',
'radius': 70,
'showSkip' : false,
'nextButton' : {className: "myNext", text: "Got it!"}

And the result:

Final hint

As you can see, the radius of the highlighted area is bigger this time.


The last feature I want to discuss is the possibility to execute callback functions. EnjoyHint provides you with the onStart and onEnd properties to run callbacks. The first is executed before the first hint starts and the second is executed after the last one is finished. The following is an example of use:

var enjoyhint_instance = new EnjoyHint({
    onStart: function () {
        // runs before the first hint
    onEnd: function () {
        // runs after the last hint

There is also another property to run a callback called onBeforeStart. This one fires before the certain hint is started:

var enjoyhint_script_steps = [{
    /* hint description */
    onBeforeStart: function () {
        // runs before the hint


EnjoyHint allows you to create step-by-step guides by adding hints to your website step by step. This tool provides you with additional useful features, such as custom event creation. You can use HTML in the hint’s description, which allows you to change its appearance the way you need.

If you want to check out the source code, you can visit this GitHub page. Here’s the demo page.

  • Allow me to show you a excellent ways to earn a lot of extra money by !finishing basic tasks from your house for few short hours a day — See more info by visiting >MY___|DISQUS|___ID|

  • Allow me to show you a real way to earn a lot of extra money by~ finishing basic tasks from your house for few short hours a day — See more info by visiting >MY!___@+__ID|

  • Sergey Laptick

    Here’s an example:

    var myButton = document.getElementById(“buttn12345”);

    var enjoyhint_script_steps = [

    selector: myButton,
    event: ‘click’,
    description: ‘This button gives you superpowers’,


    Is this what you was looking for?

    • Sithu

      yes, thanks this works for me.

      One more question,
      Cant we use other attribute like name as the selector other than Id?

      Thanks for the respond :)

      • Sergey Laptick

        You’re welcome, Sithu (:

        Well, any appropriate selector is fine. I haven’t tested all the possible options to be honest, but you can try this:

        var myButton = document.getElementsByName(“my-button-name”)[0];

        to use the first element with name=”my-button-name”.

        Or even this:

        var myButton = document.getElementsByTagName(“button”)[0];

        to use the first button on your page.

        • Sithu


          Thanks for the reply.
          I have several html pages and if user close the hints in middle , and then at the next page load, hints are shown. how can i identify that user close the hints in middle of the process in-order to stop showing entire hints?

          • Dmitry Dudin

            Hi, Sithu
            For now we don’t have such possibility


          • Sithumail

            Thanks for the reply. I was able to do a workaround on that.

  • how to go to the previous step?

    • Sergey Laptick

      Hi, Alex.
      Unfortunately, this feature is not available.

  • Sergey Laptick

    Hi, Sithu.

    Sorry for the late answer. As it turns out, such use case hasn’t been tested yet, so it seems like there’s nothing you can do about it at the moment. But EnjoyHint is an open-source project, so you’re free to add your pull request.

  • Ganesh Cripz

    will the hint flow works for multiple pages…..?????

    • Sergey Laptick

      Nope. It actually won’t.

  • Selmene Meska

    Will the hint flow works inside an iFrame element ?

  • Selmene Meska

    Here is my code skeleton :

    Some element here ….

    The problem is when i try to get the ID of an element inside the iFrame using this :
    var enjoyhint_script_steps = [{
    selector: $(“#myIframe”).contents().find(“#myElement”),
    event: ‘next’,
    description: ‘Long description here’,

    something went wrong in the hint flow , the selected area is not of the element what i m looking for (myElement in this case).

    • Sergey Laptick

      Yeah. Seems like there’s a problem in this case. Console says: “Cannot read property ‘left’ of undefined”. Guess, EnjoyHint can’t define the offset value for an element within your iFrame. To be honest, I don’t know if there’s a workaround for this issue. But if it’s possible for you, you can define all hints within your “anotherPageHere” and then add it to the page and everything will work just fine.

      • Selmene Meska

        i found a solution which is : i should create an empty div element with the same position,height and width of the iFrame element , in this case the hint flow works !
        another question please :is there double click event ?

        • Sergey Laptick

          Nice. I’ll write it down for future use.

          Do you mean, is there a way to double click on smth to trigger the next hint? Try this:

          selector: myButton,
          event: ‘dblclick’,
          description: ‘Double click me’,


          ‘dblclick .btn’ : ‘Double click me’

          • Selmene Meska

            Yes that’s it ! thank you very much ^^

          • Sergey Laptick

            You’re welcome.

  • Slim Comar

    thanks, very usefull

  • Vineet Kumar

    Is it compatible with AngularJs apps?
    I think it doesn’t work for them.

  • Divya Jeganathan

    can we change the direction of the arrow and hint?

  • Alex Smelovsky

    How can I remember hint status so that I can continue where it left off?

Get the latest in JavaScript, once a week, for free.