Jquery - Pseudo-recursive function with "this" element - javascript

I'm trying to apply a cool animation effect on a list with Jquery using a pseudo-recursive function.
It works pretty well for the first item, but after the first loop, the this which was selecting #column-left section becomes the li so of course, the function does not find the next li:hidden because it is already inside. Is there a way for me to come back to my original this once the "this" has changed or maybe do something different ?
$("#column-left section").mouseenter(function fadeItem(){
console.log(this);
$(this).find('ul li:hidden:first').delay(500).fadeIn(fadeItem);
});
Thank you very much for your help.

How about after the .fadeIn() trigger a mouseenter event on the parent section element:
$("#column-left section").mouseenter(function () {
$(this).find('ul li:hidden:first').delay(500).fadeIn(function () {
var $this = $(this);
//check to make sure there are more hidden `<li>` elements
if ($this.siblings('li:hidden').length > 0) {
//trigger a `mouseenter` event on the parent `section` element to continue the queue
$this.parents('section').trigger('mouseenter');
}
});
});
Here is a demo: http://jsfiddle.net/bhTnL/2/

You can use .end():
$(this)
.find('ul li:hidden:first')
.delay(500)
.fadeIn(fadeItem)
.end(); // returns to first selector
But you don't actually need to do this. To select the next hidden li, just do this:
$(this)
.find('ul li:hidden:first')
.delay(500)
.fadeIn(fadeItem)
.closest("li:hidden")
.delay(500)
.fadeIn(fadeItem);

Every function has access to the call method which allows you to pass in your this parameter. I rewrote your original solution using it here:
$("#column-left section").mouseenter(function fadeItem(){
$(this).find('ul li:hidden:first').delay(500).fadeIn.call(this, fadeItem);
});

Ok guys, I found an even better way:
$(this).find('ul li:hidden:first').delay(100).show("fast",function(){
$(this).next(':hidden').show("fast",arguments.callee);
});
Simply use next() (more info) to select the next li then call the function itselt using arguments.callee (more info)
Which gives the full following script below to show the list and hide it:
//show
$("#column-left section").mouseenter(function(){
$(this).find('ul li:hidden:first').delay(100).show("fast",function(){
$(this).next().show("fast",arguments.callee);
});
});
//hide
$("#column-left section").mouseleave(function(){
$(this).find('ul li:visible:last').delay(100).hide("fast",function(){
$(this).prev().hide("fast",arguments.callee);
});
});

Related

setTimeout in jQuery.each not working

I wanna imitate the menu item animation of this site
here's the key code I write to make the animation:
li{transition:transform 600ms}
li.animated{transform:translateY(20px)}
/* Javascript */
$('nav ul li').each(function(i){
setTimeout(function(){
$('ul li').addClass('animated');
},400*i)
})
But it doesn't work, in this fiddle, the 4 items are being translated together, not "timeoutted" at all; strangely, in my actual site, the codes seem to be more broken, the class wasn't added at all. I inspected the code of my site and fiddle again, but I couldn't find where the problem is.
You can use the second parameter from the .each method to determine the element. Like:
$('.inOrder').click(function(){
$('ul li').each(function(i, ele){
setTimeout(function(){
$(ele).addClass('animated');
},400*i);
})
})
https://jsfiddle.net/2pgf76vx/2/
You have to use this to target each elements individually,
$('ul li').each(function(i){
setTimeout(function(){
$(this).addClass('animated');
}.bind(this),400*i)
});
DEMO
Or you can use arrow function to fix this,
$('ul li').each(function(i){
setTimeout(()=>{
$(this).addClass('animated');
},400*i)
});

jQuery $each fadeIn fadeOut

Everything works fine except one thing, I'd like it so when you have the .show class already visible, it will fade again when you click on another of the #c- divs.
http://jsfiddle.net/7KdR6/1/
$('[id^="c-"]').each(function(i){
$this = $(this);
$(this).text(i);
$(this).on('click',function(){
$('.show').fadeIn().text(i);
event.stopPropagation();
});
})
$(document).on('click', function(){
$('.show').fadeOut();
});
One of your problems is that you are not stopping the propagation because event is not being defined. You'll have to use the parameter for the click handler. Edit: Actually, it looks like event is automatically passed - I did not realize this before now. However, I still think it best to put the event object as the parameter if you are going to use it - jQuery does this in their examples and it makes it more obvious.
I also notice you are caching this but then not using that cached var. This means that every time you write $(this), it will have to rewrap that jquery object.
Then you can have a fadeOut and use the fadeIn as a callback for the fadeOut. This way if the .show element is already shown, it will fadeOut first. I'd write it like this:
$('[id^="c-"]').each(function (i) {
$this = $(this);
$this.text(i);
$this.on('click', function (event) {
event.stopPropagation();
$show = $(".show");
$show.fadeOut(function () {
$show.fadeIn().text(i);
});
});
})
Fiddle
You need to hide the element before using fadeIn on a visible element
$('[id^="c-"]').each(function (i) {
var $this = $(this);
$this.text(i);
$this.on('click', function () {
$('.show').hide().fadeIn().text(i);
event.stopPropagation();
});
})
Demo: Fiddle
Try calling .hide() before calling .fadeIn().
DEMO FIDDLE

jQueryUI Resizable alsoResize can't be passed $(this).next()

When using jQueryUI .resizable() function, I'm trying to cause the next element in the DOM to also be resized. I can pass a jQuery selector, or even a string with a class or ID to the alsoResize method, but I can't pass $(this).next() to select the next element in DOM.
My code:
$(selector).resizable({ alsoResize:$(this).next() });
You can run the fiddle here, and uncomment the lines 67/68 to see this work/not work.
http://jsfiddle.net/WpgzZ/706/
It's because this is referring to the document (you can see this by doing console.log(this)). If you change it to alsoResizeReverse: $("#resizable").next() it should work for you.
Edit
You can do something like this:
$.each($("#colors li"), function(index, value) {
$(this).resizable({ alsoResize:$(this).next() })
});
It is because when the code is executed this is not pointed to the "#resizable" element
$("#resizable").resizable({
alsoResizeReverse: $("#resizable").next(),
// alsoResizeReverse: $(".myframe"),
});

Hiding button using jQuery

Can someone please tell me how I can hide this button after pressing it using jQuery?
<input type="button" name="Comanda" value="Comanda" id="Comanda" data-clicked="unclicked" />
Or this one:
<input type=submit name="Vizualizeaza" value="Vizualizeaza">
Try this:
$('input[name=Comanda]')
.click(
function ()
{
$(this).hide();
}
);
For doing everything else you can use something like this one:
$('input[name=Comanda]')
.click(
function ()
{
$(this).hide();
$(".ClassNameOfShouldBeHiddenElements").hide();
}
);
For hidding any other elements based on their IDs, use this one:
$('input[name=Comanda]')
.click(
function ()
{
$(this).hide();
$("#FirstElement").hide();
$("#SecondElement").hide();
$("#ThirdElement").hide();
}
);
You can use the .hide() function bound to a click handler:
$('#Comanda').click(function() {
$(this).hide();
});
jQuery offers the .hide() method for this purpose. Simply select the element of your choice and call this method afterward. For example:
$('#comanda').hide();
One can also determine how fast the transition runs by providing a duration parameter in miliseconds or string (possible values being 'fast', and 'slow'):
$('#comanda').hide('fast');
In case you want to do something just after the element hid, you must provide a callback as a parameter too:
$('#comanda').hide('fast', function() {
alert('It is hidden now!');
});
It depends on the jQuery selector that you use. Since id should be unique within the DOM, the first one would be simple:
$('#Comanda').hide();
The second one might require something more, depending on the other elements and how to uniquely identify it. If the name of that particular input is unique, then this would work:
$('input[name="Vizualizeaza"]').hide();

jQuery : How to remove class for all element on click?

I would like to know if some one can improve my code... Using jQuery I'm trying to apply a class on the element we just click and disable this class on the other elements.
You will se in my code that I'm trying to apply a class on the I just clicked and remove all the class on the others elements.
But for the moment, I'm doing it the "easy and mega long way" as you can see in $("choice1-1").click(function()
Can some help me with a code that could detect all the others ID ?
Here my code for the moment
$(document).ready(function()
{
$('#stick-question-1').mouseenter(function()
{
$('#stick-choices-1').show();
});
$('#stick-choices-1').mouseleave(function()
{
$('#stick-question-1').show();
$('#stick-choices-1').hide();
});
$("choice1-1").click(function()
{
$(this).addClass('hover-etat');
$("#choice1-2").removeClass('hover-etat');
$("#choice1-3").removeClass('hover-etat');
$("#choice1-4").removeClass('hover-etat');
});
});
And my HTML is like this
<div id="stick-choices-1" class="stick-choices">
Under 3'9
4' to 5'2
5'3 to 5'7
5'8 and more
</div>
Just use:
$("#stick-choices-1 a").click(
function(e) {
e.preventDefault();
$('.hover-etat').removeClass('hover-etat');
$(this).addClass('hover-etat');
});
I've changed your initial selector, so that the click event is triggered by clicking any of the links within the #stick-choices-1 div element, it prevents the default action of clicking the link (assuming that you want the default to be stopped), removes the hover-etat class from any element that has that class, and then applies that class-name to the this element.
It may, though, make sense to restrict the scope in which jQuery searches for elements with the hover-etat class, to those elements within the same #stick-choices-1 element, rather than the whole document:
$("#stick-choices-1 a").click(
function(e) {
e.preventDefault();
$('#stick-choices-1 .hover-etat').removeClass('hover-etat');
$(this).addClass('hover-etat');
});
Or:
$("#stick-choices-1 a").click(
function(e) {
e.preventDefault();
$(this).siblings('.hover-etat').removeClass('hover-etat');
$(this).addClass('hover-etat');
});
It will works fine :
$("#choice1-1").click(function(){
$(".stick-choices a").each(function(){
$(this).removeClass(".hover-etat");
});
$(this).addClass(".hover-etat");
});
This should do it, and registers this handler for all of the links.
$('#stick-choices-1 > a').click(function(ev) {
$(this).addClass('hover-etat').siblings().removeClass('hover-etat');
...
});
Note the use of .siblings() to ensure that only the links that are in the same group are affected, and without sending an unnecessary class change to the clicked link.
This click event will work for all of the choices:
$('.stick-choices a').click(function(e){
$(this).siblings('.hover-etat').removeClass('hover-etat');
$(this).addClass('hover-etat');
});
$("a", $("#stick-choices-1")).click(function(){
$(".hover-etat").removeClass('hover-etat');
$(this).addClass('hover-etat');
});
May be something like this?
$('div.stick-choices a').on('click', function(e) {
e.preventDefault();
$(this).addClass('hover-etat').siblings('a').removeClass('hover-etat');
});

Categories

Resources