Jump to content

stop a auto slide


alzami

Recommended Posts

i have a created an auto image slide gallery which i want to stop whenever i click on the "close auto " button.but cant figure out how to.so please help me out on this!!i've deleated the "next" and "previous" sections of javascript for simplification because that part works just fine.

<!doctype html><html><head><meta charset="utf-8"><title>Untitled Document</title><style>#this{	width:500px;	height:100px;	border:1px solid blue;	display:none;}#this img{	width:100px;	height:100px;}#that {	width:300px;height:300px;	position:absolute;top:120px;	left:200px;border:1px solid black;}#that img{	width:300px;height:300px;}	a:hover{		color:red;	}</style></head><body style="position:relative;"><div id="this"></div><div style="height:30px;width:100px;background-color:grey;float:left;position:absolute;top:0px;left:510px;" id="next"><a href="#" onClick="show();">next</a></div><div style="height:30px;width:100px;background-color:grey;float:right;position:absolute;top:0px;left:0px;" id="previous"><a href="#" onClick="showBack();">previous</a></div><div style="height:30px;width:100px;background-color:grey;float:left;position:absolute;top:0px;left:600px;" id="auto"><a href="#" onClick="auto();">auto</a></div><div style="height:30px;width:100px;background-color:grey;float:left;position:absolute;top:50px;left:600px;" id="auto"><a href="#" onClick="close();">closeAuto</a></div><div id="that"><img src="image1.jpg" /></div><script>var i;	var imag = ["image1.jpg","image2.jpg","image3.jpg","image4.jpg","image5.jpg"]function load(){	var m=document.getElementById("this");		for(i=0;i<imag.length;i++){		m.innerHTML += '<img src="'+imag[i]+'" id="'+i+'"  />';	}	}	</script><script>load();</script><script>a=0;function auto(){		var m=document.getElementById("that");	a++;	if(a==imag.length){			m.innerHTML='<img src="'+imag[0]+'" />';			a=0;		}else{		m.innerHTML='<img src="'+imag[a]+'" />';		}					var c=setTimeout(auto,700);		}</script><script>function close(){	clearTimeout(c);	var m=document.getElementById("that");	m.innerHTML='<img src="'+imag[a]+'" />';}</script></body></html>
Edited by alzami
Link to comment
Share on other sites

you defined "var c" inside "auto"'s scope so no other function (close, in this case) knows what it is. define var c outside the function so the other functions can see it, and assign setTimeout() to c (not var c) inside the function

Link to comment
Share on other sites

Well, let's kill the thing...

 

Rather than...

clearTimeout(c);

...use...

clearTimeout(c);c = null;

...replace...

onClick="auto();"

...with...

onClick="c=0;auto();"

...then at the top of auto() add...

if (c==null) {return;}

...also when you declare the global c set it to zero.

Edited by davej
Link to comment
Share on other sites

i used the codes as you described;here is the full code which include "next" "previous" button and all the rest.I have made it such a way that if i use the next and previous button before clicking auto button ,the auto will start from the next image. .i used the codes that u suggested but its giving me an error.though the codes works still.but it cant manage to stop the auto scroll. :(

<!doctype html><html><head><meta charset="utf-8"><title>Untitled Document</title><style>#this{	width:500px;	height:100px;	border:1px solid blue;	display:none;}#this img{	width:100px;	height:100px;}#that {	width:300px;height:300px;	position:absolute;top:120px;	left:200px;border:1px solid black;}#that img{	width:300px;height:300px;}	a:hover{		color:red;	}</style></head><body style="position:relative;"><div id="this"></div><div style="height:30px;width:100px;background-color:grey;float:left;position:absolute;top:0px;left:510px;" id="next"><a href="#" onClick="show();">next</a></div><div style="height:30px;width:100px;background-color:grey;float:right;position:absolute;top:0px;left:0px;" id="previous"><a href="#" onClick="showBack();">previous</a></div><div style="height:30px;width:100px;background-color:grey;float:left;position:absolute;top:0px;left:600px;" id="auto"><a href="#" onClick=" c=0 ;auto();">auto</a></div><div style="height:30px;width:100px;background-color:grey;float:left;position:absolute;top:50px;left:600px;" id="auto"><a href="#" onClick=" close();">closeAuto</a></div><div id="that"><img src="image1.jpg" /></div><script>var i;	var imag = ["image1.jpg","image2.jpg","image3.jpg","image4.jpg","image5.jpg"]function load(){	var m=document.getElementById("this");		for(i=0;i<imag.length;i++){		m.innerHTML += '<img src="'+imag[i]+'" id="'+i+'"  />';	}	}	load();var p=0;var k=0;var a=0;function show(){	var m=document.getElementById("that");	var s=document.getElementById("next");	var d=document.getElementById("previous");	p++;	if(p==imag.length){		p=0;		a=k=p;		m.innerHTML='<img src="'+imag[p]+'" />';	}else{	m.innerHTML='<img src="'+imag[p]+'" />';    a=k=p;	}}function showBack(){	var m=document.getElementById("that");	var s=document.getElementById("next");	var d=document.getElementById("previous");		if(k==0){		k=imag.length-1;				m.innerHTML='<img src="'+imag[k]+'" />';					a=p=k;		}		else{			k--;		m.innerHTML='<img src="'+imag[k]+'" />';										a=p=k;		}	}var c;if(c==null)     {return;}function auto(){		var m=document.getElementById("that");	a++;	if(a==imag.length){			m.innerHTML='<img src="'+imag[0]+'" />';			a=0;		}else{		m.innerHTML='<img src="'+imag[a]+'" />';		}					 c=setTimeout(function(){auto();},700);		 		}function close(){		var m=document.getElementById("that");	clearTimeout(c);	c=null;	m.innerHTML='<img src="'+imag[a]+'" />';	}</script></body></html>
Link to comment
Share on other sites

Should be...

var c=0;function auto(){  if(c==null) {return;}[etc...]

Also change close() to a different name. I think close is probably a reserved word.

 

And you should stop using "this" for anything. It has a proper use.

Edited by davej
Link to comment
Share on other sites

added it and changed close to clse.still not doing anything .getting frustrated

var c=0;function auto(){  if(c==null) {return;}		var m=document.getElementById("that");	a++;	if(a==imag.length){			m.innerHTML='<img src="'+imag[0]+'" />';			a=0;		}else{		m.innerHTML='<img src="'+imag[a]+'" />';		}					 c=setTimeout(function(){auto();},700);		 		}function clse(){		var m=document.getElementById("that");	clearTimeout(c);	c=null;	m.innerHTML='<img src="'+imag[a]+'" />';	}</script>
Link to comment
Share on other sites

Search the document for close and make sure you have them all changed.

 

Also put... alert('close it');

 

...inside the clse function so that you know when it ran.

Edited by davej
Link to comment
Share on other sites

if i do that way it stops but neither next nor previous button works

<script>function auto(){  if(c==null) {return;}		var m=document.getElementById("that");	a++;	if(a==imag.length){			m.innerHTML='<img src="'+imag[0]+'" />';			a=0;		}else{		m.innerHTML='<img src="'+imag[a]+'" />';		}					 c=setTimeout(function(){auto();},700);		 		}function clse(){		var m=document.getElementById("that");	clearTimeout(c);var c=null;	m.innerHTML='<img src="'+imag[a]+'" />';	}</script>
Link to comment
Share on other sites

Go just above your first script block and insert...

<script>window.onerror = function(m, u, l){  alert('Javascript Error: '+m+'nURL: '+u+'nLine Number: '+l);  return true;}</script>

...then add alerts as the first item inside each of your functions.

Edited by davej
Link to comment
Share on other sites

thats my final code and works just same as my expectation .thanks for your patience :)

<!doctype html><html><head><meta charset="utf-8"><title>Untitled Document</title><style>#this{	width:500px;	height:100px;	border:1px solid blue;	display:none;}#this img{	width:100px;	height:100px;}#that {	width:300px;height:300px;	position:absolute;top:120px;	left:200px;border:1px solid black;}#that img{	width:300px;height:300px;}	a:hover{		color:red;	}</style></head><body style="position:relative;"><div id="this"></div><div style="height:30px;width:100px;background-color:grey;float:left;position:absolute;top:0px;left:510px;" id="next"><a href="#" onClick="show();">next</a></div><div style="height:30px;width:100px;background-color:grey;float:right;position:absolute;top:0px;left:0px;" id="previous"><a href="#" onClick="showBack();">previous</a></div><div style="height:30px;width:100px;background-color:grey;float:left;position:absolute;top:0px;left:600px;" id="auto"><a href="#" onClick=" auto();">auto</a></div><div style="height:30px;width:100px;background-color:grey;float:left;position:absolute;top:50px;left:600px;" id="auto"><a href="#" onClick=" clse();">closeAuto</a></div><div id="that"><img src="image1.jpg" /></div><script>window.onerror = function(m, u, l){  alert('Javascript Error: '+m+'nURL: '+u+'nLine Number: '+l);  return true;}</script><script>var i;	var imag = ["image1.jpg","image2.jpg","image3.jpg","image4.jpg","image5.jpg"];function load(){	var m=document.getElementById("this");		for(i=0;i<imag.length;i++){		m.innerHTML += '<img src="'+imag[i]+'" id="'+i+'"  />';	}	}</script><script>load();</script><script>var p=0;var k=0;var a=0;function show(){	var m=document.getElementById("that");	var s=document.getElementById("next");	var d=document.getElementById("previous");	p++;	if(p==imag.length){		p=0;		a=k=p;		m.innerHTML='<img src="'+imag[p]+'" />';	}else{	m.innerHTML='<img src="'+imag[p]+'" />';    a=k=p;	}}</script><script>function showBack(){	var m=document.getElementById("that");	var s=document.getElementById("next");	var d=document.getElementById("previous");		if(k==0){		k=imag.length-1;				m.innerHTML='<img src="'+imag[k]+'" />';					a=p=k;		}		else{			k--;		m.innerHTML='<img src="'+imag[k]+'" />';										a=p=k;		}	}</script><script>var c=0;function auto(){  if(c==null) {return;}		var m=document.getElementById("that");	a++;	if(a==imag.length){			m.innerHTML='<img src="'+imag[0]+'" />';			a=0;		}else{		m.innerHTML='<img src="'+imag[a]+'" />';		}					 c=setTimeout(function(){auto();},700);		 		}function clse(){		var m=document.getElementById("that");	clearTimeout(c);	c=null;	m.innerHTML='<img src="'+imag[a]+'" />';	}</script></body></html>
Link to comment
Share on other sites

I did a complete rewrite of your example (and in the time you got your problem solved, regardless I'll post anyways).

<!doctype html>    <html>    <head>        <meta charset="utf-8">        <title>Untitled Document</title>        <style>            #gallery{                width:500px;                height:100px;                border:1px solid blue;                display:none;            }            #gallery img{                width:100px;                height:100px;            }            #current {                width:300px;height:300px;                position:absolute;top:120px;                left:200px;border:1px solid black;            }            #current img{width:300px;height:300px;}            div.aButton{                height:30px;                width:100px;                background-color:grey;                position:absolute;                left:510px;            }            #next{left:510px;}            #previous{left:0px;}            #auto{left:600px;}            #closeAuto{top:50px;left:600px;}            a:hover{color:red;}        </style>    </head>    <body style="position:relative;">        <div id="gallery"></div>        <div class="aButton" id="next">            <a href="#" onClick="myGallery.forward();">next</a>        </div>        <div class="aButton" id="previous">            <a href="#" onClick="myGallery.back();">previous</a>        </div>        <div class="aButton" id="auto">            <a href="#" onClick="myGallery.auto();">auto</a>        </div>        <div class="aButton" id="closeAuto">            <a href="#" onClick="myGallery.stop();">closeAuto</a>        </div>        <div id="current">            <img src="css/images/animated-overlay.gif" />        </div>    <script>        //my polyfill instance function for calling constructors with        // numerous arguments        if(!Function.prototype.instance)            Function.prototype.instance = function(classname,args){                //allows one to call a new constructor with a variable length                // of arguments I mostly use it when testing if this relates                // to the constructor from within that same constructor                var args = Array.prototype.slice.call(args);                args.unshift("");//first argument is always ignored, so                   //add a placeholder in the argument array so that                   // the 1st REAL argument isn't overlooked.                return new (Function.bind.apply(classname,args));                }        function slider(){            //makes sure that if you call the constructor without the "new"            // operator that its called correctly            if(!(this instanceof slider))                return Function.instance(slider,arguments);            this.gallery=document.getElementById("gallery");            this.previous=document.getElementById("previous");            this.current=document.getElementById("current");            this.next=document.getElementById("next");            this.iterator=null;            var _intervalID=null;//private variable            for(var i=0;i<arguments.length;i++){                var img = new Image()                img.src = arguments[i];                img.alt = "alt ["+i+"]";                this.gallery.appendChild(img);            }            this.iterator = this.gallery.firstElementChild;            this._updateCurrent();            this.auto = function auto(forward,interval){                    if(_intervalID!=null) return;                    forward = forward !=false; //defaults forward to true;                    interval = typeof interval =="number"                        ?Math.max(0,parseInt(interval))//validate interval                        :700;//interval default                    if(forward)                        _intervalID = setInterval(this.forward.bind(this),interval);                    else                        _intervalID = setInterval(this.back.bind(this),interval);                };            this.stop = function stop(){                    if(_intervalID==null)return;                    //can't stop interval since slider doesn't know the ID                    clearInterval(_intervalID);                    _intervalID=null;                };        };        //helper function to be called internally        slider.prototype._updateCurrent=function _updateCurrent(){            this.current.innerHTML=""            this.current.appendChild(this.iterator.cloneNode(true));            };        slider.prototype.forward = function forward(){            //do nothing if too few images in gallery            if(this.gallery.children.length<2)                return;            if(this.iterator.nextElementSibling === null)                //go back to beginning if current image is the last                 this.iterator = this.gallery.firstElementChild            else                 //else go to next image                this.iterator = this.iterator.nextElementSibling;            return this._updateCurrent();            };        slider.prototype.back = function back(){            //do nothing if too few images in gallery            if(this.gallery.children.length<2)                return;            if(this.iterator.previousElementSibling === null)                //go back to last image if current image is the first                 this.iterator = this.gallery.lastElementChild            else                 //else go to previous image                this.iterator = this.iterator.previousElementSibling;                        return this._updateCurrent();            };        var myGallery = slider(           "image1.jpg", "image2.jpg",           "image3.jpg", "image4.jpg",           "image5.jpg");    </script>    </body></html> 

I used an OOP approach so all the behavior and info is consolidated into a single object (and so its a little more readable). as it is now its made specifically bound to your particular example. but spending a couple more minutes on the code I can make it generic enough that you can easily have multiple galleries on a page, if you'll ever need to.

Edited by Hadien
  • Like 1
Link to comment
Share on other sites

i am new to javascript as well as oop.i have decided to study your code.i didn't understand some terms .may i ask some question regarding your codes.

how

Array.prototype.slice.call(args)

this works?and

what does

Function.prototype.instance

it represents?

Link to comment
Share on other sites

well let's break each down to single words. grab a cold one as this is a long post.

 

starting with Array.prototype.slice.call(args). since you likely already know what an Array is I'll be brief with it. An array is a contiguous collection of data, each data point having an index which the array will refer to. Arrays also have a length property and numerous functions to go with it. may seem obvious, but these index/length qualities are whats important, which I'll explain later in the post.

 

prototype is javascripts way of predefining properties and methods that are directly available to all instances of the class (in this case all Array instances will have the slice function). if the current object doesn't have the property or method defined, it'll check it's prototype to see if its defined there, this is why when you create a new object it already comes with a set of functions you didn't define like toString (which converts the object into a string if javascript expected a string when given an object). you can easily overwrite (or "shadow", as the term is called) a prototype's property/method by defining another property/method of the same name at a level closer than the prototype. for instance Function has a prototype, which in turn has an Object's prototype. this means Function has Object's toString method. however Function has shadowed Object.prototype.toString() by defining a Function.prototype.toString(), so instead of function.toString() printing "[Object object]", it'll print either the actual code in a string, or the function with the inside code replaced with "[native code]" (exactly what's printed can vary from browser to browser, but pretty much only functions that aren't user defined will print "[native code]".

 

slice is an array function that makes a shallow copy of the current array instance it accepts upto two index arguments (begin, end) to show what to copy from the current array, and returns that copy as an array. if you don't pass in arguments to it (which i don't), it assumes you want to shallow-copy the entire array.

 

call is a function defined in Function.prototype. this means every single function in javascript has access to it. call (and it's similar sibling methods: apply and bind) controls what the "this" keyword will be when it runs the function, the first argument is the "this" reference, while all following arguments will be given to the method it's calling as that method's arguments. so slice.call(args,begin,end) is basically the same as args.slice(begin,end)…basically IF args is an actual array.

 

so why am I running Array.prototype.slice.call(args) and not simply args.slice()? simple answer is because args isn't an Array. args is an Arguments Object (rather should be, I've made no checks to enforce). when a function is running they have access to an Arguments object (uppercase) which is stored in arguments (lowercase) and arguments, understandably, stores all the arguments that were passed to the function. well what I am doing is that I'm taking all the arguments passed into slider (your images urls) and giving them to the instance method. So args is slider's arguments

 

Back to Array.prototype.slice.call(args)… args isn't an array, but it IS array-like. args has an index like arrays do, and a length property like arrays. but it has other properties like caller and callee which arrays don't have. and args doesn't have access to methods that Arrays have like indexOf, push, slice, or what I need unshift. SO I grab Array's slice method (via Array.prototype.slice) and tell it to use args as if its an array (via .call(args)). Since slice doesn't use any other Array methods inside it, just does index copies and uses length, it has no idea that args is NOT an array, and slice will return args converted into an array.

 

as for Function.prototype.instance

 

it is a function that I added so that i can make a call to a class's constructor that could accept any amount of arguments. in your case I wrote slider in a way that it can accept as many arguments (images) as you want. since I wanted to add support where its not necessary to prepend slider with the "new" keyword, like how it is done in jQuery (you never have to say "new $()" cause they added support for that), I gave you the instance method I wrote up in my own polyfill.js. The if(Function.prototype.instance) is a check to see if there is already a method "instance()" defined in Function's prototype. Now there shouldn't be one as its not documented nor planned for Function to have such a method and in all honestly it shouldn't. however since you and I can't separate classes from Function it kinda leaves our hands tied.

 

I once tried writing my own class Object which would allow me to use classical inheritance in javascript more simply. class would be more or less a wrapper/adapter object which I could pass simple commands like:

Dog.extends(Animal)   .implements(walkable)   .overloads({speak:function(){return "woof";}); 

where Dog and Animal are class constructors, walkable is an interface, and speak is an overloaded and inheritable function. the entire thing fell apart when I couldn't code for dynamic constructors so I just moved all my class Object methods to Function.prototype, with instance being one of my remanent 'class' methods. If I ever figure out a better structure for my class object, I'll come back and clean up these remnants, but for now you have access to this stand-alone method that you can use.

 

While simply adding to Function.prototype is bad, its "a slap on the wrist" bad, while giving us so much more utility with Function. The if() check is there for consistentcy (all other polyfills use similar checks) and as a form of "future-proofing". if ECMA script ever does come out with it's own instance method (unlikely) then my code here won't overwrite it, and will probably be better since it'll have more access to the insides of javascript.

 

hoped that answered more questions than it probably gave you. :good:

Link to comment
Share on other sites

There are other issues that could be mentioned:

 

Absolute and relative positioning should be avoided unless they are truly needed. They aren't needed here.

Edited by davej
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...