1

My apologies for adding yet another jQuery question but I've been banging my head against this code for far too long. The following code is used on my website: brianjenkins94.tumblr.com in order to fill the #iframe div with the corresponding content loaded via $.get(). The nav works properly (save the obnoxious page jumps occurring from the unconfigured scrollzer & scrolly libraries) but I have yet to be able to figure out how to restore the page content based upon what is provided by the document.location.hash property. If anyone could identify why this code is nonfunctional or perhaps provide some insight as to whether there's a better way of going about doing this, it would be greatly appreciated.

Thanks ahead of time, Brian


$(document).ready(function() {
    console.log("Executing embedded jQuery.")
    if (document.location.hash.length == 0) {
        $("#home")[0].click();
        console.log("Simulating #home link click.");
    } else {
        $(document.location.hash)[0].click();
        console.log("Simulating " + document.location.hash + " link click.");
    }

    $("#header #nav a").click(function() {
        if (!$(this).hasClass("active")) {
            $("#nav a").removeClass("active");
            $(this).addClass("active");

            document.location.hash = $(this).attr('href');

            switch (document.location.hash) {
                case "#home":
                    $.get("{text:DocumentRoot}index.html", function(data) {
                        $("#iframe").html(data);
                        console.log("Loaded index.html");
                    });
                    break;
                case "#showcase":
                    $.get("{text:DocumentRoot}showcase.html", function(data) {
                        $("#iframe").html(data);
                        console.log("Loaded showcase.html");
                    });
                    break;
                case "#about":
                    $.get("{text:DocumentRoot}about.html", function(data) {
                        $("#iframe").html(data);
                        console.log("Loaded about.html");
                    });
                    break;
                case "#github":
                    $.get("{text:DocumentRoot}github.html", function(data) {
                        $("#iframe").html(data);
                        console.log("Loaded github.html");
                    });
                    break;
                default:
                    console.log("No corresponding page.")
                    event.preventDefault();
                    break;
            }
        }
    });
});

Edit: {text:DocumentRoot} is a tumblr placeholder value I set to: https://rawgit.com/brianjenkins94/Sites/master/

bjenks22446
  • 155
  • 7

2 Answers2

2

You are trying to trigger an event prior to actually setting the events. Re-organize your code like so:

$(document).ready(function() {
    console.log("Executing embedded jQuery.");

    $("#header #nav a").click(function() {
        if (!$(this).hasClass("active")) {
            $("#nav a").removeClass("active");
            $(this).addClass("active");

            document.location.hash = $(this).attr('href');

            switch (document.location.hash) {
                case "#home":
                    $.get("{text:DocumentRoot}index.html", function(data) {
                        $("#iframe").html(data);
                    });
                    break;
                case "#showcase":
                    $.get("{text:DocumentRoot}showcase.html", function(data) {
                        $("#iframe").html(data);
                    });
                    break;
                case "#about":
                    $.get("{text:DocumentRoot}about.html", function(data) {
                        $("#iframe").html(data);
                    });
                    break;
                case "#github":
                    $.get("{text:DocumentRoot}github.html", function(data) {
                        $("#iframe").html(data);
                    });
                    break;
                default:
                    event.preventDefault();
                    break;
            }
        }
    });

    if (document.location.hash.length == 0) {
        $("#home").trigger("click");
        console.log("Simulating #home link click.");
    } else {
        $(document.location.hash).trigger("click");
        console.log("Simulating " + document.location.hash + " link click.");
    }    
});
Tristan Lee
  • 1,210
  • 10
  • 17
  • It would only be an infinite loop if he triggered the click yet again inside his handler, which I don't see any place where that is happening. – Tristan Lee Mar 16 '15 at 18:01
  • @brianjenkins94, it's little things like this where a second set of eyes always help. – Tristan Lee Mar 16 '15 at 18:02
  • I mean, when it gets to the `if (document.location.hash.length == 0)` check, either there is no hash, and it triggers a click on the #home link, or there is a hash, and it triggers a click on that hash, which will cause it to come back through the `if (document.location.hash.length == 0)` logic again, and trigger another click on the hash. I can see this behavior if I set up breakpoints, but without the console open, it doesn't appear like it is going into an infinite loop. – Zack Mar 16 '15 at 18:04
  • @Zack that's because the code never executes a page reload. If it did then it would most certainly be an infinite loop. – bjenks22446 Mar 16 '15 at 18:07
1

You can just call .click() directly on your link that was selected with your $("#home") jQuery object selector.

$("#home").click();
Zack
  • 2,789
  • 33
  • 60
  • replacing .trigger("click"); with .click() regrettably does not appear to solve the problem. – bjenks22446 Mar 16 '15 at 16:56
  • So, the click itself is not actually the problem. Are you having difficulty in the switch on the document.location.hash? It is not really clear where exactly you are having your issue, or what that issue actually is. – Zack Mar 16 '15 at 17:13
  • `$("#home").click();` would add a click event handler to the element, not invoke the actual `click` function on the DOM itself. For that you would want: `$("#home")[0].click();` – Tristan Lee Mar 16 '15 at 17:17
  • @TristanLee take a look at the example at the bottom of the page here http://api.jquery.com/click/ You can see that you don't need the brackets on the `.click()` if you want to trigger the click event on all of the selected elements. If you want to only trigger the click event on the first matched element, then you can add the `[0]` like you have. – Zack Mar 16 '15 at 17:21
  • On page load if i pass the URL "brianjenkins94.tumblr.com/#home" I expect the $(document).ready to take the document.location.hash and if it is undeclared to perform the $("home").click() function to get the external html and to place it inside of the #iframe div. If document.location.hash is declared then I expect $(document.location.hash).click() function to get the corresponding page (i.e. #about) and place it inside of the #iframe div. All the navbar links are clickable and functional, but on page load none of my expected alterations are happening to the #iframe div. – bjenks22446 Mar 16 '15 at 17:21
  • @brianjenkins94 I put breakpoints inside your `$("#header #nav a").click(function()...` and it never hit those breakpoints when clicking on the nav links. – Zack Mar 16 '15 at 17:22
  • Your first if-else is causing an infinite loop, because if there is no hash, it simulates the #home click, and so the page loads again and since the hash is now #home, it simulates a click on that link, and loads again, etc, etc... – Zack Mar 16 '15 at 17:26
  • @Zach, you're right about that triggering the events if no argument is passed, but I believe the OP is wanting to simulate a click, not trigger (since I don't see any handlers set on the `click` event of the `#home` element, hence why I suggested calling `click()` directly on the DOM element. – Tristan Lee Mar 16 '15 at 17:31
  • i could understand how my if-else statement was causing an infinite loop but no page-reloading should be occurring, just the appending of the various external html files into the #iframe div. – bjenks22446 Mar 16 '15 at 17:36
  • @TristanLee How did you put @Zach? It's @Zack lol.. but anyway, `.click()` will trigger the *event* of clicking on an element *just like* if the mouse actually clicked on that element, at that point, if there are any handlers that were added with `.click(function()...`, those handlers will run, but you do not have to have handlers assigned to a click *event* for that event to happen. – Zack Mar 16 '15 at 17:36
  • I thought $("#header #nav a").click(function() assigned handlers to each respective link inside of #header #nav. I'll go look up handler assignment. – bjenks22446 Mar 16 '15 at 17:38
  • @brianjenkins94 You are right, if you pass a callback function *inside* the `.click(...)` like you have done, then when elements that match the selector are clicked, that callback function will run, or at least they should. I'm not sure why they are not in your case. – Zack Mar 16 '15 at 17:45
  • 1
    @Zack, here's a fiddle to show you that it will not simulate what you're describing. It only triggers the handlers set for that event. It does not simulate the mouse clicking the link. http://jsfiddle.net/r6648ttj/1/ – Tristan Lee Mar 16 '15 at 17:45
  • @TristanLee You're right. I must be getting confused because I have used something like `document.getElementById('home').click()` before, which works in the updated fiddle here http://jsfiddle.net/r6648ttj/3/ – Zack Mar 16 '15 at 17:51
  • I updated the code block both here and on tumblr to reflect how the code looks now. Although the simple act of loading the page should append the "Hi! I'm index..." post to the top yet it still does not work. – bjenks22446 Mar 16 '15 at 17:53
  • 1
    @Zack, that example is correct. jQuery's `click()` function is not the same as the DOM `click()` function. `document.getElementById('home').click()` is the same as `$("#home")[0].click()` which is why your updated example works. – Tristan Lee Mar 16 '15 at 17:53