js number +1 problem - javascript

I need click div.toggle1,control slideup, slidedown the div#text1,
click div.toggle7,control slideup, slidedown the div#text7.
here is my code, also in http://jsfiddle.net/qHY8K/ my number +1 not work, need a help. thanks.
html
<div class="toggle1">click</div>
<div id="text1">text1</div>
<div class="toggle7">click</div>
<div id="text7">text2</div>
js code
jQuery(document).ready(function() {
counter = 0;
for(i=1;i<11;i++){
(function(i){
counter = counter +1;
$('.toggle'+counter).toggle(function(){
$('#text'+counter).css('display','none');
},
function() {
$('#text'+counter).css('display','block');
});
})(i);
};
});

Lets simplify things a bit. One of the nice things about jQuery is that you can apply an event handler to many elements all at the same time. Start by adding a common classname to all of your 'toggle' divs:
HTML
<div class="toggle toggle1">click</div>
<div id="text1">text1</div>
<div class="toggle toggle7">click</div>
<div id="text7">text2</div>
Now you can use just one selector to target all of those divs. The rest is just a matter of pulling out the numeric difference in each 'toggle' div's classname:
JavaScript
jQuery(document).ready(function() {
$('.toggle').toggle(off, on);
function on() {
var i = this.className.match(/[0-9]+/)[0];
$('#text'+i).css('display','block');
}
function off() {
var i = this.className.match(/[0-9]+/)[0];
$('#text'+i).css('display','none');
}
});
I've updated your jsFiddle project. Hopefully this works out for you: http://jsfiddle.net/ninjascript/qHY8K/3/

Two solutions:
With your HTML as quoted, you can just do this:
jQuery(document).ready(function() {
$("div.toggle").click(function() {
$(this).next().toggle();
});
});
...since the div you're toggling is the next adjacent div. Note also that I'm using jQuery's toggle function to toggle the visibility.
But if it's possible that may change and you're defending against that, read on...
In your JavaScript code, you're already doing something that makes it possible to avoid the counter entirely, as knitti pointed out. But the way you're doing it creates functions unnecessarily and by using the same name (i) for both your loop counter and the argument to your anonymous function, you're making it very difficult to read and maintain that code.
So:
jQuery(document).ready(function() {
for(i=1;i<11;i++){
makeToggler(i);
}
function makeToggler(index){
$('.toggle'+index).click(function(){
$('#text'+index).toggle();
});
}
});
You can see how nice and clear that makes things, and in particular using a different name for the loop counter and the argument to makeToggler avoids confusion. And again, using jQuery's toggle function, no need for you to do it at the click level. (Also note that you don't put ; after the ending brace of a for statement.)

You don't need hard coded loop.
Preserve your current HTML and have such jQuery code instead:
$("div[class^='toggle']").each(function() {
var num = $(this).attr("class").replace("toggle", "");
$(this).toggle(function(){
$('#text' + num).css('display','none');
},
function() {
$('#text' + num).css('display','block');
});
});
This will iterate over all the <div> elements with class name starting with toggle and attach them the proper toggle function.
Updated jsFiddle: http://jsfiddle.net/qHY8K/5/

why do you introduce a new variable counter? (you should use var counter = 0; if you do).
in your function you could simply use your copied loop variable i:
for(i=1;i<11;i++){
(function(i){
$('.toggle'+i).toggle(function(){
$('#text'+i).css('display','none');
},
function() {
$('#text'+i).css('display','block');
});
})(i);
};

If your HTML has the structure as above, you could give all the toggleX elements the same class toggle and then all you have to do is:
$('.toggle').toggle(function(){
$(this).next().css('display','none');
},
function() {
$(this).next().css('display','block');
});
DEMO

Related

slideUp and slideDown animation does not work after first use

I have used jQuery to build something like a dropdown, but it only works for the first two clicks, and then it doesn't. How can I make a dropdown? Can it be done with a loop? (I have not learnt loop yet, so any solution would work.)
For Each SLIDEUP and SLIDEDOWN I wanted to make different TIME....
jQuery(document).ready(function() {
jQuery(".click-on").click(function() {
jQuery(".box").slideUp(2000, function() {
jQuery(".click-on").click(function() {
jQuery(".box").slideDown(500);
});
return false;
});
return false;
});
});
.box {
width: 300px;
height: 300px;
background-color: skyblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p id="fan">THIS IS A FAN</p>
<p id="gun">THIS IS A GUN</p>
<p class="click-on">Click Here</p>
<div class="box"></div>
Do you want to achieve something like that?
$(document).ready(function(){
$(".click-on").click(function(){
$('.box').slideToggle();
});
});
https://jsfiddle.net/jsrc9mbd/1/
The answer by #hetious is what I would have given - but having just seen the comment that slide-up and slide-down should have different times, you'll have to do this instead. Basically, check when you click whether the box is visible or not, and either slideUp or dlideDown accordingly:
jQuery(document).ready(function() {
jQuery(".click-on").click(function() {
var box = jQuery(".box");
if (box.is(":visible")) {
box.slideUp(2000);
}
else {
box.slideDown(500);
}
});
);
(Note that I have extracted a variable for jQuery(".box"), just to save some typing. And you can also use $ as an alias for jQuery to save yet more (the only reason this wouldn't work is if you are using another library which defines a global $ variable, which a few do.)
This is because you misunderstand the meaning of the .click() function.
.click() sets the handler function each time when the click event is triggered from the selected DOM.
Since you have called another .click() within the callback of .slideUp(), you are actually replacing the handler function. In your current logic, the obvious fix is to do infinite callback after each click like:
jQuery(".click-on").click(function(){
jQuery(".box").slideUp(2000, function(){
jQuery(".click-on").click(function(){
jQuery(".box").slideDown(500,function(){
jQuery(".click-on").click(function(){
jQuery(".box").slideUp(2000, function(){//Repeating callbacks... ...
});
});
});
});
and seriously it is very bad. Such implementation should not be done.
Instead, it is better for you to have a conditional checking for each click, so the logic will determine itself either .slideUp() or .slideDown() should be called. It should be like
$(".click-on").click(function(){//you can also use $ instead of jQuery
//do some conditional check here
if(isSlidedUp)$(".box").slideDown(1000);
else $(".box").slideUp(1000)
});
or even better you use .slideToogle().
$(".click-on").click(function(){
$(".box").slideToggle(1000)
}

Toggling one thing with two different elements

In my previous question I asked about how can I toggle a textarea with a paragraph. I got the answer. Now I want to do the opposite of it. First I was showing the already hidden textarea + 2 buttons by a click of a hyperlink. Now on the click of one of the buttons I want to hide the text + 2 buttons and show the paragraph that was first already shown.
I have tried this JS so far but it's not working:
$(document).ready(function () {
$(".no_link").click(function (e) {
e.preventDefault();
});
$(".edit_offer").on('click', function () {
toggleEditPanel($(this));
});
$("#cancel_edits").on('click', function () {
$(this).closest("button").hide();
$(this).closest("textarea").hide();
$(this).closest("p.content").show();
});
});
function toggleEditPanel(link) {
link.parent().parent().parent().find("textarea").toggle();
link.parent().parent().parent().find("button").toggle();
link.parent().parent().parent().find("p.content").toggle();
}
But its not working. How can I solve this error?
If I am trying to call the function toggleEditPanel() again. Its not working then aswell.
You can find the markup in the fiddle. Here's the fiddle.
UPDATE 1:
Just came up with a solution. I can use the $.siblings() function to toggle the elements beside the button. Still, is there any better solution?
Here's the code that I came up with:
$("#cancel_edits").on('click', function () {
$(this).hide();
$(this).siblings("button").hide();
$(this).siblings("textarea").hide();
$(this).siblings("p.content").show();
});
UPDATE 2:
The problem in the above code is that if there are more than one panels like this then the code is not working. How can I solve that issue aswell?
You are using Id for selector $("#cancel_edits") .
Id selectors returns only first element , so if there are multiple pannel it will work only for first.
Instead give some class name and use it for selector. Further you can use chaining and caching in your code for better performance.
$(".cancel_edits").on('click', function () {
var elm=$(this);
elm.add(elm.siblings("button,textarea")).hide();
elm.siblings("p.content").show();
});
I would recommend referencing your elements by ID:
$("#cancel_edits").on('click', function () {
$('#save_edits').hide();
$('#edited_content').hide();
$(this).hide();
$("p.content").show();
});
JSFiddle
The great thing about using IDs is that you are guaranteed they are unique - no need to use closest() to find the element you want. If, however, you're using classes instead, closest() might be necessary or helpful.

Toggle specific div based on click, hide all other divs of the same class

See my current code here: http://jsfiddle.net/swQLg/3/
I have some div's like
<div class="qtn">question1</div>
<div class="ans">answer1</div>
<div class="qtn">question2</div>
<div class="ans">answer2</div>
<div class="qtn">question3</div>
<div class="ans">answer3</div>
<div class="qtn">question4</div>
<div class="ans">answer4</div>
my jquery function is
$(document).ready(function () {
$(".qtn").on('click', function () {
$(this).next(".ans").slideToggle();
});
});
When I show one answer, I would like it to hide the other answers if they are showing.
Try this:
$(document).ready(function () {
$(".qtn").on('click', function () {
var $ans = $(this).next(".ans");
$ans.slideToggle(); //toggle the current one
$(".ans").not($ans).slideUp(); //hide the others
});
});
Fiddle
The reason I save $(this).next(".ans"); to a variable is for performance. If I didn't do this, every time that you call $(this).next(".ans");, jQuery would have to wrap this into a jquery object and then perform the next() function on that jquery object. In this case that would only be 1 extra time, but that still means 2 unnecessary operations.
Here is a jsperf test demonstrating the difference.
Put slideUp() in your click event to slide everything up. This will take care of closing/hiding already open divs and then put your code.
Demo
$(document).ready(function () {
$(".qtn").on('click', function () {
$(".ans").not($(this).next(".ans")).slideUp(); // slide the rest up
$(this).next(".ans").slideToggle();
});
});
Edited to fix what #smerny pointed out.

How to use jQuery after new objects are injected into DOM?

I am making a Sentence Generator. So far, it can take a list of words. Then it gets data from sentence.yourdictionary.com to take a sentence. I display the first sentence from sentence.yourdictionary.com using $("ul.example>li").first().Then it is put into a paragraph <p id="sents">.
So if you entered in the words yo and nose your output would be
<p id="sents"><li id="yo"><strong>Yo</strong> ' money
back a hund'd times, de preacher says!</li><li id="nose">I will no longer be caught with a
bleeding <strong>nose</strong>, heart palpatations, week long benders or hurting myself in any major way.</li></p>
I want a function to be called when you hover over the new list items.
$(document).ready( function() {
$("li").hover( function () {
$(this).append("<span>Testing</span>");
var id = $(this).attr("id");
console.log(id);
}, function () {
$(this).find("span:last").remove();
});
});
This doesnt work after the new list items are injected into the DOM. I tried adding an event listener for mousemove, but then when you hover over it the word "test" shows up a bunch of times! How can I make it happen after the new list items are injected?
Here is a jfiddle if you want some clarification: http://jsfiddle.net/varhawk5/cNKyx/1/
Thank you so much. Sorry I'm just learning javascript!
EDIT
To fix this issue, I used the .on() function as the comments suggested. There is no "hover" event though, so I think this is the only way.
$("body").on("mouseenter", "li#topWord", function() {
var word = $(this).data("word");
var sents = sentences[word]
$(this).html("<div class='restOfSents' data-word='" + word +"'></div>");
for(var i=1; i<sentences[word].length; i++) {
$(".restOfSents").append($(sentences[word][i]));
}
console.log(sents);
});
$("body").on("mouseleave", "li", function() {
// Remove the new div
});
$(document).ready( function() {
$(document).on('hover','li', function () {
$(this).append("<span>Testing</span>");
var id = $(this).attr("id");
console.log(id);
}, function () {
$(this).find("span:last").remove();
});
});
You're right! The reason for this, is that $(document).ready() only gets called on page load. You can either manually add a new event hook to each new element as you add it, or take advantage of jQuery's "on" functionality which will automatically detect new dom elements which match your criteria.
You should make use of .on() rather than .hover():
$('li').on('mouseenter', function() { ... })
Also you shouldn't use IDs for this. Make use of data-* attributes instead. Otherwise your code will break when a user enters the same word twice (as IDs are unique).
var id = $(this).attr('data-example');

jQuery mouse click counter

I need to color a table in zebra style, and then when I click on the table, twice (not double click), it should change back to original.
My question is, how to count 2 clicks?
Demo: http://jsfiddle.net/aztVY/
(function () {
var count = 0;
$('table').click(function () {
count += 1;
if (count == 2) {
// come code
}
});
})();
You can use jQuery's toggleClass function for that:
$(" ... ").click(function() {
$(this).toggleClass("someClass");
});
When clicked once, the element has the someClass class, and when clicked twice, the class is removed again.
I might be wrong, but in between the lines of your question I read that you actually ask about toggleClass() method documented here.
Add or remove one or more classes from each element in the set of
matched elements, depending on either the class's presence or the
value of the switch argument.

Categories

Resources