0

Yello. So I've been trying to develop a small web app of sorts and try to learn about the building blocks of front-end development as I went. As I was going along, I got sorta stumped on a problem, which I was able to work around, but I can't figure out why the way I did it isn't working.

Here's the relevant HTML for reference:

<div>
  <div>
    <span>Searching for a specific one?</span>
    <div class="dropdown-btn">
      <span>Pick one!</span>
    </div>
    <div class="dropdown-list">
      <ul>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
      </ul>
    </div>
  </div>
  <div id="results" class="nothing">
    <p>Fanfare</p>
  </div>
</div>

And the relevant Javascript:

var
    ddbtn = $(".dropdown-btn"),
    res = $("#results");

$(document).ready(function () {
    ddbtn.click(function () {
        res.removeClass("nothing");
        res.addClass("lower");
    });
    $(document).click(function() {
        res.removeClass("lower");
    });
});

The idea is to change the attributes of #results when opening and closing .dropdown-list (the script for that is in another file, but it isn't relevant for the issue), by adding and removing classes to #results. But I can't seem to figure out why this doesn't do the job, at least when I tested this on Safari & Chrome. I tried alert() for testing, but it looks like it never fires.

And it's weird because I've tried other ways, and they work perfectly fine. Using no variables and declaring the selectors themselves works:

$(document).ready(function () {
    $(".dropdown-btn").click(function () {
        $("#results").removeClass("nothing");
        $("#results").addClass("lower");
    });
    $(document).click(function() {
        $("#results").removeClass("lower");
    });
});

And even saving the variables as only strings and using them as $(<string>) works:

var
    ddbtn = ".dropdown-btn",
    res = "#results";

$(document).ready(function () {
    $(ddbtn).click(function () {
        $(res).removeClass("nothing");
        $(res).addClass("lower");
    });
    $(document).click(function() {
        $(res).removeClass("lower");
    });
});

Heck, I even have the same line of var ddbtn = $(".dropdown-btn") on the other .js file, and that seems to be working just fine. I just really want to know why the first approach doesn't work as expected; not sure if there's something fundamental I'm missing here, so thanks in advance!

  • Are the elements available in the DOM when `var ddbtn = $(".dropdown-btn"), res = $("#results");` is executed? Define the variables outside of `$(document).ready(function () { ... })` but fill them only in the handler. – Andreas Jun 29 '17 at 06:36
  • It does not "store the selector." It runs the selector you give against the current elements in the DOM, creates a jQuery object, puts the matching elements in the jQuery object, and gives you a reference to that jQuery object. The selector is not stored (modulo jQuery internals). – Vigneshwaran Markandan Jun 29 '17 at 06:39
  • Its weird in my case it works fine I have tested this code, I think you have something other issue even you can test this same code on demo file ... then you it works fine :) – Abhijeet Jun 29 '17 at 06:39
  • @Andreas I assumed so, but after seeing the question that was linked by Phil, I think it really wasn't. I moved the `script` tags from the head to just below the body, and now it seems to be working fine. I assumed that placing my code within `$(document).ready()` would do it, so I wonder why it didn't if it's only supposed to fire after everything was loaded/ready – Danny Hernandez Jun 29 '17 at 06:57
  • The line `var ddbtn = $(".dropdown-btn"), res = $("#results");` fetches the elements and is executed **before** the DOM is ready (because it is not inside the ready handler) – Andreas Jun 29 '17 at 07:15
  • @Andreas Oh shoot, well now I feel a bit dumb, but that definitely explains it, so I should probably move it inside the `document.ready()` handler. As you can see, I'm still getting used to the language and the fundamentals, but hey, baby steps. Thank you! – Danny Hernandez Jun 29 '17 at 08:21

0 Answers0