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.

Tom
  • 2,604
  • 11
  • 57
  • 96

3 Answers3

2

Try to use the following:

$(document).on("click", ".play", function() {
    // Data
}
Deep Frozen
  • 2,053
  • 2
  • 25
  • 42
  • -1 for binding this to document - that's how .live() has been misused and why .delegate() and .on() functions were created – Zathrus Writer Sep 17 '12 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. – aziz punjani Sep 17 '12 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 Sep 17 '12 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 :) – Zathrus Writer Sep 17 '12 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. – aziz punjani Sep 17 '12 at 15:02
  • @aziz.punjani It's been a year or two since I came to that conclusion, I haven't used it since. I may have just mis-interpreted results at some point. In either case, it isn't documented, so it probably isn't a good idea to use it even if it did work. – Kevin B Sep 17 '12 at 15:06
  • @aziz.punjani It has always worked with the context argument. http://jsfiddle.net/LHxNZ/1/ although I'm not sure what it's doing internally; – Kevin B Sep 17 '12 at 15:08
  • Yes Kevin, i guess that's my point. Even using a context selector it still binds to the document. http://jsfiddle.net/azizpunjani/LHxNZ/3/. Good to get a refresher on this. – aziz punjani Sep 17 '12 at 15:19
  • @aziz.punjani It looks like in jQuery 1.3.2 it did bind to the document regardless of context, but in 1.4.4 it was actually binding the event to the context. – Kevin B Sep 17 '12 at 15:19
  • Oh, how did you come to that conclusion ? The way i test is i try to stop the event propagation to the document from within the click function. If it is successful i know it's not bound to the document because it was able to prevent the propagation. And this excerpt hints at it, `Since all .live() events are attached at the document element, events take the longest and slowest possible path before they are handled.` unless i'm totally off ? – aziz punjani Sep 17 '12 at 15:23
  • No you're right, that's what i observe from the fiddle, i was looking at the core. It still has to propagate to the document. If you bind the events in the opposite order, it always reaches the document before the live event happens until 1.7.2. I just mis-interpreted results. – Kevin B Sep 17 '12 at 15:25
  • Ah ok, always good to go to the source. As of 1.7 `.live` internally calls `.on` so using a context selector for `live` would be the same as using `.on` with a context selector. – aziz punjani Sep 17 '12 at 15:28
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(){....
aziz punjani
  • 25,586
  • 9
  • 47
  • 56
  • I tried to replace my current `.on()` with your suggestion but still the same problem. Any ideas? – Tom Sep 17 '12 at 14:36
  • I wonder if I should be using `on()` in my success function? http://stackoverflow.com/questions/4842119/jquery-binding-click-to-a-link-after-ajax-call – Tom Sep 17 '12 at 14:58
  • What version of jQuery are you using? .on() appeared in 1.7.2 if i'm not mistaken – Mark Pieszak - Trilon.io Sep 17 '12 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)`. – aziz punjani Sep 17 '12 at 16:07
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.

amcdnl
  • 8,470
  • 12
  • 63
  • 99