I'm trying to make a webpage where a set of DIVs cycles from top to bottom (see fiddle). And then whenever you hover a certain part of the div (in this case, the STOP link), the animation stops then plays again on mouseout. What I'm lacking right now is a way to stop the animation whenever that STOP link has been clicked. I've added a stop function on the link but it won't work. There might have been a conflict or some sort with the hover function I've made.
Thanks in advance for the help and sorry for the noobish question.
Link to the fiddle: http://jsfiddle.net/Psp9R/
Jquery:
$(document).ready(function() {
$(".row").last().addClass("last");
$(".mholder").each(function() {
var i = 0;
$(this).find(".row").each(function() {
var $this = $(this);
$this.css("bottom", i);
i += $this.height();
});
});
// PLAY AND STOP
$('#start').click(function() {
$("#overlay").hide();
var countScrolls = $('.mholder .row').length;
for (var i=0; i < countScrolls; i++) {
doScroll($('.mholder .row:nth-child(' + i + ')'));
}
});
$('.stop').click(function() {
var countScrolls = $('.mholder .row').length;
$("#overlay").show();
for (var i=0; i < countScrolls; i++) {
$('.mholder .row:nth-child(' + i + ')').stop();
}
});
//PAUSE ON HOVER
$(".stop").hover(function () {
var countScrolls = $('.mholder .row').length;
for (var i=0; i < countScrolls; i++) {
$('.mholder .row:nth-child(' + i + ')').stop();
}
}, function () {
var countScrolls = $('.mholder .row').length;
for (var i=0; i < countScrolls; i++) {
doScroll($('.mholder .row:nth-child(' + i + ')'));
}
});
});
function doScroll($ele) {
var bottom = parseInt($ele.css("bottom"));
if (bottom < -60) { //bit arbitrary!
var $lastEle = $ele.closest('.mholder').find(".last");
$lastEle.removeClass("last");
$ele.addClass("last");
var bottom = (parseInt($lastEle.css("bottom")) + $lastEle.height());
$ele.css("bottom", bottom);
}
$ele.animate({
bottom: (parseInt(bottom) - 80)
}, 2200, 'linear', function() {
doScroll($(this))
});
}
You know what, when you click stop, it really stops but when you move your mouse out of stop button, browser understands that you fire mouseout event and it resumes its jogging . So you have to tell browser that you click on stop button and ignore mouseout event. I changed your code by adding a flag iStop to order browser stop. You can check it out at: jsFiddle
Implement a interval which is cleared when the stop link is clicked, then started again on mouseout.
setInterval - https://developer.mozilla.org/en/docs/DOM/window.setInterval
clearInterval - https://developer.mozilla.org/en-US/docs/DOM/window.clearInterval
Related
hello I am struggling to use JS in order to make the buttons on my HTML page add a border to the button when it is clicked and to remove the border when it is clicked again. it works for the first 2 clicks but then no longer does anything after that. please excuse my js im extremely inexperienced.
JavaScript:
<script>
var flag = true;
var buttons = document.getElementsByClassName("btn");
function buttonFunction() {
if (flag) {
for (var i = 0; i < buttons.length; i++) {
document.getElementsByClassName("btn")[i].addEventListener("click", function() {
this.classList.add("buttonSelect");
flag = false
return
});
}
} else {
if (flag == false) {
for (var i = 0; i < buttons.length; i++) {
document.getElementsByClassName("btn")[i].addEventListener("click", function() {
this.classList.add("buttonUnselect");
flag = true
return
});
}
}
}
}
</script>
The real issue is you're adding both classes and never removing them. Get rid of the if else statement and just toggle the class on click. Don't need to wrap the loop in a function either. Just let the javascript execute the event listeners at runtime.
Also, make use of the buttons var you created instead of trying to query the DOM again for the same elements.
<script>
var buttons = document.getElementsByClassName("btn");
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", function() {
this.classList.toggle("buttonSelect");
})
}
</script>
I currently have it so my titles slide in when the link is clicked.
How do I make it so that (when the link is clicked) the current title will slide out before the new one slides in?
This is the clicked event I have been using. It might be all wonky, I have been adding different things to it to try and get it to work.
// list of sections. the first section contains only the h1.
var sections = document.querySelectorAll("section");
function hideSections() {
for (var i = 0; i < sections.length; i++) {
sections[i].className = "hidden";
}
}
// list of links in the nav.
var links = document.querySelector("nav").querySelectorAll("a");
// add listeners to those links
for (var i = 0; i < links.length; i++) {
links[i].addEventListener("click", clicked);
}
function clicked(event) {
var target = document.querySelector('h2');
target.className = "slideout";
event.preventDefault();
hideSections();
var current = event.target.hash;
// "show" appropriate selection, based on id from link
document.querySelector(current).className = "";
// modify URL to reflect current location
location.hash = current;
target.addEventListener("animationend", newfile);
function newfile() {
target.removeEventListener("animationend", newfile);
}
target.addEventListener("animationstart", newfile);
}
// when page loads...
hideSections();
if (location.hash == "") {
sections[0].className = "";
} else {
document.querySelector(location.hash).className = "";
}
https://jsfiddle.net/yk7w2zt2/
Here is my full code.
You need you delay showing the next section until after the h2 has slid off the screen.
See JSFiddle using setTimeout():
https://jsfiddle.net/w9uypaae/
I'm trying to create a simple content slider that could handle dynamically added content to the slider. None of the "lightweight" plugins I found provided such functionality or, if it did, it didn't work correctly.
var $left = $('.left'),
$right = $('.right'),
$months = $('.sub ul');
$left.click(function(){
for(i = 0; i < 3; i++){
$months.find('li').first().before($.parseHTML('<li>xxx</li>'));
}
pos = $months.position();
$months.css('left', pos.left + 90);
});
$right.click(function(){
for(i = 0; i < 3; i++){
$months.find('li').last().after($.parseHTML('<li>xxx</li>'));
}
pos = $months.position();
$months.css('left', pos.left - 90);
});
This is the code I've got so far and here's a fiddle with an example - http://jsfiddle.net/kkr4zg0r/2/. It kind of works, but the problem is that since new content is added the navigation goes off (you can see what I mean by clicking left-right a couple of times).
I understand what's the problem for this - the newly added items "shift" the content and I need to do better calculations than substracting/adding 90px to the left position of the element but I can't figure out how to get the correct index of the elements and basically get this sliding by exactly (and correctly) by 3(or 6) elements at the time.
Currently the code is adding extra elements whenever a navigation button is pressed, if I could get the index of the currently visible first/last element, I could probably tell whether I need to add more elements and only add them then.
This is a basic illustration of what I'm trying to achieve
edit
I've changed the jsfiddle to the correct one.
The whole idea is to check when adding elements is necessary and when shift is enough:
Fiddle
$(document).ready(function()
{
var $main = $('.main'),
$left = $('.left'),
$right = $('.right'),
$months = $('.sub ul');
var addCount = 3;
var liWidth = 30;
var shiftX = addCount * liWidth;
$left.click(function()
{
var currentLeft = parseInt($months.css('left'));
var totalLength = $months.find('li').length * liWidth;
if (-currentLeft + $main.width() >= totalLength)
{
for (var i = 0; i < addCount; i++)
{
$months.find('li:last').after('<li>xxx</li>');
}
}
$months.css('left', currentLeft -= shiftX);
});
$right.click(function()
{
var currentLeft = parseInt($months.css('left'));
if (currentLeft < 0)
{
$months.css('left', currentLeft += shiftX);
}
else
{
for (var i = 0; i < addCount; i++)
{
$months.find('li:first').before('<li>xxx</li>');
}
}
});
});
I am trying to setup an element that will rotate 180 degrees when clicked and then back again when clicked again. The code I am using is as follows. Is obviously not right and feels like I need to use a for loop.
$('#hodgepodge').click(function(){
var i = 0;
if (i < 1) {
$('#hodgepodge').rotate(180);
var i = 1;
} else {
$('#hodgepodge').rotate(0);
var i = 0;
}
});
You can use jQuery's data() to keep track of the state, and then just toggle it :
$('#hodgepodge').on('click', function(){
$(this).rotate( !$(this).data('state') ? 180 : 0 );
$(this).data('state', !$(this).data('state'));
});
FIDDLE
Try to initialize before click event like
var i = 0;
$('#hodgepodge').click(function(){
if (i < 1) {
$('#hodgepodge').rotate(180);
i = 1;
} else {
$('#hodgepodge').rotate(0);
i = 0;
}
});
I have four buttons which has click able property. Clicking on button will make a div slide down and clicking again on same div should close the div. I want to add a condition like, when I have a div open, the click property on rest of the three buttons should be disabled, what I did is
for (var i = 1; i <= 4; i++) {
$(".slide" + i).click(function () {
var openTab = $(this).attr('class');
openTab = openTab.replace('slide', '');
var facetGroup = $(this).attr("key");
if ($('#panel').is(':visible')) {
buttonCloser(openTab);
} else {
buttonOpener(openTab, facetGroup);
}
});
}
function buttonCloser(m) {
for (var j = 1; j <= 4; j++) {
if (j != m) {
//alert(j);
$(".slide" + j).bind("click");
} else {
$(".slide" + j).css({
"background-color": " #fff5c3",
"color": "#000000"
});
}
}
$("#panel").slideUp("slow");
}
function buttonOpener(m, n) {
for (j = 1; j <= 4; j++) {
if (j != m) {
$(".slide" + j).unbind("click");
} else {
$(".slide" + j).css({
"background-color": "#293345",
"color": "#fff5c3"
});
}
}
$("#panel").slideDown("slow");
refreshFacet(n);
}
The problem with this code is that the first time I open a div by clicking on slider, the other three click events are disabled, bt when I close that div, it will nt re-enable its click property. so it wont open anything..
Without seeing your actual mark-up, I'd suggest that you use simple jQuery, rather than mixing and matching between 'plain' JavaScript and jQuery:
var buttons = $('button[class^="slide"]'),
panel = $('#panel');
$(buttons).click(
function() {
var that = $(this);
if (panel.is(':visible')) {
if (that.hasClass('opener')) {
panel.slideToggle();
that.removeClass('opener');
}
else {
return false;
}
}
else {
panel.slideToggle();
that.addClass('opener');
}
});
JS Fiddle demo.
References:
addClass().
attribute begins with selector attribute^="value" selector.
hasClass().
removeClass().
slideToggle().