I don't know what's wrong with my code. I cannot pass a function in my javascript, [i don't want to put it inline]
My problem is my prev button and next button doesn't work, I also tried to put return false on prev and next to stop refreshing the page, but it still refreshing on click.
This is my code [please also see my comments] and my codepen:
$(document).ready(function slider() {
$('#img1').show('fade', 500);
$('#img1').delay(5000).hide("slide", { direction: 'left' }, 500);
});
var count = 2;
setInterval(function loop() {
var all = document.getElementsByTagName('li').length; // <-- i got the li elements so i did the same to prev and next
$('#img' + count).show('slide', { direction: 'right' }, 500);
$('#img' + count).delay(5500).hide('slide', { direction: 'left' }, 500);
if (count === all) {
count = 1;
} else {
count += 1;
}
}, 6500);
var sliderInt = 1;
var sliderNext = 2;
document.getElementsByClassName('prev').onclick = function prev() { // <-- not working
console.log('clicked prev');
var newSlide = sliderInt - 1;
showSlide(newSlide);
return false;
}
document.getElementsByClassName('next').onclick = function next() { // <-- not working
console.log('clicked next');
var newSlide = sliderInt + 1;
showSlide(newSlide);
return false;
}
function stopLoop() {
window.clearInterval(loop());
}
function showSlide(id) { // <-- this function doesn't work from prev and next
stopLoop(); // <-- I want to stop the loop() function when prev and next is clicked
if (id > count) {
id = 1;
} else if (id < 1) {
id = count;
}
$('li').hide('slide', { direction: 'left' }, 500);
$('#img' + id).show('slide', { direction: 'right' }, 500);
sliderInt = id;
sliderNext = id + 1;
window.slider(); // <-- I want to call the function slider here
}
a fix demo will be much appreciated :)
When you use the document.getElementsByClassName('prev').onclick you got an array. Use it like below
document.getElementsByClassName('prev')[0].onclick
document.getElementsByClassName('next')[0].onclick
getElementsByClassName returns a HTMLCollection. So you need to pass the relevant index to which you want to add the onclick function
document.getElementsByClassName('next')[0]
But this will attach the event only on the first element in the collection.
An more relevant example is
var list = document.getElementsByClassName('next or prev');
for (var i = 0, len = list.length; i < len; i++) {
(function(i){ // creating closure
list[i].addEventListener('click',function(){
// code you want to execute on click of next or prev
}
}(i))
}
As you are already using jquery you can avoid all this if you use class selector
$('.next or .prev').on('click',function(event){
// relevant code
})
Related
I want to trigger an event to execute code wrapped in $('.selector').on('event').
The selector change just before I trigger the event.
To understand the problem : I have a text on page 1 and the function trigger a click to go to the page 2 (this works btw!). So now I'm on page 2 and I want to trigger a click to execute code in on() method. And this doesn't work.
I've tried many things and nothing works, the only way to execute the code in on() method is to manually click on the selector.
This is the entire code actually :
jQuery(function() {
// the input field
$input = jQuery("input[type=\'search\']");
// clear button
var $clearBtn = jQuery("button[data-search=\'clear\']"),
// prev button
$prevBtn = jQuery("button[data-search=\'prev\']"),
// next button
$nextBtn = jQuery("button[data-search=\'next\']"),
// the context where to search
$content = jQuery(".search_content"),
// jQuery object to save <mark> elements
$results,
// the class that will be appended to the current
// focused element
currentClass = "current",
// top offset for the jump (the search bar)
offsetTop = 50,
// the current index of the focused element
currentIndex = 0,
//the current ajaxpage
currentPage = 1;
/**
* Jumps to the element matching the currentIndex
*/
function jumpTo() {
if ($results.length) {
var position,
$current = $results.eq(currentIndex);
$results.removeClass(currentClass);
if ($current.length) {
$current.addClass(currentClass);
position = $current.offset().top - offsetTop - 100;
window.scrollTo(0, position);
}
}
}
var mark = function() {
// Read the keyword
var keyword = $input.val();
// empty options
var options = {};
// Remove previous marked elements and mark
// the new keyword inside the content
jQuery(".search_content").unmark({
done: function() {
jQuery(".search_content").mark(keyword, options);
$results = $content.find("mark");
currentIndex = 0;
jumpTo();
}
});
};
function registerClear() {
$input.on("input", function() {
searchVal = this.value;
$content.unmark({
done: function() {
$content.mark(searchVal, {
separateWordSearch: true,
done: function() {
$results = $content.find("mark");
currentIndex = 0;
console.log(searchVal);
console.log("page2");
jumpTo();
}
});
}
});
});
}
registerClear();
/**
* Clears the search
*/
$clearBtn.on("click", function() {
$content.unmark();
$input.val("").focus();
});
/**
* Next and previous search jump to
*/
$nextBtn.add($prevBtn).on("click", function() {
if ($results.length) {
currentIndex += jQuery(this).is($prevBtn) ? -1 : 1;
if (currentIndex < 0) {
currentIndex = $results.length - 1;
}
if (currentIndex > $results.length - 1) {
currentIndex = 0;
}
//TODO : - LINK DONE - SEARCH ON EACH PAGE IF THERE ARE OCCURENCE
if (currentIndex == 0 && jQuery(this).is($nextBtn)) {
if (confirm("No more instances found! Go to the next page?")) {
alert("NEXT PAGE");
jQuery("a[data-page=\'2\']").click();
jQuery(document).ready(function() {
jQuery(".search_content").click();
});
jQuery(document.body).on("click", ".search_content", mark)
registerClear();
} else {
//do nothing
}
}
jumpTo();
}
});
});
this is the important part:
if (currentIndex == 0 && jQuery(this).is($nextBtn)) {
if (confirm("No more instances found! Go to the next page?")) {
alert("NEXT PAGE");
jQuery("a[data-page=\'2\']").click();
jQuery(document).ready(function() {
jQuery(".search_content").click();
});
jQuery(document.body).on("click", ".search_content", mark)
registerClear();
} else {
//do nothing
}
}
What I've tried :
I've search many things on SO.
Since the content on which I trigger the event is loaded via ajax I thought it was because I triggered the event to soon, so I've tried wrapping my code in document.ready, or with setTimeOut function. No results.
I've tried this :
jQuery('#bar')[0].click();
This :
jQuery(document).ready(function(){
jQuery('#foo').on('click', function(){
jQuery('#bar').simulateClick('click');
});
});
jQuery.fn.simulateClick = function() {
return this.each(function() {
if('createEvent' in document) {
var doc = this.ownerDocument,
evt = doc.createEvent('MouseEvents');
evt.initMouseEvent('click', true, true, doc.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
this.dispatchEvent(evt);
} else {
this.click(); // IE Boss!
}
});
}
I've tried putting the trigger after the on() method.
I've tried changing the element on which I do the event.
And also changing the event triggered.
Now I feel like I've tried everything, so I am asking for your help please.
$('element_selector').trigger('eventname', param1, param2,...);
this will trigger given event, params are optional if required
I do not have much experience in animation on Jquery. I want to make a simple animation that will highlight my text line by line with the possibility of stopping. I know how to do something like this for one line but I have no idea how to deal with loop.
here is my code:
var lines = $('#page')[0].getClientRects();
for (var i=0, max = lines.length; i < max; i++)
{
$('#under_liner')
.queue(function() {
$(this).css('top', lines[i].bottom).dequeue();
})
.animate({
width: lines[i].right - lines[i].left
}, 1000 )
.queue(function() {
$(this).css('width', 0).dequeue();
});
}
and jsfiddle http://jsfiddle.net/mz03kfua/2
I don't know if this is exactly what you are looking for, but here's how I'd do it.
Make a function that does the underlining
Make a recursive call on animation callback
Create a global variable to keep count of the current underlined line
Add a boolean that stops the function when false
var lines = $('#page')[0].getClientRects();
var play = true;
var index = 0;
underlineLine();
$('button').click(function(){
play = !play
if(play){
underlineLine()
$(this).html("STOP")
}else{
$(this).html("CONTINUE")
}
})
function underlineLine(){
if(index >= lines.length) return
if(play){
$('#under_liner').css('top', lines[index].bottom).dequeue();
$('#under_liner').css('width','0px');
$('#under_liner').animate({
width: lines[index].right - lines[index].left
}, 1000, function(){
underlineLine(index++)
})
$('#under_liner').css('width', 0).dequeue();
}
}
HERE IS A FIDDLE WITH THE CODE.
Hope it helps.
http://jsfiddle.net/mz03kfua/4/
var lines = $('#page')[0].getClientRects();
var current = 0;
var element;
function animateLine() {
if(typeof lines[current] !== "object") {
return;
}
var line = lines[current];
element = jQuery("<div />", {"class": "under_liner"}).prependTo("#page");
element.css({top: line.bottom}).animate({width: line.width}, 1000, function() {
current++;
animateLine();
});
}
function stopLine(e) {
e.preventDefault();
element.stop(true);
}
jQuery(".stop").click(stopLine);
animateLine();
I am trying to create a div with content scrolling horizontally after a specific period of time - Like a slide show. I am using mcustomscollbar plugin. I am using a for loop to increment the id's and using the scrollTo function to slide the content but the scroll jumps to the last one.
Here its the js
for (var num = 1; num < 24; num++) {
var idj = '#' + 'id' + num;
var dlp = scrollToI(idj);
}
function scrollToI(person) {
setTimeout(function () {
console.log(person);
$('#content1').mCustomScrollbar("scrollTo", person);
}, 2000);
}
Fiddle : http://jsfiddle.net/infern00/3psLU/
ScrollBar Plugin used : http://manos.malihu.gr/jquery-custom-content-scroller/
You mean something like this:
$(document).ready(function () {
$("#content1").mCustomScrollbar({
axis: "x",
theme: "dark-thick",
advanced: {
autoExpandHorizontalScroll: true
}
});
var i = 1;
var interval = setInterval(function () {
var idj = '#' + 'id' + i;
console.log(idj);
scrollToI(idj);
if (i > 23) clearInterval(interval);
i++;
}, 2000);
function scrollToI(person) {
$('#content1').mCustomScrollbar("scrollTo", person);
}
});
Check the FIDDLE
I cant get my head around this, been trying many many different ways but no luck.. Basically, I'm trying to pause the animation on mouseOver and resume it on mouseOut. I was able to make it pause by simply using clearTimeout() but I have no idea on how to resume it back on. Please kindly advise me with a correct solution and syntax.
Thank you in advance!
(function ($) {
$.fn.simpleSpy = function (interval, limit) {
limit = limit || 3;
interval = interval || 3000;
items = [];
return this.each(function () {
$list = $(this),
currentItem = 0,
total = 0; // initialise later on
var i = 0;
smplet = $list.clone();
smplet.css("display","none");
$("body").append(smplet);
total = smplet.find('> li').length;
$list.find('> li').filter(':gt(' + (0) + ')').remove();
$list.css("display","");
height = $list.find('> li:first').height();
$list.wrap('<div class="spyWrapper" />').parent().css({ height : 55, position:"relative", overflow:"hidden" });
$('.close').click(function(){
clearTimeout(timec);
if(currentItem == 0 && smplet.length != 1)
delitem=total;
else
delitem=currentItem - 1;
smplet.find('> li').eq(delitem).remove();
currentItem--;
var temp=smplet.find('> li').eq(currentItem).clone();
var $insert = temp.css({
"margin-top":-height-height/3,
opacity : 0
}).prependTo($list);
// fade the LAST item out
$list.find('> li:last').animate({ opacity : .5 ,"margin-top":height/3}, 500, function () {
$(this).remove();
});
$insert.animate({"margin-top":0,opacity : 1 }, 500).animate({opacity : 1},1000);
currentItem++;
total=smplet.find('> li').length;
if (currentItem >= total) {
currentItem = 0;
}
if (total == 1){
simpleSpy.stop();
}
else if(total == 0){
$("#topbar").hide();
}
timec=setTimeout(spy, interval);
});
currentItem++;
function spy() {
var temp=smplet.find('> li').eq(currentItem).clone();
var $insert = temp.css({
"margin-top":-height-height/3,
opacity : 0,
display : 'none'
}).prependTo($list);
$list.find('> li:last').animate({ opacity : .5 ,"margin-top":height/3}, 500, function () {
$(this).remove();
});
$insert.animate({"margin-top":0,opacity : 1 }, 500).animate({opacity : 1},1000);
$insert.css("display","");
currentItem++;
if (currentItem >= total) {
currentItem = 0;
}
timec=setTimeout(spy, interval);
}
timec=setTimeout(spy, interval);
});
};
$('ul.alerts')
.mouseover(function(){
clearTimeout(timec);
})
.mouseout(function(){
timec=setTimeout(spy, interval);
});
})(jQuery);
Call
$(document).ready(function() {
$('ul.alerts').simpleSpy();
});
jsfiddle with html and css
http://jsfiddle.net/1781367/3eK4K/3/
I changed the timeout, which you were setting over and over, to an interval, which you only need to set once. Then I added a "paused" property that is set to true on mouseover and back to false on mouseout.
var paused = false;
$list.mouseover(function() { paused = true; });
$list.mouseout(function() { paused = false; });
Then we just check that property before the rotation animation occurs:
if (paused) {
return;
}
http://jsfiddle.net/3eK4K/6/
I am attempting to create a responsive slider, that will change to a simple set of dot points when in mobile mode (< 940).
The issue I am facing is in my else statement I am unable to clearintervals that were made in the if statement, because t comes up as undefined. I have resorted to using
for (var i = 1; i < 99999; i++) window.clearInterval(i); to clear the interval which works, but I don't like it because it's ugly and cumbersome, is there another way of accomplishing this?
$(document).ready(function() {
function rePosition() {
//get responsive width
var container_width = $('.container').width();
//Slider for desktops only
if(container_width >= 940) {
//get variables
var slide_width = $('.slider_container').width();
var number_of_slides = $('.slider_container .slide').length;
var slider_width = slide_width*number_of_slides;
//set element dimensions
$('.slide').width(slide_width);
$('.slider').width(slider_width);
var n = 1;
var t = 0;
$('.slider_container').hover(function() {
clearInterval(t);
}, function() {
t = setInterval(sliderLoop,6000);
});
var marginSize = i = 1;
//Called in Doc Load
function sliderLoop(trans_speed) {
if (trans_speed) {
var trans_speed = trans_speed;
}
else
{
var trans_speed = 3000;
}
if (i < number_of_slides) {
marginSize = -(slide_width * i++);
}
else
{
marginSize = i = 1;
}
$('.slider').animate({ marginLeft: marginSize }, trans_speed);
}
t = setInterval(sliderLoop,6000);
$('.items li').hover(function() {
$('.slider').stop();
clearInterval(t);
var item_numb = $(this).index();
i = item_numb;
sliderLoop(500);
}, function() {
t = setInterval(sliderLoop,6000);
});
}
else
{
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
$('.slider').stop(true, true);
$('.slider').css('margin-left', '0px');
//rearrange content
if($('.slider .slide .slide_title').length < 1) {
$('.items ul li').each(function() {
var item_numb = $(this).index();
var content = $(this).text();
$('.slider .slide:eq(' + item_numb + ')').prepend('<div class="title slide_title">' + content + '</div>')
});
}
}
}
rePosition();
$(window).resize(function() {
rePosition();
});
});
Teemu's comment is correct. I'll expand on it. Make an array available to all of the relevant code (just remember that globals are bad).
$(document).ready(function() {
var myIntervalArray = [];
Now, whenever you create an interval you will need to reference later, do this:
var t = setInterval();//etc
myIntervalArray.push(t); //or just put the interval directly in.
Then to clear them, just loop the array and clear each interval.
for (var i=0; i<myIntervalArray.length; i++)
clearInterval(myIntervalArray[i]);
}
Umm, wouldn't t only be defined when the if part ran... as far as I can tell, this is going to run and be done... the scope will be destroyed. If you need to maintain the scope across calls, you'll need to move your var statements outside of reposition(), like so:
$(document).ready(function() {
var t = 0;
...
function rePosition() { ... }
});