jQuery - Variable selectors in ForEach loop - javascript

I've written a forEach loop which goes through an array of divs (by ID), selects child elements with a certain class and removes another class from them. I'm having a few issues turning the variable back into a selector and joining it to the other ones. As a result, my forEach loop doesn't work.
http://jsfiddle.net/NWmB5/7/ (Try clicking one of the links, the third item should turn black again if the code works)
var toDoCategories;
$(document).ready(function() {
toDoCategories = [$("#testDiv"),$("#anotherDiv"),$("thirdDiv")];
setTimelinePosition($('#thirdDiv'));
$('#targetFirstDiv').click(function() {
setTimelinePosition($('#anotherDiv'));
});
$('#targetSecondDiv').click(function() {
setTimelinePosition($('#testDiv'));
});
});
/* Show current position on timeline */
function setTimelinePosition($position) {
var $theTimelineTrigger = $('span.timelineTrigger');
toDoCategories.forEach(function(currentCategory) {
var $deselectTimelinePositionElement = $(currentCategory, $theTimelineTrigger);
$($deselectTimelinePositionElement).removeClass('currentPosition');
});

It should be as simple as
$(document).ready(function () {
var $toDoCategories = $("#testDiv, #anotherDiv, #thirdDiv"); //NOTE HERE
setTimelinePosition('#thirdDiv');
$('#targetFirstDiv').click(function () {
setTimelinePosition('#anotherDiv');
});
$('#targetSecondDiv').click(function () {
setTimelinePosition('#testDiv');
});
/* Show current position on timeline */
function setTimelinePosition(position) {
$toDoCategories.find('.currentPosition').removeClass('currentPosition')
$(position).find('.timelineTrigger').addClass('currentPosition');
}
});
Demo: Fiddle
Another approach: Fiddle

Related

jQuery hiding child element opens its child

Im using a table and rows can have child rows and it can go down a few levels,
what is happening now is that when hiding a child element it then opens that childs child element.
Heres my jQuery:
$(document).ready(function() {
function getChildren($row) {
var children = [], level = $row.attr('data-level');
while($row.next().attr('data-level') > level) {
children.push($row.next());
$row = $row.next();
}
return children;
}
$('.parent').on('click', function() {
var children = getChildren($(this));
$.each(children, function() {
$(this).toggle();
})
});
$(".parent a").click(function(e) {
e.stopPropagation();
})
})
I have set up a jsfiddle so you can see whats happening
https://jsfiddle.net/rhvye8k0/4/
If you click the first "+" you will see what im trying to describe.
Cant think how to sort it out
Update,
have sorted it and updated jsfiddle https://jsfiddle.net/rhvye8k0/5/
There may be a way to reduce the jQuery but it works for now
Your problem is the $(this).toggle(); in .parent's onclick handler. The tr at level 3 has style="display:none", the others don't. toggle() will toggle the receiving element(s) visibility so the others are show (their display is implicitly block) and level 3's is hidden.

Jquery hover event stuck on clone elements

I am creating an plugin with wordpress for the portfolio items. Everything works fine . But the issue is when i apply the filter the hover effect stopped working on the cloned items
also available JS FIDDLE
the jquery code is given below i tried
/* Scroll to Top Button */
jQuery(document).ready(function() {
// Animate Box Shadow on some elements
// Add the overlay. We don't need it in HTML so we create it here
// Clone portfolio items to get a second collection for Quicksand plugin
var $portfolioClone = jQuery(".rudra-portfolio").clone(true);
// Attempt to call Quicksand on every click event handler
jQuery(".rudra-portfolio-filter a").click(function(e) {
jQuery(".rudra-portfolio-filter li").removeClass("current");
// Get the class attribute value of the clicked link
var $filterClass = jQuery(this).parent().attr("class");
if ($filterClass == "all") {
var $filteredPortfolio = $portfolioClone.find("li");
} else {
var $filteredPortfolio = $portfolioClone.find("li[data-type~=" + $filterClass + "]");
}
// Call quicksand
jQuery("ul.rudra-portfolio").quicksand($filteredPortfolio, {
duration: 500,
easing: 'easeInOutQuad'
});
jQuery(this).parent().addClass("current");
// Prevent the browser jump to the link anchor
e.preventDefault();
})
jQuery(".port-li").click(function() {
jQuery(this).find('.content-wrapper').slideDown();
});
jQuery(".overeffect").mouseover(function() {
jQuery(this).find('.content-wrapper').slideDown();
});
jQuery("#portfolio-grid li").mouseleave(function() {
jQuery('.content-wrapper').slideUp(500);
});
});
hour effect is working fine for first and second time , but after that it stopped working .
Update
I also tried this Jquery clone
solved by me ..
i just need to use this
jQuery(document).on('hover',".overeffect",function(){
jQuery(this).find('.content-wrapper').slideDown();
});

jQuery Accordion | Open first element on pageload & active state confusion

I am using the Javascript below to animate an accordion (it's a slightly modified variant of the one explained here: http://tympanus.net/codrops/2010/04/26/elegant-accordion-with-jquery-and-css3/.
Now I wanted to have the first element to be open on pageload, so I figured I just give it some sort of extra-class via Javascript (and define that .active state via CSS) to have it open up.
This worked, however if I hover over any but the first-element with said .active class, the first element keeps its state, and stays open until I hover over it at least once.
So, what I want is: the first element of my accordion is open and collapses if the user hovers over any of the elements that are not the first. I think I need to add a line in the hover function to either take the class away of the first element or to give the new element the active state, but I don't know how to do it and keep breaking the thing.
<script type="text/javascript">
jQuery(function() {
activeItem = jQuery("#accordion li:first");
jQuery(activeItem).addClass('active');
jQuery('#accordion > li, #accordion > li.heading').hover(
function () {
var jQuerythis = jQuery(this);
jQuerythis.stop().animate({'height':'280px'},500);
jQuery('.heading',jQuerythis).stop(true,true).fadeOut();
jQuery('.bgDescription',jQuerythis).stop(true,true).slideDown(500);
jQuery('.description',jQuerythis).stop(true,true).fadeIn();
},
function () {
var jQuerythis = jQuery(this);
jQuerythis.stop().animate({'height':'40px'},1000);
jQuery('.heading',jQuerythis).stop(true,true).fadeIn();
jQuery('.description',jQuerythis).stop(true,true).fadeOut(500);
jQuery('.bgDescription',jQuerythis).stop(true,true).slideUp(700);
}
);
});
</script>
Looks like this is happening because each accordion item has its own hover event that takes care of its own animation. You can refactor the code slightly to make this easier to understand and reuse:
var activeItem = jQuery("#accordion li:first");
jQuery('#accordion > li, #accordion > li.heading').hover(
function () { hoverMe(jQuery(this)); },
function () { unhoverMe(jQuery(this)); }
);
//This gets called when cursor hovers over any accordion item
var hoverMe = function(jQuerythis) {
//If the first item is still active
if (activeItem) {
contract(activeItem); //...Shrink it!
activeItem = false;
}
//Expand the accordion item
expand(jQuerythis);
};
//This gets called when cursor moves out of accordion item
var unhoverMe = function(jQuerythis) {
contract(jQuerythis);
};
//I have moved the hover animation out into a separate function, so we can call it on page load
var expand = function(jQuerythis) {
jQuerythis.stop().animate({'height':'280px'},500);
jQuery('.heading',jQuerythis).stop(true,true).fadeOut();
jQuery('.bgDescription',jQuerythis).stop(true,true).slideDown(500);
jQuery('.description',jQuerythis).stop(true,true).fadeIn();
};
//I have moved the unhover animation out into a separate function, so we can contract the first active item from hoverMe()
var contract = function() {
jQuerythis.stop().animate({'height':'40px'},1000);
jQuery('.heading',jQuerythis).stop(true,true).fadeIn();
jQuery('.description',jQuerythis).stop(true,true).fadeOut(500);
jQuery('.bgDescription',jQuerythis).stop(true,true).slideUp(700);
};
//Now expand the first item
expand(activeItem);
I have put together a simplified version demonstrating the logic. Please let me know how you get on.

How to animate an element while using .before in jquery

I want to append .item element before .content element but it just simply removes .item from previous location and append before .content.
What i want is to use some animation that slowly remove .item element from its original position and appear slowly on its new position.. how can i do this?
$Item = $('.item');
$('.content').before($Item);
Regards.
How about something like this:
$Item = $('.item');
$Item.fadeOut(1000, function() {
$('.content').before($Item);
$Item.fadeIn(1000);
}
The .fadeOut() method fades the element over the specified time (in milliseconds), and on completion calls the function which then moves the element and fades it back in.
Demo: http://jsfiddle.net/9gGAT/5/
You can also use the hide and show -methods of jquery to achieve a sliding effect. I'd also package the transition within it's own method so it can be reused, so you don't have to write the same code multiple times.
var smoothLikeSilk = function(mover, before) {
$item = $(mover);
$content = $(before);
$item.hide('slow', function() {
$content.before($item);
$item.show('slow');
});
}
$(function(){
$('#btnMove').on('click',function(){
smoothLikeSilk('.item', '.content');
});
});
http://jsfiddle.net/9gGAT/6/
Do you mean something like this:
jsFiddl Link
Try this,
$(function() {
$('#btnMove').on('click', function() {
$Item = $('.item').fadeOut('slow', function() {
$('.content').before($Item);
$Item.fadeIn('slow');
})
});
});​
Demo

javascript set element background color

i have a little javascript function that does something when one clicks on the element having onclick that function.
my problem is:
i want that, into this function, to set a font color fot the html element having this function onclick. but i don't suceed. my code:
<script type="text/javascript">
function selecteazaElement(id,stock){
document.addtobasket.idOfSelectedItem.value=id;
var number23=document.addtobasket.number;
number23.options.length=0;
if (stock>=6) stock=6;
for (i=1;i<=stock;i++){
//alert ('id: '+id+'; stock: '+stock);
number23.options[number23.options.length]=new Option(i, i);
}
}
</script>
and how i use it:
<li id = "product_types">
<a href="#" onclick='selecteazaElement(<?= $type->id; ?>,<?= $type->stock_2; ?>);'><?= $type->label; ?></a>
</li>
any suggestions? thanks!
i have added another function (jquery one) that does partially what i need. the new problem is: i want that background color to be set only on the last clicked item, not on all items that i click. code above:
$(document).ready(function() {
$('.product_types > li').click(function() {
$(this)
.css('background-color','#EE178C')
.siblings()
.css('background-color','#ffffff');
});
});
any ideas why?
thanks!
I would suggest
$(document).ready(function() {
$('.product_types > li').click(function() {
$('.product_types > li').css('background-color','#FFFFFF');
$(this).css('background-color','#EE178C');
});
});
Your element could have this code:
<li id = "product_types" onclick="selecteazaElement(this);" <...> </li>
To change the foreground color of that element:
function selecteazaElement(element)
{
element.style.foregroundColor="#SOMECOLOR";
}
If you want to change the background color on only the last element clicked, each element must have a different id. I'd suggest naming each one something like product_types1, product_types2, ..., product_typesN, and so on. Then have a reset function:
function Reset()
{
for (var i = 1; i <= N; i = i + 1)
{
document.getElementById('product_types'+i).style.backgroundColor="#RESETCOLOR";
}
}
When you call your selecteazaElement(this) function, first call the Reset function, then set the new element:
function selecteazaElement(element)
{
Reset();
element.style.backgroundColor="#SOMECOLOR";
}
This way all of the elements that start with product_types followed by a number will be reset to one particular color, and only the element clicked on will have the background changed.
The 'scope' of the function when invoked is the element clicked, so you should be able to just do:
function selecteazaElement(id,stock){
document.addtobasket.idOfSelectedItem.value=id;
var number23 = document.addtobasket.number;
number23.options.length=0;
if (stock>=6){
stock=6;
}
for (var i=1;i<=stock;i++){
//alert ('id: '+id+'; stock: '+stock);
number23.options[number23.options.length]=new Option(i, i);
}
// Alter 'this', which is the clicked element in this case
this.style.backgroundColor = '#000';
}
$(function() {
/*if product_types is a class of element ul the code below
will work otherwise use $('li.product_types') if it's a
class of li elements */
$('.product_types li').click(function() {
//remove this class that causes background change from any other sibling
$('.altBackground').removeClass('altBackground');
//add this class to the clicked element to change background, color etc...
$(this).addClass('altBackground');
});
});
Have your css something like this:
<style type='text/css'>
.altBackground {
background-color:#EE178C;
/* color: your color ;
foo: bar */
}
</style>
Attach a jQuery click event to '#product_types a' that removes a class from the parent of all elements that match that selector; then, add the class that contains the styles you want back to the parent of the element that was just clicked. It's a little heavy handed and can be made more efficient but it works.
I've made an example in jsFiddle: http://jsfiddle.net/jszpila/f6FDF/
try this instead:
//ON PAGE LOAD
$(document).ready(function() {
//SELECT ALL OF THE LIST ITEMS
$('.product_types > li').each(function () {
//FOR EACH OF THE LIST ITEMS BIND A CLICK EVENT
$(this).click(function() {
//GRAB THE CURRENT LIST ITEM, CHANGE IT BG, RESET THE REST
$(this)
.css('background-color','#EE178C')
.siblings()
.css('background-color','transparent');
});
});
});
If I am correct, the problem is that the click event is being binded to all of the list items (li). when one list item is clicked the event is fired on all of the list items.
I added a simple .each() to your code. It will loop through each of the list items and bind a event to each separately.
Cheers,
-Robert Hurst

Categories

Resources