1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

execute code on real time

Discussion in 'jQuery' started by supercain, Oct 17, 2013.

  1. #1
    Hi,

    im making some sort of image gallery which displays only the image marked with an ID contained in a text file. I need that as soon as i update that text file with another ID, the image changes in real time to the new one. This is my code:


    1. <script type='text/javascript'>
            var primimg;
            function firstimage() {
              var xmlhttp;
              if (window.XMLHttpRequest)
              {
                xmlhttp=new XMLHttpRequest();
              }
              xmlhttp.onreadystatechange=function()
              {
                if (xmlhttp.readyState==4 && xmlhttp.status==200)
                {
                  primimg=xmlhttp.responseText;
                }
              }
              xmlhttp.open("GET","image.txt",true);
              xmlhttp.send();
            }
            setInterval("firstimage()", 500); 
            $(window).load(function(){
              $(function() {
              $('#fader *').not(primimg).hide();
              $('#fader *').each(function() {
                var img = $(this);
                $('<img>').attr('src', $(this).attr('src')).load(function() {});
              });
              });
            });
            </script>
      Code (markup):
    The image displays but not on real time but onl after refreshing the page. Could you please give me a hand?

    Thank you.
     
    supercain, Oct 17, 2013 IP
  2. PoPSiCLe

    PoPSiCLe Illustrious Member

    Messages:
    4,623
    Likes Received:
    725
    Best Answers:
    152
    Trophy Points:
    470
    #2
    You should first of all remove the window . load function, since that's what's causing the image to only be refreshed on page load...
     
    PoPSiCLe, Oct 17, 2013 IP
  3. supercain

    supercain Greenhorn

    Messages:
    29
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #3
    I tried that one already but then it wont work. I changed my code like this:

    setInterval(function(){
    $(function() {
    $('#fader *').not(primimg).hide();
    $('#fader *').each(function() {
    var img = $(this);
    $('<img>').attr('src', $(this).attr('src')).load(function() {});
    });
    });
    }, 500);

    but it still wont get the value on real time (as i reupload the text file to the server).
     
    Last edited: Oct 17, 2013
    supercain, Oct 17, 2013 IP
  4. supercain

    supercain Greenhorn

    Messages:
    29
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #4
    Hello? Any help please?
     
    supercain, Oct 22, 2013 IP
  5. ThePHPMaster

    ThePHPMaster Well-Known Member

    Messages:
    737
    Likes Received:
    52
    Best Answers:
    33
    Trophy Points:
    150
    #5
    1) Extract your window.load method into a different function (ex: loadImages()).
    2) Replace the onload with that function: $(window).load(function(){ loadImages();{);
    3) Attach an onload event of that new function to the ajax request: xmlhttp.onload = loadImages; xmlhttp.open("GET","image.txt",true);

    Your issue is that whenever the ajax happens, you don't reload the images.
     
    ThePHPMaster, Oct 22, 2013 IP
  6. supercain

    supercain Greenhorn

    Messages:
    29
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #6
    Like this?

    
    <script type='text/javascript'>
          var primimg;
          function firstimage() {
            var xmlhttp;
            if (window.XMLHttpRequest)
            {
              xmlhttp=new XMLHttpRequest();
            }
            xmlhttp.onreadystatechange=function()
            {
              if (xmlhttp.readyState==4 && xmlhttp.status==200)
              {
                primimg=xmlhttp.responseText;
              }
            }
            xmlhttp.open("GET","image.txt",true);
            xmlhttp.send();
          }
          setInterval("firstimage()", 500);
          $(window).load(loadimages(){
            $(loadimages() {
            $('#fader *').not(primimg).hide();
            $('#fader *').each(function() {
              var img = $(this);
              $('<img>').attr('src', $(this).attr('src')).load(function() {});
            });
            });
          });
          </script>
    
    Code (markup):
    I didnt quite get the 3rd point though. Where should i put that? At the very end or before declaring loadimages()?

    Thank you.
     
    supercain, Oct 23, 2013 IP
  7. ThePHPMaster

    ThePHPMaster Well-Known Member

    Messages:
    737
    Likes Received:
    52
    Best Answers:
    33
    Trophy Points:
    150
    #7
    More like this:

    
    <script type='text/javascript'>
          var primimg;
          function firstimage() {
            var xmlhttp;
            if (window.XMLHttpRequest)
            {
              xmlhttp=new XMLHttpRequest();
            }
            xmlhttp.onreadystatechange=function()
            {
              if (xmlhttp.readyState==4 && xmlhttp.status==200)
              {
                primimg=xmlhttp.responseText;
              }
            }
            xmlhttp.onload = loadImages;
            xmlhttp.open("GET","image.txt",true);
            xmlhttp.send();
          }
          setInterval("firstimage()", 500);
          function loadimages(){
            $('#fader *').not(primimg).hide();
            $('#fader *').each(function() {
              var img = $(this);
              $('<img>').attr('src', $(this).attr('src')).load(function() {});
          });
          $(window).load(function (){loadImages();});
    </script>
    
    Code (markup):
    Not test, but you get the idea.
     
    ThePHPMaster, Oct 23, 2013 IP
  8. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #8
    This reeks of the typical jquery for NOTHING BS, making something simple far, FAR more complex AND cryptic than need be -- though I'd have difficulty saying what the correct code would be without seeing a sample of the text file you are operating upon and the markup this code is attempting to modify.
     
    deathshadow, Oct 24, 2013 IP
  9. supercain

    supercain Greenhorn

    Messages:
    29
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #9
    it didnt work. Seems like i cant change the $(function() to something else, in this case to loadimages(). Any idea why?

    The text file is nothing but something like this: #img02

    The html is something like this:

    <div id="fader">
    <img id="img01" alt="" src="imagenes/01.jpg">
    <img id="img02" alt="" src="imagenes/02.jpg">
    <img id="img04" alt="" src="imagenes/03.jpg">
    
    </div>
    HTML:
    Very straightforward as you may see.
     
    supercain, Oct 24, 2013 IP
  10. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #10
    The image hide/changes need to go inside your response handler. 'primer' won't exist until that has run and returned state 4 / 200.

    I would further suggest axing the jquery, and using class swaps instead of the hide() method -- make the default state of #fader img be display:none, then add a class to show the current one.

    (function() {
    	
    	function ajaxNew() {
    		if (window.XMLHttpRequest) return new XMLHttpRequest();
    		try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
    		catch (e) {}
    		try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
    		catch (e) {}
    		try { return new ActiveXObject("Microsoft.XMLHTTP"); }
    		catch (e) {}
    		return false;
    	}
    	
    	function classExists(e, n) {
    		return new RegExp('(\\s|^)' + n + '(\\s|$)').test(e.className);
    	}
    	
    	function classAdd(e, n) {
    		if (!classExists(e, n)) { 
    			e.className += (e.className ? ' ' : '' ) + n;
    		}
    	}
    	
    	function classRemove(e, n) {
    		e.className = e.className.replace(
    			new RegExp('(\\s|^)' + n + '(\\s|$)'),' '
    		) . replace(/^\s+|\s+$/g,'');
    	}
    	
    	var ajax = ajaxNew(),
    		
    	if (ajax !== false) {
    	
    		var current = false;
    		
    		function request() {
    			ajax.open('GET','image.txt', true);
    			ajax.send();
    		}
    		
    		ajax.onreadystatechange = function() {
    			if (this.readyState == 4) {
    				if (this.status == 200) {
    					if (current) classRemove(current,'show');
    					current = document.getElementById('ajax.responseText');
    					classAdd(current,'show');
    				}
    				setTimeout(request, 500);
    			}
    		}
    		
    		request();
    	
    	} // might want to add an else handler for no AJAX here
    	
    })();
    Code (markup):
    with CSS thus:
    #fader img { display:none; }
    #fader img.show { display:block; }
    Code (markup):
    If you want fade-in and fade-out effects, simply apo all the images, set z-index to 0, and add another tracker to track the previous image. You can then use opacity and transition without any changes to that script.

    I'd even consider adding a class to #fader in the scripting and using that to hide the images instead of targeting #fader -- that way scripting off all the images show all the time.

    ... THOUGH, loading images and hiding them this way is grossly inefficient and not really something that has any business being done client side in real time, much less via bandwidth hogging polling... assuming this is for a website and not some crapplet, it's a poster child of 'gee ain't it neat' scripting for nothing.
     
    deathshadow, Oct 24, 2013 IP
  11. supercain

    supercain Greenhorn

    Messages:
    29
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #11
    Hi,

    i tried the code but it didnt work. I think i messed up. I put it inside head just like this:

      <script type='text/javascript'>
    (function() {
     
        function ajaxNew() {
            if (window.XMLHttpRequest) return new XMLHttpRequest();
            try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
            catch (e) {}
            try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
            catch (e) {}
            try { return new ActiveXObject("Microsoft.XMLHTTP"); }
            catch (e) {}
            return false;
        }
     
        function classExists(e, n) {
            return new RegExp('(\\s|^)' + n + '(\\s|$)').test(e.className);
        }
     
        function classAdd(e, n) {
            if (!classExists(e, n)) {
                e.className += (e.className ? ' ' : '' ) + n;
            }
        }
     
        function classRemove(e, n) {
            e.className = e.className.replace(
                new RegExp('(\\s|^)' + n + '(\\s|$)'),' '
            ) . replace(/^\s+|\s+$/g,'');
        }
     
        var ajax = ajaxNew(),
         
        if (ajax !== false) {
     
            var current = false;
         
            function request() {
                ajax.open('GET','image.txt', true);
                ajax.send();
            }
         
            ajax.onreadystatechange = function() {
                if (this.readyState == 4) {
                    if (this.status == 200) {
                        if (current) classRemove(current,'show');
                        current = document.getElementById('ajax.responseText');
                        classAdd(current,'show');
                    }
                    setTimeout(request, 500);
                }
            }
         
            request();
     
        } // might want to add an else handler for no AJAX here
     
    })();
    
      </script>
    Code (markup):
    but no image shows now. I dont mean this for a website. Its just a tool to show images to a colleague in real time because this way it would be faster and much better quality than streaming them.
     
    supercain, Oct 24, 2013 IP
  12. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #12
    oops, doh. My bad, typo.

    current = document.getElementById('ajax.responseText');

    do we see a problem here?

    change to :
    current = document.getElementById(ajax.responseText);

    no quotes.

    Also, I suggest placing this script right before </body> instead of inside <head>. It's better to run scripting like this AFTER any DOM elements being targeted is built.

    I didn't test the above, but if I have time later I'll make a working demo just to be sure of it.
     
    deathshadow, Oct 24, 2013 IP
  13. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #13
    Put together a working demo, with a few extra 'gems'.

    http://www.cutcodedown.com/for_others/supercain/images.html

    as with all my examples the directory:
    http://www.cutcodedown.com/for_others/supercain/

    Is open for easy access to the bits and pieces.

    I made it call a simple images.php to replicate the txt file you'd be manually editing:
    <?php echo 'gallery', floor((time() % 15) / 5); ?>
    Code (markup):
    Changes the value based on the time. I also upped the polling period to a second. There were a couple other 'bugs' I squashed in the above 'quicky' code. I added tracking of the 'previously shown' item, so the two target classes are 'current' and 'previous'. By absolute positioning the images inside their container, setting them all the same size, and then using z-index with opacity and transitions, I'm able to easily add a fade in of the newly selected image over the old one.

    #fader,
    #fader img {
    	width:480px;
    	height:360px;
    }
    
    #fader {
    	position:relative;
    	margin:1em auto;
    }
    
    .scriptedFader img {
    	position:absolute;
    	top:0;
    	left:0;
    	z-index:1;
    	opacity:0;
    }
    
    .scriptedFader img.current {
    	z-index:30;
    	opacity:1;
    	transition:opacity 1s;
    }
    
    .scriptedFader img.previous {
    	z-index:20;
    	opacity:1;
    }
    Code (markup):
    Because the animation effect is moved into the CSS and the use of the extra classes, you could quite easily change it to a slide-in effect thus:

    .scriptedFader img {
    	position:absolute;
    	top:0;
    	left:100%;
    }
    
    .scriptedFader img.current {
    	z-index:30;
    	left:0;
    	transition:left 1s;
    }
    
    .scriptedFader img.previous {
    	z-index:20;
    	left:0;
    }
    Code (markup):
    or a slide across effect:

    .scriptedFader img {
    	position:absolute;
    	top:0;
    	left:100%;
    }
    
    .scriptedFader img.current {
    	left:0;
    	transition:left 1s;
    }
    
    .scriptedFader img.previous {
    	left:-100%;
    	transition:left 1s;
    }
    Code (markup):
    Or slide from the right, top, or bottom by simply swapping out all the 'left' as desired... and this is why I think 2/3rds of Jquery's codebase belongs on the cutting room floor :D
     
    deathshadow, Oct 24, 2013 IP
    ryan_uk and malky66 like this.
  14. supercain

    supercain Greenhorn

    Messages:
    29
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #14
    But doing it like this implies that the images will slide automatically? Because i didnt mean that. I need to be able to change the picture manually and that the other user sees that on his own end. Clicking a button would automatically update the value on the txt file, and since the gallery shows the image with that id in real time, it ill slide to that picture on every computer you see it simultaneously.
     
    supercain, Oct 24, 2013 IP
  15. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #15
    My PHP file is updating them automatically, you can make it call whatever you want to set it. Just change the images.php I'm calling to your TXT file (omit the #) and away you go.

    I only set up the automatic responder to demonstrate that the AJAX and swapping code work.
     
    deathshadow, Oct 24, 2013 IP
  16. supercain

    supercain Greenhorn

    Messages:
    29
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #16
    It works very nice. Thank you. Now i need to take care of the buttons to have the text file updated with the ID of the image to show. I have this code but seems to be in clonflict with yours.


     $( document ).ready(function() {
          var last_img_value= 6; // Meaning 5.jpg
          var first_img_value= 1; // Meaning 1.jpg
          var curr_img_ptr = 0;
         
          $( "#next" ).click(function() {
                var curr_img = $('#img_goes_here img').attr('src');
                var mySplit = curr_img.split("/");
                var just_number = mySplit[1].split(".");
                var new_img_num = parseFloat(just_number[0]);  // whatever the current img # is ie 5.jpg means 5
                curr_img_ptr = new_img_num;  // store current image number
                new_img_num = 'img' + new_img_num; // inc new_img_number
                var new_img_test = new_img_num;  // set test condition
                new_img_num = new_img_num; // Create a string in case it is good
                console.log('trying ' ,    new_img_num);
               
                if (new_img_test > last_img_value){
                    console.log('cant advance forward');
                    return false;
                }
           
              $.post( "imagen.txt", { imgs: new_img_num })
              .done(function( data ) {
              console.log( "Data Loaded: " + data );
              });
     
          });
         
          $( "#prev" ).click(function() {
                var curr_img = $('#img_goes_here img').attr('src');
                var mySplit = curr_img.split("/");
                var just_number = mySplit[1].split(".");
                var new_img_num = parseFloat(just_number[0]);  // whatever the current img # is ie 5.jpg means 5
                curr_img_ptr = new_img_num;  // store current image number
                new_img_num = new_img_num - 1; // dec new_img_number
                var new_img_test = new_img_num;  // set test condition
                new_img_num = 'img' + new_img_num; // Create a string in case it is good
                console.log('trying' , new_img_num);
               
                if ( new_img_test < first_img_value  ){
                    console.log('cant dec back');
                    return false;
                }
           
              $.post( "update_img.php", { imgs: new_img_num })
              .done(function( data ) {
              console.log( "Data Loaded: " + data );
              });
     
          });
        }
    Code (markup):
    What could be the problem?

    Thank you.
     
    supercain, Oct 25, 2013 IP
  17. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #17
    Yeah, that's probably not gonna work with my code -- jQuery doesn't even work how I work, so trying to do anything with that fat bloated idiotic crap attached to it is going to be problematic. Really whatever it is that code is trying to do, it's trying too hard. A lot of stuff is going on inside the events I'm not sure what good it is, and would probably benefit from a bit of preparation and pre-processing outside the events... Of course it has the 'wait for onload' nonsense that just makes it bigger, fatter and slower -- hallmarks of jQuery programmers... the laugh being they then have the cojónes to claim it somehow speeds up development and/or makes things simpler.

    Question: Are you trying to put the forward/back and/or controls on the same page, or a separate page? The above snippet is unclear as to that. I can do up a quick example of handling it either way.

    I was also thinking something like this would benefit from pulling images automatically from the directory to build the list, so you don't have to hardcode the image ID's, how many files, etc, etc... That would be easy enough to implement using glob() server-side.
     
    deathshadow, Oct 26, 2013 IP
  18. supercain

    supercain Greenhorn

    Messages:
    29
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #18
    Hi,

    i solved the issue and it works now. Its just kinda slow at the beginning but then it seems to run smoothly. Im just concerned about the server load. Wont my server collapse for having the page reload automatically so often? I actually wont use the script for over 25 minutes (continuous) a week though. I can send you the link by PM if you wish.
     
    supercain, Oct 26, 2013 IP
  19. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #19
    Could be any number of things causing that slowdown, including the first-load for any images.

    that's the problem with using AJAX for polling, or really any type of polling technology. The smaller you can keep the file and keeping the data being sent a static file like you are does reduce that 'pain' -- but really it hinges on how often you are sending that request -- part of why I dropped it to every half-second. Also would depend on how many people are trying to use it at once. Really though the simpler you keep the request and the data, the less of a worry this is unless you're gonna try supporting hundreds or thousands of users at once... especially if it's only for 25 minutes a day. Even so, you might want to add some form of lockout/shutdown/killswitch for it when not in use, just so someone doesn't walk across it and decide to use it to do a DDOS against you.

    I just updated the directory:
    http://www.cutcodedown.com/for_others/supercain/

    With a new set of code that's likely far leaner and faster than the jQ mess, and implements a few of those things I mentioned like auto-building the list... Lemme break down the files it uses:

    imageId.txt - the file containing which image to use. I've reduced it to only containing the number of the file so 1) the file_put_contents can be typecast to integer, making script injections impossible, and 2) make the file as small as possible.

    getImages.php uses glob to pull the images from the /selectImages directory, putting them in a nice convenient array. It also checks imageId.txt to set the current image index.

    template.php just some quick styling and outer markup for the demo. I like to keep it separate so I don't have to look at it when working on the 'functionality' code.

    update.php can be called directly or via AJAX. I use a $_GET['ajax'] as a trip for AJAX requests. It can be sent index=# to set the value in imageId.txt. If non-ajax it will show a list of images with working links non-scripting, or with scripting enabled forward/back buttons and call itself via AJAX to set the value using ajaxIdPut.js

    images.php simple updater with no controls, calls imageIdGet.js

    imagesWithControls.php update with controls, calls imageIdGetPut.js

    library.js just a few common functions used in all the other files, without becoming a fat bloated 'framework'. It's usually better/more efficient to pick and choose what you need in an interpreted language, than it is to crap all over the page wtih a massive 'framework' like jQuery... which is how the most complex of these -- ajaxIdGetPut.js plus library.js doesn't even come to as much code as what you were trying to do with jQuery NOT COUNTING JQ against the total.

    I also tossed all the code in a .rar file.

    The big feature of this version is that it's automated in terms of adding/removing content and generating the markup for them. getImages.php scans /selectImages, then images.php or imagesWithControls.php outputs the appropriate IMG tags with any needed classes/ID's. The scripting completely self-hooks off the parent, so nothing is hardcoded in terms of content delivery.

    Hope this helps...

    Side note, could be funny to watch when multiple people start trying to use the controls at once :D
     
    deathshadow, Oct 26, 2013 IP
    ryan_uk likes this.
  20. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,732
    Likes Received:
    1,998
    Best Answers:
    253
    Trophy Points:
    515
    #20
    Huh, that's odd. glob is returning empty on my server... works fine local. Probably a permissions issue.
     
    deathshadow, Oct 26, 2013 IP