1

I have a site that plays a stream. I perform an AJAX call to the server once a person presses a button.

<input type="submit" class="play" data-type="<?php echo $result_cameras[$i]["camera_type"]; ?>" data-hash="<?php echo $result_cameras[$i]["camera_hash"]; ?>" value="<?php echo $result_cameras[$i]["camera_name"]; ?>">

This prints out a bunch of buttons that the user can select. This is processed by the following code:

<script>
$(document).ready(function(){

$(".play").on('click', function(){
    var camerahash = $(this).data('hash');
    var cameratype = $(this).data('type');
    function doAjax(){
        $.ajax({
            url: 'index.php?option=streaming&task=playstream&id_hash=<?php echo $id_hash; ?>&camera_hash='+camerahash+'&format=raw',
            success: function(data) {
                if (data == 'Initializing...please wait')
                {
                    $('#quote p').html(data); //shows a message here
                    setTimeout(doAjax, 2000);
                }
                else
                {
                    if (cameratype == "WEBCAM" && data == 'Stream is ready...')
                    {
                        $('#quote p').html(data); //another message here
                        window.location = 'rtsp://<?php echo DEVSTREAMWEB; ?>/<?php echo $session_id;?>/'+camerahash;
                    }
                    else if (cameratype == "AXIS" && data == 'Stream is ready...')
                    {
                        $('#quote p').html(data); //another message here
                        window.location = 'rtsp://<?php echo DEVSTREAMIP; ?>/<?php echo $session_id;?>/'+camerahash;
                    }
                    else
                    {
                        $('#quote p').html(data); //another message here
                    }

                }

            }
        });

    }
    doAjax();
});
});
</script>

Everything works as the user gets messages when they click a button. But clicking another button doesn't show the messages any more. I've used the delegate event (.on) for dynamically loaded buttons (instead of .click()) which I thought would address this but it looks like I just don't get what I need to do.

3
  • You have used on but you haven't delegated the event handler. Bind it to an ancestor element that is in the DOM at the time the code runs, and pass the selector as the 2nd argument. Commented Sep 17, 2012 at 14:15
  • are you sure you understood event delegation using on() correctly? Commented Sep 17, 2012 at 14:15
  • @ZathrusWriter apparently not.
    – Tom
    Commented Sep 17, 2012 at 14:37

3 Answers 3

2

To start off you need to specify a selector within .on. In your case if you don't have a parent/ancestor you can specify document.

 $(document).on('click', '.play', function(){....
4
  • I tried to replace my current .on() with your suggestion but still the same problem. Any ideas?
    – Tom
    Commented Sep 17, 2012 at 14:36
  • I wonder if I should be using on() in my success function? stackoverflow.com/questions/4842119/…
    – Tom
    Commented Sep 17, 2012 at 14:58
  • What version of jQuery are you using? .on() appeared in 1.7.2 if i'm not mistaken Commented Sep 17, 2012 at 15:31
  • Why is function doAjax() in the .on click event handler ? Take it of there and just pass in the variables that function needs via function arguments. doAjax(camerahash). Commented Sep 17, 2012 at 16:07
2

Try to use the following:

$(document).on("click", ".play", function() {
    // Data
}
12
  • -1 for binding this to document - that's how .live() has been misused and why .delegate() and .on() functions were created Commented Sep 17, 2012 at 14:17
  • 3
    That's not wrong per say, it's just inefficient, but as per the code provided it's the best answer. Commented Sep 17, 2012 at 14:19
  • @ZathrusWriter The reason .live was innefficient is that it selected elements and then did nothing with them. With .live() you always had the choice to use it on something other than the document using the context argument.
    – Kevin B
    Commented Sep 17, 2012 at 14:21
  • @aziz.punjani agreed, however it is directly due to that fact that people just omitted the context argument most of the time :) Commented Sep 17, 2012 at 14:24
  • @Kevin B, i think i disagree with part of your statement. I believe all event handlers attached using live are bound at the document level, even specifying a context argument would ultimately bind it to the document. Do your experiments show otherwise ? If this weren't the case then e.stopPropgation() would work on .live events that had a context selector. Commented Sep 17, 2012 at 15:02
2

Bind on the parent element and delegate on the button.

Example, binds on the table and binds to the 'tr' since the TR might not be there when you bind this.

$("#dataTable").on("click", "tr", function(event){ alert($(this).text()); });

You should checkout CanJS ( canjs.us ), they have automatic binders for this type of thing.

Not the answer you're looking for? Browse other questions tagged or ask your own question.