Owl
Owl

Reputation: 689

jquery swap dynamic images after document has loaded

I am using this tutorial:

http://www.devinrolsen.com/jquery-image-swapping-with-fade-effect/

But I cannot make it to work. I believe this is some conflict with my other scripts.

I have a catalogue with enters all jquery action in catalogue.php. Then a reader.php which displays either the catalogue or a single page. I have the simpletabs jquery script active.

Now I try to implement the jquery image swapping like in the tutorial above.

But the events for the image clicks are not started at all. I tried all the codes from the tutorial, but it does not work, it just loads the image in the window alone.

So I am trying to debug it, and just to show an alert box:

$("a.img_thumb").on("click", function (e) {
    alert('Works!');
});

But the alert is not triggered. (Although the other javascript is working, tabs, loader etc.)

I tried also:

$(function(){
    $("a.img_thumb").on("click", function (e) {
        alert('Works!');
    });
});

And now I tried this too:

$(document).ready(function() {
    $("a.img_thumb").on("click", function (e) {
        alert('Works!');
    });
});

These are all my jquery in the catalogue.php

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="js/simpletabs_1.3.js"></script>
<script>
    $(document).bind('ajaxStart', function(){
        $('#loading').css("display", "block");
    }).bind('ajaxStop', function(){
        $('#loading').css("display", "none");
    });
    function show_object(itemid,object_type){
        var request = $.ajax({
            url: "reader.php",
            type: "GET",
            data: "id="+ itemid,
            dataType: "html"
        });
        $('table.object_list_' + object_type).hide();
        request.done(function(msg) {       
            $('div.show_object_' + object_type).append(msg);       
        });
        request.fail(function(jqXHR, textStatus) {
            alert( "Request failed: " + textStatus );
        });
    };
    $("a.img_thumb").on("click", function (e) {
        alert('Works!');
    });
</script>

Here is part of the source code, the images are created dynamically from a xml file

    <a href="http://domain.com/itemimages/img50293090.jpg" class="img_thumb">
<img src="http://domain.com/itemimages/img50293090.jpg" alt="pic" class="thumbnail"></a>

Thank you, I have no idea where the error is

Additional info

The two scripts, catalogue.php and reader.php build a catalogue. the names are not good, because the catalogue.php does not anything else than have some css and jquery. This is the whole script of catalogue.php:

<?php
//If needed, paste
header('Content-Type: text/html; charset=utf-8');
?>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script type="text/javascript" src="js/simpletabs_1.3.js"></script>
    <script>
        $(document).bind('ajaxStart', function(){
            $('#loading').css("display", "block");
        }).bind('ajaxStop', function(){
            $('#loading').css("display", "none");
        });
        function show_object(itemid,object_type){
            var request = $.ajax({
                url: "reader.php",
                type: "GET",
                data: "id="+ itemid,
                dataType: "html"
            });
            $('table.object_list_' + object_type).hide();
            request.done(function(msg) {       
                $('div.show_object_' + object_type).append(msg);       
            });
            request.fail(function(jqXHR, textStatus) {
                alert( "Request failed: " + textStatus );
            });
        };
        $(document.body).on("click", "a.img_thumb", function (e) {
            alert('Works!');
        });

    </script>

    <style type="text/css" media="screen">
        @import "css/simpletabs.css";
    </style>
    <style type="text/css">
        #loading {
            display:none;
            position:absolute;   
            left:30px;   
            top:90px;   
            z-index: 1000;          
        }
        img.list_image {
            heigth:90px; 
            width:90px;
        }
        td.list_info {
            width:150px;
        }
        p.tab_header {
            font-weight:bold;
        }
        table.infotable {
            width:800px;
        }
        td.key {
            width:200px;
        }
        td.value {
            width:400px;
        }
        #show_info {
            width:50%;
            float:left;
        }

        #show_pictures {
            width:50%;
            float:right;
        }
        #show_maplinks {
            width:100%;
            clear:all;
        }
        #main_image {
            width:200px;
            margin:3px;
        }
        #thumbs {
            width:200px;
        }
        img.thumbnail {
            max-width:60px;
            max-height:60px;
            margin:3px;
            float:left;
        }
    </style>
</head> 
<body>
    <div id="catalogue" class="simpleTabs">
        <img src="loading.gif" id="loading"/>
<?php
include('reader.php');
?>
    </div>

The reader.php show the list with the items, if $_GET['id'] is not set. If GET is set, then it shows the single item with a lot of data and the images.

The reader.php is almost 1000 lines so I will not post it here.

But, as discussed in the comments. could it be that the problem is somehow, because the images are loaded with ajax when the user clicks on one item at the list? So the images are not present at initial load

Finally I got something working, thanks to you all!

In reader.php where the images are created, I added an onclic-function:

<div id="thumbs">
    <?php foreach ($original_images as $image) { ?>
    <a href="<?php echo $image['url'] ?>" class="img_thumb">
        <img src="<?php echo $image['url'] ?>" alt="kuva" class="thumbnail" onclick="alertme()"/>
    </a>
    <?php } ?>
</div>

And the jquery looks like this:

function alertme() {
    alert('Works!');
};

And this works. How this?

Upvotes: 1

Views: 465

Answers (2)

SpYk3HH
SpYk3HH

Reputation: 22570

If that snippet is from your HEAD, then you're missing your "onload" event. Change your snippet too:

function show_object(itemid,object_type){
    var request = $.ajax({
        url: "reader.php",
        type: "GET",
        data: "id="+ itemid,
        dataType: "html"
    });
    $('table.object_list_' + object_type).hide();
    request.done(function(msg) {       
        $('div.show_object_' + object_type).append(msg);       
    });
    request.fail(function(jqXHR, textStatus) {
        alert( "Request failed: " + textStatus );
    });
};
$(function() {  //  $(document).load(function....
    $(document).bind('ajaxStart', function() {
        $('#loading').css("display", "block");
    })
    .bind('ajaxStop', function(){
        $('#loading').css("display", "none");
    });
    $("a.img_thumb").on("click", function (e) {
        alert('Works!');
    });
})

Also, this could be a "timing" issue. It could be your code is running BEFORE the HTML is "written" to the document body. Too test that, simply wrap your work in a timer and run it. Wait the time, then see if the events fire.

$(function() {
    setTimeout(function() {
        $(document).bind('ajaxStart', function() {
            $('#loading').css("display", "block");
        })
        .bind('ajaxStop', function(){
            $('#loading').css("display", "none");
        });
        $("a.img_thumb").on("click", function (e) {
            alert('Works!');
        });
    }, 3000);   //  3 second timer, this event won't be set till 3 seconds after the page is loaded
})

If this is a timing issue (dynamic data loaded after event listener set) then simply go to where you load the new HTML, and place your event code there. Make sure you place it at the end, after all new HTML is loaded and written.

Another thing you might do, is use the delegate side of .on(). This should add the event click to even dynamic content. This is usually my last resort, as I like control over pinpoint element events, but this is a "clean" way to maintain code in one place.

Using .delegate()

$("body").on("click", "a.img_thumb", function (e) {
    alert('Works!');
});

Upvotes: 1

red-X
red-X

Reputation: 5128

To avoid creating eventlisteners for objects that don't exist yet, you can create the listener on a parent object(body, or a closer object would be even better)

Give this a try:

$(document.body).on("click", "a.img_thumb", function (e) {
    alert('Works!');
});

The listener is added to the body in this case, it's registered for the click event, but only if the click event is on a a.img_thumb within the body. This way the link's don't have to exist yet when you're adding the listener.

Upvotes: 0

Related Questions