Namespace is undefined - javascript

I am building a javaScript plug-in and I define a namespace in my plugin; but, the web page cannot find it. Please be as explicit as you be with your answer; as I learn better examining code, watching a video somebody doing live coding and testing.
Here is my HTML:
...
<article class="slider_cnt">
<div class="slider">
<img src="img/slide1.jpg" />
<img src="img/slide2.jpg" />
<img src="img/slide3.jpg" />
</div>
</article>
</div>
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/modernizr-2.6.2.min.js"></script>
<script type="text/javascript" src="js/elegant2_slider.js"></script>
<script type="text/javascript">
$(document).ready(function () {
elegantNamespace.initialize($('.slider'),'img'); // options setup
});
</script>
</body>
and my javaScript:
(function ($) {
this.elegantNamespace = this.elegantNamespace || {};
var ns = this.elegantNamespace;
// settings
var $slider; // class or id of carousel slider
var $slide; // could also use 'img' if you're not using a li
var $transition_time = 1000; // 1 second
var $time_between_slides = 2300; // 2.3 seconds
var $interval;
ns.initialize = function(fram, slide){ // options setup
$slider = fram;
$slide = slide;
startloop();
}
slides = function() {
return $slider.find($slide);
}
slides().fadeOut();
// set active classes
slides().first().addClass('active');
slides().first().fadeIn($transition_time);
// auto scroll
startloop = function () {
$interval = setInterval(
function () {
var $i = $slider.find($slide + '.active').index();
slides().eq($i).removeClass('active');
slides().eq($i).fadeOut($transition_time);
if (slides().length == $i + 1) $i = -1; // loop to start
slides().eq($i + 1).addClass('active');
slides().eq($i + 1).fadeIn($transition_time+ 2000);
}, $transition_time + $time_between_slides);
}
pauseLoop = function() {
window.clearInterval($interval);
}
$slider.hover(
function () {
pauseLoop(); // pause the loop
},
function () {
startloop(); //scroll()
});
})();

The browser recognizes your namespace fine. Your program is bugged.
You created variables $slider and $slide.
You use the initialize function to give those variables values:
ns.initialize = function(fram, slide){ // options setup
$slider = fram;
$slide = slide;
startloop();
}
Here you have a function that uses those variables:
slides = function() {
return $slider.find($slide);
}
In order for this function to work the variables must be initialized. Meaning that you have to call the initialize function before you call the slider function.
And this is where your problem is. By calling the slider function you are trying to use $slider which is not yet initialized. As a result your script breaks:
slides().fadeOut();
slides().first().addClass('active');
slides().first().fadeIn($transition_time);
At the end of your script you are also trying to use $slider:
$slider.hover(
function () {
pauseLoop(); // pause the loop
},
function () {
startloop(); //scroll()
});
To fix this move that code into the initialize function. That way it should work. Like this:
ns.initialize = function(fram, slide){
$slider = fram;
$slide = slide;
slides().fadeOut();
slides().first().addClass('active');
slides().first().fadeIn($transition_time);
$slider.hover(
function () {
pauseLoop();
},
function () {
startloop();
});
startloop();
}

Related

Add back and forward functionalities in slideshow

I made a slideshow with php and javascript and it slides the images just fine , but i'm a bit stuck at the back and forward functionalities and i would be grateful if you could help me a bit here.This is what i've done so far:
PHP:
$dir = 'images/slideshow';
$images = scandir($dir);
$i = 0;
echo '<div id="slideshow-wrapper">';
echo '<div id="slideshow-beta">';
foreach($images as $img){
if ($img != '.' && $img != '..') {
$i++;
echo '<img src="../images/slideshow/'.$img.'" class="img_'.$i.'">';
}
}
echo '</div>';
echo '<div id="slideshow-controller">';
echo '<div class="left-arrow-div"><span class="left-arrow" onclick="SlideShow(-1);"></span></div>';
echo '<div class="right-arrow-div"><span class="right-arrow" onclick="SlideShow(1);"></span></div>';
echo '</div>';
echo '</div>';
Javascript:
var i=1;
var begin=true;
function SlideShow(x){
if(x==-1){
i--;
}else if(x==1){
i++;
}
var total=$('#slideshow-beta img').length;
for(var j=1;j<=total;j++){
if($('.img_'+j).css('display')!='none'){
begin=false;
break;
}else{
begin=true;
}
}
if(i>total){
i=1;
$('.img_'+total).fadeOut(1000,function(){
$('.img_'+i).fadeIn(1000);
});
}else if(begin){
$('.img_'+i).show();
}else if(!begin){
$('.img_'+(i-1)).fadeOut(1000,function(){
$('.img_'+i).fadeIn(1000);
});
}
setTimeout(function(){
i++;
SlideShow(x);
},5000);
}
HTML:
<body onload="SlideShow(false);">
As you can see i tried to make an onclick event to change the 'i' value on run , though the value is changed , the image is not . Maybe because pressing back/forward calls another instance of the function instead of overwriting it.I don't know for sure , i'm lost on this one.
Here's a fiddle
I've made a major overhaul, but the idea stays the same (fiddle):
Changes to CSS:
.left-arrow, .right-arrow {
cursor: pointer;
/** display: none **/
}
#slideshow-controller {
z-index: 2;
position: absolute;
/** added **/
opacity: 0;
transition: opacity 300ms ease-in;
/***********/
}
#slideshow-wrapper:hover > #slideshow-controller {
opacity: 1;
}
Changes to HTML (removed inline onClick):
<div class="left-arrow-div"><span class="left-arrow">Back</span>
</div>
<div class="right-arrow-div"><span class="right-arrow">Forward</span>
</div>
Javascript:
var i = 0;
var images = $('#slideshow-beta img'); // cache all images
var total = images.length;
var timeout;
/*** hide all images at the start ***/
images.each(function (index) {
$(this).css({
display: 'none'
});
});
/*** bind event handlers to arrows ***/
$('.left-arrow').click(function () {
SlideShow(-1);
});
$('.right-arrow').click(function () {
SlideShow(1);
});
/*** Start the slideshow on 1st image ***/
SlideShow(0);
function SlideShow(x) {
if (isNaN(x)) { // throw error if x is not a number
throw new Error("x must be a number");
}
clearTimeout(timeout); // clear previous timeout if any to prevent multiple timeouts running
var current = (total + i + x % total) % total; // get the current image index
$(images[i]).fadeOut(1000, function () { // fade out the previous
$(images[current]).fadeIn(1000); // fade in the current
});
i = current; // set i to be the current
timeout = setTimeout(function () { // cache the timeout identifier so we can clean it
SlideShow(1);
}, 5000);
}
I have fixed your problems - the main problem was that you call the function inline - but the function doesn't exist at this moment (the milliseconds in pageload). The other one was your if (now with 3 = that includes the type - because false, 0, -1 and so on are "the same".
The only problem now is that the interval runs infinitely and can call the next image instantly after a manual change.
In conclusion I recommend you to use a library like cycle2 or anything like this.
https://jsfiddle.net/Lroatbzg/15/
jQuery(window).on('load', function() {
$("#slideshow-wrapper").hover(function(){
$(".left-arrow,.right-arrow").fadeIn();
}, function(){
$(".left-arrow,.right-arrow").fadeOut();
});
var i=1;
var total = $('#slideshow-beta img').length;
function SlideShow(x) {
if(x === -1) {
i--;
} else if(x === 1) {
i++;
}
if(i > total) {
i = 1;
}
$('#slideshow-beta img').hide();
$('#slideshow-beta .img_' + i).fadeIn(1000);
}
setInterval(function() {
i++;
SlideShow(i);
}, 5000);
jQuery('.left-arrow-div').on('click', function() {
SlideShow(-1);
});
jQuery('.right-arrow-div').on('click', function() {
SlideShow(1);
});
SlideShow(false);
});
Your fiddle throws a ReferenceError: SlideShow is not defined (Firefox using Firebug).
Try replacing function SlideShow(x){...} with SlideShow = function (x) {...} (https://jsfiddle.net/Lroatbzg/12/).
Honestly I don't know why the latter works, as those two statements are equivalent to me (any explanation on that?).
Declaring your function the other way around gets rid of the error - at least in my browser.
use
if(x=='-1'){
i--;
}else if(x=='1'){
i++;
}
instead of
if(x==-1){
i--;
}else if(x==1){
i++;
}
The problem is that the setTimeOut will execute the function SlideShow delayed. However, when you click a button, this delayed execution is not stopped. To stop this execution, I made a small change to the code. Furthermore, I solved the ReferenceError in jsfiddle by launching the onClick-functionality through jQuery.
This result can be checked here: https://jsfiddle.net/Lroatbzg/13/
$("#slideshow-wrapper").hover(function(){
$(".left-arrow,.right-arrow").fadeIn();
}, function(){
$(".left-arrow,.right-arrow").fadeOut();
});
var i=1;
var direction=1;
var begin=true;
var latest=Math.random();
function SlideShow(parameter){
if(latest!=parameter)
return; //Return when this function is not called through the last click or timeout.
var total=$('#slideshow-beta img').length;
i=i+direction;
if(i>total)
i=1;
if(i<1)
i=total;
begin=true;
for(var j=1;j<=total;j++)
{
if($('.img_'+j).css('display')!='none')
{
begin=false;
$('.img_'+total).fadeOut(1000,function(){
$('.img_'+j).css('display','none');
$('.img_'+i).fadeIn(1000);
});
break;
}
}
if(begin)
$('.img_'+i).show();
setTimeout(function(){
SlideShow(parameter);
},5000);
}
SlideShow(latest);
$("#left").click(function(){ latest=Math.random(); direction=-1; SlideShow(latest); });
$("#right").click(function(){ latest=Math.random(); direction=1; SlideShow(latest); });
The HTML is changed as follows:
<div id="slideshow-controller">
<div class="left-arrow-div" id="left"><span class="left-arrow">Back</span></div>
<div class="right-arrow-div" id="right"><span class="right-arrow">Forward</span></div>
</div>

Reverse jQuery effect after a given time

one quick question!
I am using the following code which does a "flip" card effect to flip a specific div element, when a certain link is mouse clicked. Is it possible to make the "flip" effect reverse after some time? Exactly as if I was clicking again with the mouse, but timed. I can do it now by cliking, but I would like to time it.
$(document).ready(function () {
$('.flip_card').click(function () {
var x = $(this).attr("id");
var i = x.substring(10);
$('.flip' + i + '').find('.card').toggleClass('flipped');
});
});
I have tried using the jquery functions delay() or settimeout, but I can only achieve that the first "flip" effect is delayed and happens after certain time. That is not what I want...
I hope my question is understanble enough.
Many thanks!
Try this.
$(document).ready(function () {
$('.flip_card').click(function () {
var x = $(this).attr("id");
var i = x.substring(10);
var ele = '.flip' + i + '';
$(ele).find('.card').toggleClass('flipped');
setTimeout(function(){
$(ele).find('.card').toggleClass('flipped');
}, 1000);
});
});
Try utilizing .queue()
$(document).ready(function () {
$(".flip_card").click(function () {
var x = this.id;
var i = x.substring(10);
$(".flip" + i).find(".card").toggleClass("flipped")
.queue("reset", function() {
setTimeout(function() {
$(".flip"+ i + " .card.flipped:eq(-1)").toggleClass("flipped");
// set duration here
}, 3000);
}).dequeue("reset");
});
});
You can use setTimeout(), but you should keep track of the timer ID so you can cancel it if the user clicks again before the timeout has executed. You can use the .data() function to store the timer ID so each card keeps track of its own timer ID.
$(document).ready(function () {
$('.flip_card').click(function () {
var i = $(this).attr('id').substring(10);
var $card = $('.flip' + i).find('.card');
// Clear the timeout if there is one.
var timerId = $card.data('timerId');
if (timerId) {
clearTimeout(timerId);
}
// Flip the card.
if (!$card.hasClass('flipped')) {
$card.addClass('flipped');
// Set the timeout so the card is flipped back after 3 seconds.
$card.data('timerId', setTimeout(function () {
$card.removeClass('flipped');
}, 3000));
} else {
$card.removeClass('flipped');
}
});
});
jsfiddle
How about something this simple. Just chaining should make it.
$(document).ready(function () {
$('.flip_card').bind('click', function() {
var x = $(this).attr("id");
var i = x.substring(10);
var ele = '.flip' + i + '';
$(ele).find('.card').toggleClass('flipped').delay(3000).toggleClass('flipped');
});
});

Call one event on a set of matches

I do what something like:
$('div > img').onAll('load', function() { alert('Loaded!') })
Which would alert "Loaded!" only once
I don't want this:
$('div > img').on('load', function() { alert('Loaded!'); });
because this would call the event after every single image has been loaded
Is there any ready function in jQuery that calls an event on a set of matches? Or do I have to write a custom function for it?
Create your own method
$.fn.onAll = function(ev, callback) {
var xhr = [];
this.each(function() {
var def = new $.Deferred();
var ele = document.createElement(this.tagName.toLowerCase());
ele['on'+ev] = function() {
def.resolve();
}
ele.src = this.src;
xhr.push(def);
});
$.when.apply($, xhr).then(callback);
return this;
}
to be used as
$('div > img').onAll('load', function() { alert('Loaded!'); });
FIDDLE
Try this
var $images = $("div > img")
, imageCount = $images.length
, counter = 0;
// one instead of on, because it need only fire once per image
$images.one("load",function(){
// increment counter everytime an image finishes loading
counter++;
if (counter == imageCount) {
// do stuff when all have loaded
alert('Loaded!');
}
}).each(function () {
if (this.complete) {
// manually trigger load event in
// event of a cache pull
$(this).trigger("load");
}
});
try something like this
$('body').on('load','div > img',function() { alert('Loaded!') });
Happy Coding :)

Add looping scroll to my carousel in Prototype-UI

I have a carousel that scrolls fine but when it comes to the end of the content (<li>.</li>) it just stops. I would like it to start again from the beginning.
Here is my code that I have hobbled together as not to good with JavaScript etc..
<script type="text/javascript">
function startscroll() {
x = window.setInterval(function scroll() {
hCarousel.scrollTo(hCarousel.currentIndex() + 3);
},3000);
}
function stopscroll() {
window.clearInterval(x);
}
function runTest() {
hCarousel = new UI.Carousel("horizontal_carousel", {direction: "horizontal"});
startscroll();
$('horizontal_carousel').observe('mouseover', stopscroll);
$('horizontal_carousel').observe('mouseout', startscroll);
}
Event.observe(window, "load", runTest);
</script>
Thanks for any help
Dave.
change this
$('horizontal_carousel').observe('mouseover', stopscroll);
$('horizontal_carousel').observe('mouseout', startscroll);
to
$('horizontal_carousel').onmouseover = function(){
stopscroll();
}
$('horizontal_carousel').onmouseout = function(){
startscroll();
}`

Reset slide interval JQuery

I've made a slide show width a javascript and Jquery. But I need to reset the slide interval when the user is navigating manualy to the next or previous slide. I am relatively new to javascipt and it's syntax. Any help will be appriciated. Here is my code:
<script type="text/javascript" src="/elements/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
var currentSlideId = 0;
var slidesAmount = 0;
function selectSlide(id) {
jQuery(".startpage-test.slide" + id).show().siblings(".startpage-test").hide();
jQuery(".slideshow-show-active.slide" + id).addClass("active").siblings(".slideshow-show-active").removeClass("active");
}
function nextSlide() {
currentSlideId++;
if (currentSlideId >= slidesAmount) currentSlideId = 0;
selectSlide(currentSlideId);
}
function prevSlide() {
currentSlideId--;
if (currentSlideId < 0) currentSlideId = slidesAmount - 1;
selectSlide(currentSlideId);
}
jQuery(document).ready(function() {
slidesAmount = jQuery(".startpage-test").length;
jQuery(".show_previous").click(function() {
prevSlide();
return false;
});
jQuery(".show_next").click(function() {
nextSlide();
return false;
});
window.setInterval(function() {
nextSlide();
}, 7000);
});
jQuery("object.flashContent").each(function () {
swfobject.registerObject(jQuery(this).attr("id"), "9.0.0");
});
</script>
The next-/prev-button looks like this:
<div class="show_next">
<span class="slide_nav"><img src="/elements/next.png" width="57" alt="Next"></span>
</div>
<div class="show_previous">
<span class="slide_nav"><img src="/elements/prev.png" width="57" alt="Previous"></span>
</div>
In all slides there is a link of course, and it would also be nice to stop the slide interval when hovering this a-tag. Unfortunately I don't know how to do this either.
You can assign the result of setInterval() to a variable, then call clearInterval() passing in that variable whenever you need. So in your case, change this code:
window.setInterval(function() {
nextSlide();
},
to this:
var interval = window.setInterval(function() {
nextSlide();
},
Then, in any.hover(), .mouseenter(), .click() or whatever other mouse event handler you are using, simply call:
window.clearInterval(interval);
Of course, you need to reinstate the interval when you want to restart it!

Categories

Resources