Working with flags: How to protect your data

- select the contributor at the end of the page -

Developers can use flags for many different things, but today the use-case we're going to discuss is all about protecting your data. Imagine a very real scenario in which you want to be able to protect a variable in certain situations. In this quick tutorial, we'll talk about a use-case in JavaScript where we want to retain the data inside a div that we replaced. Let's take a look.

The problem

Grey Elerson is working on a pretty cool project. I realize this isn't much to run on, but I don't want to give away too much more information than that. Within this project, he has attached comments to an object and wanted to have a hover effect on each comment. But a problem came with the hover command in jQuery; the mouseenter event would fire twice before firing the exit event.

His original code looked like this:

    function() { 
        var high = $(this).height();
        var wide = $(this).width();
        comment_html = $(this).html();


var hoverstring = "<div style='height: "+high+"px ; width: "+wide+"px ;'><p style='font-size: 30px; color: #efefef; text-align: center;position: relative; top: 50%;transform: translateY(-50%); opacity: 0.5;'>Reply</p></div>";

$(this).html(hoverstring).css("background", "#444"); console.log("mouse in"); },

function(){ $(this).css("background", "#efefef").html(comment_html); console.log("mouse out"); } );

As you can see, Grey was calling an event on hover to replace the div's contents with a "reply to this comment" message. A very simple idea, but one that was breaking. When he hovered on the item it sometimes fired the hover event twice right in a row. Since his original comment HTML was not protected, he just overwrote it with the new HTML. This meant that when he stopped hovering on the comment, the reply message still showed.

In order to fix this we need to protect the original comment.

The solution

You can go over several solutions to this problem, but you'll quickly find that many are just complex and bloated. These might include a JSON array with the original comment HTML stored, but this involves loops and lots of data being generated. In a situation like this, you also need to decide if the solution needs to be on the server side or the client side.

Thankfully, the solution we decided on addressed the initial problem (of the double-firing of the mouseenter event and no protection).

Here's the solution broken down.

  var comment_html;
var commentflag = false;
var comment_id;

Take a close look, because what's happening in these three lines is very important:

  1. We create a comment_html variable to hold the original div contents.

  2. We create a flag called commentflag. This is just a boolean variable that will tell us if we have a comment stored (true) or not (false). We start off with a value of false because we don't have a comment stored when we start the page.

  3. We create a comment id variable. This will hold the name of the comment we're protecting. We want to store the id of the comment before we set the commentflag to true.

Next I changed up the jQuery even to an on event. This is a personal style preference and I believe it creates better code readability.

  $('div.comment').on("mouseenter", function(){
        comment_html = $(this).html();
        var hoverstring = "<div style='height: 100%; width: 100%;'><p style='font-size: 30px; color: #efefef; text-align: center;position: relative; top: 50%;transform: translateY(-50%); opacity: 0.5;'>Reply</p></div>";
        $(this).html(hoverstring).css("background", "#444");
        console.log("mouse in");
        comment_id = $(this).attr('id');
        commentflag = true;
      } else {
        // Do nothing because we have a comment saved...

Let's break down this code block too:

  1. We use an if statement to check if we have a comment that is protected. When the if statement evaluates to true (AKA commentflag == false), then we do not have a comment stored.

  2. Once we are inside the if statement we can go ahead and store this comment.

  3. Logout this for debug purposes.

  4. Save the hoverstring (the contents to override this div's html).

  5. Replace the html in this div.

  6. Set comment_id equal to this div's id attribute. This helps us remember what comment is stored.

  7. Finally, protect this comment with a commentflag = true.

To sum it up, this code will follow the logic of: Do I have a comment protected? If yes, do nothing because you don't want to hurt the protected comment. If no, go ahead and start the process for showing the "reply to comment" message and save the current contents to protect them.

If a mouseenter event is fired twice the first time, it will store the comment, and the second time it will do nothing. It can fire that mouseevent as much as it wants, and it will never hurt the protected comment.

OK, so now how do we handle the mouse out event? Easy, like this:

$('div.comment').on("mouseleave", function(){
    if($(this).attr('id') === comment_id) 
      $(this).html(comment_html).css("background", "#efefef");
      console.log("mouse out");
      commentflag = false;
    } else {
      // do nothing because we don't like you...

As usual, let's break it down:

  1. On the mouseleave event we want to start off with an if statement.

  2. The if statement evaluates to true if the id of the div firing the mouseleave event is the same div that protected itself.

  3. If it evaluates as true, we want to go ahead and restore the old HTML data, and set the commentflag back to false.

This logic ensures that if we're firing a mouseleave event from another div (than what the mouseenter event was called), then we don't accidentally overwrite the wrong div with the original content. This also sets the commentflag back to false allowing a new div to be hovered on.

If you're thinking that this is a simple fix, you're absolutely right. But don't brush it off for its ease, as sometimes the smartest solutions are those that we overlook. In my experience, this quick-fix has served me well, and I hope it does the same for you.

Get our content first. In your inbox.

Loading form...

If this message remains, it may be due to cookies being disabled or to an ad blocker.