0

I'm trying to create my own JS Password Strength Meter.

It was working before but i didn't like how it worked so I tried using

{score +=10;}

Instead of just:

score++

This is my code: http://jsfiddle.net/RSq4L/

Best Regards, Shawn,

Hope someone can help

4

4 回答 4

4

Multiple issues:

  1. Your passwordStrength() function was not defined in the global scope in the jsFiddle so it wasn't getting called. This is probably an artifact of how you set up the jsFiddle, perhaps not an issue in your real code.
  2. The method of getting the appropriate ratingMsg will not work because you don't have array values for every possible score so many scores will generate an "undefined" ratingMsg.
  3. Your CSS classes are also sparse so there are many score values that they will not match for either and no appropriate CSS class/style will be in effect. If you want a specific class for each rating value, then perhaps you should put the classname in the ratings array so it can be fetched from there along with the ratingsMsg.

For the first issue, in your jsFiddle, you also have to make sure the password processing function is defined in the global scope. The way your jsFiddle is set up, it is not (it's in the onload handler). You can fix this in the jsFiddle by just setting the first drop-down in the upper left to "no wrap (head)".

For the second issue, you are using:

ratingMsg[score]

but, your array is a sparse array not guaranteed to have an entry for most possible scores. You simply can't do it that way because many elements you access will have undefined values which won't give you a meaningful message. For example, if score was 15, you would be accessing ratingMsg[15], but there is no value in that space in the array so you won't get a meaningful rating message.

The solution is to find a different way to select the right message. The simplest way would just be an if/else if/else if statement that would check which range the score is in and set the appropriate msg. There are more elegant table driven ways, but all will involve searching through a data structure to find which two values the current score is between and using that msg.

If you look at this jsFiddle http://jsfiddle.net/jfriend00/dA7XC/, you'll see that your code is getting called, but it only hits values in the array sometimes.

And, here's a rewritten algorithm that finds the appropriate msg no matter what the score show in this fiddle: http://jsfiddle.net/jfriend00/jYcBT/.

It uses a data structure like this:

  var ratingMsg = [
      0, "Unclassified",
      10, "Weak",
      20, "Fair",
      50, "Better",
      60, "Medium",
      70, "Good",
      90, "Strong"
  ];

and a for loop like this to get the appropraite ratingMsg:

  for (var i = ratingMsg.length - 2 ; i >= 0; i-=2) {
      if (score >= ratingMsg[i]) {
          msg = ratingMsg[i+1];
          break;
      }
  }
于 2011-08-03T03:33:27.353 回答
2

Here you go: http://jsfiddle.net/RSq4L/11/

The first problem is that in your fiddle you have the onLoad option set, so your passwordStrength function is not actually being declared in the global scope. It is being declared inside of the onLoad block that jsFiddle wraps your code with. This causes the page to error out when the keypress handler tries to invoke the function.

You can fix this problem in several different ways:

  1. By explicitly declaring the function as global as per my example above.
  2. By choosing one of jsFiddle's "no wrap" options instead of onLoad.
  3. By dynamically binding your event-handler instead of setting it through the element's onkeydown attribute in the markup.

The second problem is how you are keying your score messages. You have:

var ratingMsg = new Array(0);

ratingMsg[0] = "Unclassified";
ratingMsg[10] = "Weak";
ratingMsg[30] = "Fair";
ratingMsg[50] = "Better";
ratingMsg[60] = "Medium";
ratingMsg[70] = "Good"; 
ratingMsg[90] = "Strong";

...and you lookup the message by doing ratingMsg[score]. This will only work if the score exactly matches one of your indices. And based upon your math this will not always be the case.

I would suggest doing something like:

ratingMsg = {};

ratingMsg[0] = "Unclassified";
ratingMsg[10] = "Weak";
ratingMsg[30] = "Fair";
ratingMsg[50] = "Better";
ratingMsg[60] = "Medium";
ratingMsg[70] = "Good"; 
ratingMsg[90] = "Strong";

function closestRating(score) {
    var bestKey = 0;
    var bestMatch = 100;
    for (var key in ratingMsg) {
        if (key <= score && score - key < bestMatch) {
            bestMatch = score - key;
            bestKey = key;
        }
    } 
    return ratingMsg[bestKey];
}

On an unrelated note, are you sure you want to be using onkeydown? I think onkeyup would work better.

于 2011-08-03T03:33:17.693 回答
0

Your fiddler script had several errors. Here's the corrected one: new script.

  • You were missing a semicolon here: document.getElementById("passwordDescription").innerHTML = "" + ratingMsg[score] + ""
  • You forgot to escape '^' on your regular expression
于 2011-08-03T03:54:20.553 回答
0

I just wrote this for it: Jquery Plugin for password strength forcing

于 2022-01-26T21:12:22.287 回答