0

First off, thanks to this community. I'm slowly starting to understand this stuff and I appreciate all the feedback. That said, I come with another question.

THE SITUATION: I'm trying to build a new site and I'm trying to use it as a learning experience to use some php and teach myself javascript (note, I'm wanting to stick with js right now and not jump to jquery until I get a better handle on js). I've created a gallery that will have a series of thumbnails at the top that when clicked will populate a div below with artwork, its title and a description.

THE SETUP: Because I want to have these called by names and not numbers (such as an array) so they can be interchangeable, I built each as an id's div containing all the components and then I'm calling it to the target location via the script:

function changeDiv(id) {
var target = document.getElementById('generic');
var id = document.getElementById(id);
target.innerHTML = id.innerHTML; 
}

In the body it looks like:

<img src="images/thumbs/digital-art/thumb-space-oddity.jpg" id="thumb-space-odity" onclick="callDiv('space-oddity')"/>
...
<div class="gallery-frame" id="generic"></div>

Currently this works but since I have to have a place for all of the divs to be called from I've added a php include in the footer so it loads last but contains all of the images I could possibly need:

<div style="display:none;">
<?php include("gallery.php"); ?>
</div>

... but from what I understand since this will still mean the page will load all the content that will really slow down the page. So I need a new solution.

MY CHALLENGE: First off, is there a way to do this exclusively in javascript? If so I'd gladly do that!

Assuming I cannot, I have started looking into AJAX to see how it works and while it's starting to make nominal sense (still new to javascript so I only get half of it) and between w3schools.com and the stackoverflow topic I think i have a general idea of what I need to do but it's still not working.

THE PROBLEM: Based on the above stackoverflow comment I attempted to recreate the example function in my own instance and I have set it up as the following:

<script type="text/javascript">
function createXMLHttpRequest() {
    try {
        return new XMLHttpRequest();
    }
    catch (e)
    { alert('XMLHttpRequest not working'); }
    try {
        return new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (e)
    { alert('Msxml2.XMLHTT not working'); }
    try {
        return new ActiveXObject("Microsoft.XMLHTTP");
    }
    catch (e)
    { alert('Microsoft.XMLHTTP not working'); }
    alert("XMLHttpRequest not supported");
    return null;
}
function callDiv(id) {
    var xmlHttpReq = createXMLHttpRequest();
    var url = "gallery.asp?ID=" + id;
    xmlHttpReq.open("GET", url, true);
    xmlHttpReq.send();
}
</script>

From what I've read I left the first section alone as that sets up the function (removing the null and prompts as I don't need them) and trying to have the callDiv function run the same as the previous script I was using. I have also saved out the gallery.php page as an .asp page but should I have left it as php?

Did it have to be .ashx?

And since I don't know the file it was being called from I don't know what the '?REASON' that was used in the original example meant. I tried ?ID thinking I was telling it to look for an id. Is that wrong, or unnecessary?

Thanks!

-Chris

Community
  • 1
  • 1
user1311848
  • 55
  • 2
  • 11
  • Try to format your code, and explain briefly, but with most importants details. – Gabriel Santos Jul 16 '12 at 01:56
  • 1
    Once I reviewed it I saw it didn't save. Just finished editing it – user1311848 Jul 16 '12 at 01:58
  • You are correct about using ajax, but, when you insert the result of ajax on your page? – Gabriel Santos Jul 16 '12 at 02:00
  • It's not finished yet, but here is the current page as it is supposed to work using the included php for all but the first thumbnail - the thumbnail NOT working is the one I'm experimenting with the ajax on. But to answer your question, the ajax is supposed to make the first thumbnail act like the other 4: http://www.chrisjohndesigns.com/artwork-awa.php Again, not finished so pardon the mess... – user1311848 Jul 16 '12 at 02:03
  • I think I don't understand at all your question. If you can explain briefly, with only importants things, I will thank you. – Gabriel Santos Jul 16 '12 at 02:05
  • Sorry, rather than loading new pages I am calling the content I want to the target field using javascript and its working but to do this I'm including the source of the content as an included php instance. I am trying to understand and use ajax to call that same content to the same target field on the current page WITHOUT having to preload or include all of the content of the php include – user1311848 Jul 16 '12 at 02:08
  • Ok, and, `gallery.php` will be the file with what you need? – Gabriel Santos Jul 16 '12 at 02:09
  • Ow, and gallery.php, you said you changed it to asp... I hope you changed more than just the extention. If not: that won't work, asp != php, not even close – Elias Van Ootegem Jul 16 '12 at 02:20
  • I'm using Dreamweaver and set up an asp page from the templates and added my content from the php page to the body of the asp page. But beyond that I did not change any of the content. – user1311848 Jul 16 '12 at 02:50
  • switch the extention back to php. asp requires different code, and if you don't have your php extention right, your code won't be treated as a php script, and therefore will not be executed. – Elias Van Ootegem Jul 16 '12 at 02:56

2 Answers2

0

Ok, good (and indeed brave) to want do do this in pure JS. It's a quirky, but fun language, honestly. The easiest way to achieve your goals will be using ajax calls, though it isn't a necessity.
Looking at your code, your calls will probably work just fine but you've left out the most important part of it all: a callback for the onreadystatechange event

As your script sends a request to the server, the state of that request is checked. Once the server has finished processing the sent request and the has finished responding the readyState should be 4. (more info can be found here).
Basically, try adding this to your ajax object:

function callDiv(id)
{
    var xmlHttpReq = createXMLHttpRequest();
    xmlHttpReq.onreadystatechange = function()
    {
        if (this.readyState === 4 && this.status === 200)
        {
            //this === xmlHttpReq, "this" can be tricky, it refers to the calling obj.
            console.log(this.responseText);//check your console, see what that tells you
        }
    };
    var url = "gallery.asp?ID=" + id;
    xmlHttpReq.open("GET", url, true);
    xmlHttpReq.send();
}

Personally, seeing as you're new to JS, I'd also suggest just preloading your images in a regular way:

var nextImg = document.createElement('img');
nextImg.src = 'images/nextImage.jpg';
nextImg.onload = function()
{
    //targetId
    document.getElementById('wherever').appendChild(this);//this === nextImg
};

The last scenario creates a new DOM element, img, the source is set, so that the image is being loaded, when the loading has completed, there's an event handler that appends the new image to whatever container element (might as well be the document.body element) of your choice.
the advantage here is that you don't have to wrestle with AJAX. It's asynchronous nature can be tricky. On a smal scale, this is also easily implemented and easy to debug. The downside: it's a nightmare to maintain, and shifts all functionality to the client side. There's also a couple of more issues, but I'm a bit pissed and tired. read more here. If needs must, I'll have another look at this tomorrow.

Oh, yes: welcome to SO BTW.

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • Thanks - I'm learning a lot here. I've added the code you provided but still nothing. I've relinked to my php page vs the asp but do I have to format it a certain way? currently my php page 9previously the include) is just a series of div items. – user1311848 Jul 16 '12 at 23:45
  • Still isn't working but I'm viewing the console in Chrome and the message I'm getting on line 162 (the image with the onclick) is: Uncaught ReferenceError: callDiv is not defined (repeated 2 times) – user1311848 Jul 17 '12 at 05:17
  • @user1311848: on your first comment: yes, you have to format your page in a certain way to get the most out of ajax calls. As you're passing some id value to the page, why not use a `switch ($_GET['id'])`? – Elias Van Ootegem Jul 17 '12 at 05:46
  • On the second question: it's hard to debug your code if I can't see it... why not set up a fiddle || use pastebin – Elias Van Ootegem Jul 17 '12 at 05:47
  • looked at your page: you have no closing `}` for the `callDiv` function – Elias Van Ootegem Jul 17 '12 at 05:50
0

Ok, see the follow code, you execute the request inside callDiv, and the result go inside .foo element:

function callDiv(id) {
    var request;  // Store AJAX request

    // Here you verify browsers support, to create new Ajax request
    try { // Opera, Firefox and Safari support
        request = new XMLHttpRequest();
    } catch (e) { // IE support
        try {
            request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try{
                request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
                // Hide error, something goes wrong
            }
        }
    }

    // Show result inside .foo div
    request.onreadystatechange = function() {
        if(request.readyState == 4) { // Success
            var element = document.getElementByClass('foo');
            element.innerHTML = request.responseText;
        }
    }

    // Here you send the request
    request.open("GET", "gallery.php?id=" + id, true);
    request.send(null); 
}

<div class='foo'><!-- HERE WILL SHOW THE AJAX RESULT --></div>
Gabriel Santos
  • 4,934
  • 2
  • 43
  • 74
  • This won't preload the images themselves, the `gallery` script is just returning an html script, the images still need to be loaded after that. For that matter, you might just use a `setTimeout` function and append the html strings using just pure JS: no ajax calls, na async stuff and no extra load on your server by performing unneeded requests – Elias Van Ootegem Jul 16 '12 at 02:24
  • What I understand is he whant to load the PHP file with ajax, as he explained in comments.. – Gabriel Santos Jul 16 '12 at 02:25
  • Fair enough, but the OP is worried about this slowing down his page, bc all of his images are in the footer. The quickest way to present content to the users (IMO) would therefore be: return a html page and load the images one by one using JS (since images are probably the things that have the greatest impact on the download time for his page). That's what I'd focus on. Your approach will do that, too, but (not to be blunt) will still dump all imgs in one lump, bogging down the page one way or the other – Elias Van Ootegem Jul 16 '12 at 02:31
  • With my approach, I can put javascripts at the end of script, and with a asynchronous way, load image per image, only need some adjustments. – Gabriel Santos Jul 16 '12 at 02:40
  • And thus gaining _what_ advantage over just creating a new `img` element? – Elias Van Ootegem Jul 16 '12 at 03:00
  • Dinamic versus static image names, perharps. This is one way, you can do the same in "n" ways. – Gabriel Santos Jul 16 '12 at 03:28
  • Thank you both for the help and while I'm not too sure the preloading you're referring to in the discussion it does give me some additional ideas of what I'll likely have to address – user1311848 Jul 16 '12 at 23:47
  • @GabrielSantos first of all, getElementByClass is not valid javascript method. you should use : document.getElementsByClassName("foo")[0] instead. – John Jul 22 '12 at 16:55