JQuery fadeOut only works on first element [duplicate] - javascript

This question already has answers here:
jQuery click function only works on first element
(8 answers)
Closed 8 years ago.
I have a div containing other div elements which all contain an anchor tag that runs a javascrip function (uses AJAX to delete a row from a table). Example;
<div id="container">
<div><a id="btn" onclick="SomeFunction()">Delete</a></div>
<div><a id="btn" onclick="SomeFunction()">Delete</a></div>
<div><a id="btn" onclick="SomeFunction()">Delete</a></div>
... and so on
</div>
I then have this Jquery code;
$("#btn").click(function() {
$(this).parent("div").fadeOut();
});
that should fade out each of the elements on click to my knowledge, but it's only fading out the first element, if i click the next elements button's nothing happens.
I don't have extensive JQuery knowledge to understand why this is happening.

Ids must be unique, use classes instead.
Ids
[...] elements can only have one single ID defined through the id attribute. Note that an element may have several IDs, but the others should be set by another means, such as via a script interfacing with the DOM interface of the element.
classes
Classes allows CSS and Javascript to select and access specific elements via the class selectors or functions like the DOM method
Reference
Example
HTML:
<div id="container">
<div><a class="btn" onclick="SomeFunction()">Delete</a></div>
<div><a class="btn" onclick="SomeFunction()">Delete</a></div>
<div><a class="btn" onclick="SomeFunction()">Delete</a></div>
</div>
jQuery:
$(".btn").click(function() // Identify classes by a dot and the class attribute value.
{
$(this).parent("div").fadeOut();
});
Working Demo
Offtopic: I recommend taking a look at .on().

You can only have one element on a page with the same id. jQuery is getting confused. Use class or attribute selectors instead.

Related

How to edit text in a div thats in a div thats in another div with javascript [duplicate]

This question already has answers here:
How do I change the text of a span element using JavaScript?
(18 answers)
Closed 5 years ago.
I want to know what javascript code I can use to edit the text of this word?
This is not a duplicate because this has multiple divs in a div. And the target word is located in a div that is inside the more divs.
<div id="jump">
<div class="kick">
<div class="meet">
<div class="balls">
<div class="word">
Hello
</div>
</div>
</div>
It's the 1st element that has this class...
document.getElementsByClassName('word')[0].innerHTML='Goodbye';
It's the 5th element that has this tag...
document.getElementsByTagName('div')[4].innerHTML='Goodbye';
You can use next code:
document.querySelector('.word').textContent = 'Hello World!';
<div id="jump">
<div class="kick">
<div class="meet">
<div class="balls">
<div class="word">
Hello
</div>
</div>
</div>
But if you has few elements with class word, function 'querySelectror fining only first element'.If you need get many elements, you can use document.querySelectorAll --- is HTMLCollection (not array).
I don't recommend to use getElementByClassName - is very slowly method.
Method getElementsByTagName -faster that querySelectorAll , but it use only tagName. getElementById -is the fastest menthod finding of elements.
But that method find only first element with current ID.

Javascript / Greasemonkey / Userscript.js identify element and remove one of many classes

I've spent far too many hours trying to figure this out and as JavaScript is not my primary language and not yet a jQuery guru I've determined I need to ask for help.
In a case where a generated page has a structure where it has a DIV for some odd reason no ID, multiple non-standard data tag attribute tags, but at least standard style CLASS assignment....however...it has been assigned MULTIPLE classes.
Now, just one of those style classes is such that it has a code event associated that I want to neuter and leave all other classes still assigned. What I've tried there (this list is far from complete I have tried many things):
document.getElementsByClassName('Goodclass01')[0].remove('BADCLASS');
document.querySelectorAll('[data-tag-one="["value",
"value"]"]').remove('BADCLASS');
Various jnode calls that all fail due to claims of being unknown
A couple variations of something referred to as the "location hack" none of
which I could get to work but may have very well have been user error.
Safewindow attempt to just replace BADCLASS javascript function all together
but not ideal explained below.
Here is an example of the kind of structure of the target:
<div id="main">
<div class="main_content" data-tag-id="12345">Some stuff sits above</div>
<a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS"
data-tag-one="["value", "value"]">
</div>
In this example there is a javascript function that fires upon clicking the href link above due to the function being associated with BADCLASS style assignment. So, from lots of searching it seemed like I should be able to grab that DIV by any of the initially assigned classes (since there is unfortunately not a class ID which would make it very easy) but then reassign the list of classes back minus the BADCLASS at page load time. So, by the time the user clicks the link, the BADCLASS has been removed to look like this:
<div id="main">
<div class="main_content" data-tag-id="12345">Some stuff sits above</div>
<a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03"
data-tag-one="["value", "value"]">
</div>
I also read that simply using unsafewindow to replace the BADCLASS javascript function could be possible, so I am open to hearing one of you gurus help with how easy (or hard) that would be. In a case where BADCLASS could be shared function code perhaps called by another element on the page still having that initial class that perhaps we desire to continue to function which is why if it is only a single element that needs to be altered, I would rather just change this one href div.
Hope the explanation makes sense and what is probably a laughable simple example above for the Javascript gurus so forgive me but your help is greatly appreciated and will save more hair pulling! :)
EDIT: This must work above all in Chrome browser!
Remove the class from all elements
If you want to remove the class from all elements that have the class, simply select all of the elements with that class and remove the class from their class lists.
[...document.querySelectorAll('.BADCLASS')]
.forEach(e => e.classList.remove('BADCLASS'));
const elements = [...document.querySelectorAll('.BADCLASS')];
elements.forEach(e => e.classList.remove('BADCLASS'));
console.log(elements);
<div id="main">
<div class="main_content" data-tag-id="12345">Some stuff sits above</div>
<a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS"
data-tag-one='["value", "value"]'>link</a>
</div>
Using jQuery:
$('.BADCLASS').removeClass('BADCLASS');
const elements = $('.BADCLASS');
elements.removeClass('BADCLASS');
console.log(elements);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
<div class="main_content" data-tag-id="12345">Some stuff sits above</div>
<a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS"
data-tag-one='["value", "value"]'>link</a>
</div>
Remove the class from a subset of elements
If you only want to remove the class from a subset elements, select those elements then from the class from their class lists.
[...document.querySelectorAll('.Goodclass01, .Goodclass02, .Goodclass03')]
.forEach(e => e.classList.remove('BADCLASS'));
const elements = [...document.querySelectorAll('.Goodclass01, .Goodclass02, .Goodclass03')];
elements.forEach(e => e.classList.remove('BADCLASS'));
console.log(elements);
<div id="main">
<div class="main_content" data-tag-id="12345">Some stuff sits above</div>
<a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS"
data-tag-one='["value", "value"]'>link</a>
link
</div>
Using jQuery:
$('.Goodclass01, .Goodclass02, .Goodclass03').removeClass('BADCLASS');
const elements = $('.Goodclass01, .Goodclass02, .Goodclass03');
elements.removeClass('BADCLASS');
console.log(elements);
<div id="main">
<div class="main_content" data-tag-id="12345">Some stuff sits above</div>
<a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS"
data-tag-one='["value", "value"]'>link</a>
link
</div>
Run at document idle
The default for the run-at directive is document-idle, but if for some reason that has been changed, either it needs to be document-idle, or you need to otherwise delay execution of the script until the document has loaded.
You could use the run-at directive in the userscript header like so:
// #run-at document-idle
Or attach a load event listener to the window
window.addEventListener('load', function() { /* do stuff */ }, false);
Include jQuery
If you're using one of the jQuery solutions, you will have to include jQuery using the require userscript header directive like so:
// #require https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
Got it with the help of both of the clear, awesome correct answers below that literally came in within seconds of each other and only a few min after my post, so thanks to both #Tiny and #Damian below!
I'm upvoting both as they both listed the same correct jQuery answers, and Tiny also provided the pure JS.
I am posting the full answer below because without the other steps, with Tamper/Greasemonkey neither will produce the desired results.
First, Tamper/Greasemonkey do not load jQuery by default, so it is just easy as add #require http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.mi‌​n.js to your current script and also put this.$ = this.jQuery = jQuery.noConflict(true); to avoid any versioning conflicts.
Also, in this case unfortunately I HAD to change my TamperMonkey header to:
// #run-at document-idle
along with the above mentioned:
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
and begin the script with:
this.$ = this.jQuery = jQuery.noConflict(true);
and finally the primary accepted/best answer in this case of:
$('.Goodclass01').removeClass('BADCLASS');
NOTE: The above #run-at line is required, and since so many (all) of my current Tamper/Greasemonkey scripts are actually set by default to run at START, this is of importance as it means functions like this must be separated to their own scripts to run instead AFTER the page loads (idle). Once this is added, even the above pure JS answer from Tiny did in fact produce the desired result.
As the simplest one-line answer that I was hoping was possible in Javascript, as it is so many other languages in a single line of code. I've used it in the past, but was not aware of this particular removeClass method.
Your question mentions jQuery. Did you want a solution in jQuery?
If so, it's as easy as:
$(".Goodclass01").removeClass("badclass");
Explanation:
jQuery can be referenced as jQuery() or $(). The parameters you can pass are: 1, a Selector statement (like CSS), and 2, context (optional; default is document).
By stating $(".Goodclass01") you are stating, "Give me a jQuery object with all elements that have the class Goodclass01." Then, by using the removeClass() function, you can either pass it no parameters and it would remove all classes, or you can pass it specific classes to remove. In this case, we call .removeClass("badclass") in order to remove the undesired class.
Now, if you need to select only specific elements, such as links that have Goodclass01, you can do:
$("a.GoodClass01").removeClass("badclass");
Or, if you want to select anything that has Goodclass01, but NOT Goodclass02, you can do:
$(".Goodclass01:not(.Goodclass02)").removeClass("badclass");
jQuery is not as intimidating as it looks. Give it a shot!
Edit: I also noticed you were trying to capture a link with maybe a specific property. You can use the [property] syntax to select elements that have a specific property. Most typically, people use $("a[href^=https]") or something to that effect to select all a tags with the property href that begins with ^= the string https.
You could, in your case, use the following...
$("a[data-tag-one]")
... to select all links that have the property data-tag-one.
Note: One thing to keep in mind is that, a jQuery object is different than a pure DOM element. If you have a collection of multiple elements and want to use a pure JavaScript function on one element in particular, you would have to reference it with either [0] or .get(0). Once you do that, you will no longer be able to use jQuery methods until you convert it back to a jQuery object.
But, since jQuery has a whole slew of methods to use to make DOM manipulation easier, you can probably accomplish what you need to using those methods.
Edit: I've included a snippet below so you can see some of the jQuery selectors in action.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
div#main * { background-color: #66ff66; }
div#main .BADCLASS, div#main .BADCLASS * { background-color: #ff8888 !important; }
</style>
<div id="main">
<div class="main_content" data-tag-id="12345">Some stuff sits above</div>
<a href="SOME LINK" class="Goodclass01 Goodclass02 Goodclass03 BADCLASS"
data-tag-one='["value", "value"]'>All classes and data-tag-one</a><br />
<a href="SOME LINK" class="Goodclass01 BADCLASS" data-tag-one='["value", "value"]'>Goodclass01 and data-tag-one</a><br />
All classes, no data-tag-one<br />
<a href="SOME LINK" class="BADCLASS" data-tag-one='["value", "value"]'>Just BADCLASS and data-tag-one</a><br />
<br />
<table class="Goodclass01 BADCLASS"><tr><td>Here is a table</td></tr><tr><td>with Goodclass01 and BADCLASS</td></tr></table>
</div>
<hr>
<div id="buttons">
$(".Goodclass01").removeClass("BADCLASS");<br />
$("a.Goodclass01").removeClass("BADCLASS");<br />
$(".Goodclass01:not(.Goodclass02)").removeClass("BADCLASS");<br />
$("a[data-tag-one]").removeClass("BADCLASS");<br />
Reset the HTML<br />
</div>
<script>
$("#button1").click(function(){
$(".Goodclass01").removeClass("BADCLASS");
});
$("#button2").click(function(){
$("a.Goodclass01").removeClass("BADCLASS");
});
$("#button3").click(function(){
$(".Goodclass01:not(.Goodclass02)").removeClass("BADCLASS");
});
$("#button4").click(function(){
$("a[data-tag-one]").removeClass("BADCLASS");
});
$("#button5").click(function(){
var str = '<div class="main_content" data-tag-id="12345">Some stuff sits above</div>All classes, no data-tag-one<br /><a href="SOME LINK" class="BADCLASS" data-tag-one=\'["value", "value"]\'>Just BADCLASS and data-tag-one</a><br /><br /><table class="Goodclass01 BADCLASS"><tr><td>Here is a table</td></tr><tr><td>with Goodclass01 and BADCLASS</td></tr></table>';
$("div#main").html(str);
});
</script>

Jquery/javascript fade in each element?

By default image and text will fade in one after another once there are loaded, but is there a way to have a fading effect added on "each" element once there are loaded?
I can load the element using the code below:
$("#element,#element2,#element3,#element4").fadeIn("slow");
but the downsides are:
I have to specify all the elements in the page, #div1,#div3,#container2.....
Also the elements can only fade in once the page finish loading all together,but what I want is fade in the elements before all the html finishes loaded.
Is it possible?
I would give each element a specific class, then reference it with $(".whatever"). You also will probably check out $.each(), which iterates through objects. To fade in as the page loads, you would need to place the code, or call the function outside the document ready(), somewhere near the beginning of the html.
you should use class attribute for the elements. You can access and control all the elements which have a particular class, you need not specify the id of each and every element. Here is a demo JSFIDDLE for you :
HTML:
<input type="button" id="btn_fade_out" value="Fade Out">
<input type="button" id="btn_fade_in" value="Fade In">
<br>
<div class="my_class">Element 1</div>
<div class="my_class">Element 2</div>
<div class="my_class">Element 3</div>
<img src="abc.png" height="50px" width="50px" border="1" class="my_class"></img>
JS:
$('#btn_fade_out').click(function(){
$('.my_class').fadeOut(1000);
});
$('#btn_fade_in').click(function(){
$('.my_class').fadeIn(1000);
});
The best way to do this would be having a class in common for all the elements you want to fade on load
and then use
$('.class').fadeIn(1000);
$('.class').fadeOut(1000);

Use same div to toggle different parts of the page

Hello I have the following code:
Javascript/jQuery:
$(document).ready(function() {
$(".clickMe").click(function() {
$(".textBox").toggle();
});
});
Html code printed with a for loop:
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled</div>
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled 2</div>
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled 3</div>
I would like to be able:
When the page loads I want the to be hidden and toggle on click.
Using the same ids for <a class="clickMe"> and <div class="textBox"> to be able to toggle or hide the correct/equivalent <div> element.
jsFiddle code:
http://jsfiddle.net/A7Sm4/3/
Thanks
Edit 1: Class instead of Id
Edit 2: Fixed jsfiddle link
id are supposed to be unique
you should use class to do this
[EDIT] updated the jsfiddle to fit Marko Dumic's solution: http://jsfiddle.net/SugvH/
Something like this should do the trick:
$(document).ready(function() {
var divs = [];
$(".textBox").each(function(index) {
divs[index] = this;
});
$(".clickMe").each(function(index) {
$(this).click(function() {
$(divs[index]).toggle();
});
});
});
ID must (as per spec) be unique on the page. You can easily rewrite this to use class attribute:
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled</div>
<a class="clickMe">Toggle my text</a>
<br />
<div class="textBox"> - This text will be toggled 2</div>
...
Initially, you need to either hide div.textBox when DOM becomes ready, or hide it using CSS.
Then you attach click handlers to a.clickMe:
$(function () {
$('a.clickMe').click(function () {
// find first of following DIV siblings
// with class "textBox" and toggle it
$(this).nextAll('div.textBox:first').toggle();
});
});
However, maybe you don't control the markup but desperately need this done, you can keep your markup as it is and still make it work due to the fact that jQuery uses Sizzle framework to query the DOM which can be forced around the limitation of document.getElementById() (which returns only one element).
E.g. suppose you used id instead of class, if you write $('#clickMe'), you'll get the jQuery collection of only one element (jQuery internally used .getElementById() to find the element), but if you write $('#clickMe'), you get the collection of all elements with the id set to "clickMe". This is because jQuery used document.getElementsByTagName('a') to find all anchors and then filtered-out the elements (by iterating and testing every element) whose attribute value is not "clickMe".
In that case (you used your original markup), this code will work:
$(function () {
$('a#clickMe').click(function () {
$(this).nextAll('div#textBox:first').toggle();
});
});
Again, don't do this unless you absolutely need to!
$(document).ready(function() {
$("a").click(function() {
$(this).parent().find("div").toggle();
});
});
Use something similar to this.
Try appending an index to each pair of a/div's ids (clickme1 and textbox1, etc). Then when an a is clicked, read the id, take the index off the end, and show/hide the textbox with the same index.

CSS Multiple ID with Same Name Work Around?

First I realize ID's should be unique. But right now I can't do much about that. I have a javascript plug-in that is generating ID names and for one page it works great. The issue is in creating another page, it will start over using the same naming convention. For example:
Page 1
<ul id="1">
Page 2
<ul id="1">
So if I am trying to style ul#1 on Page 1 it will also style ul#1 on Page 2. So, any suggestions on how to separate our the two id's? This html is generated by the JS, otherwise I would just attach a class to it.
Thanks.
First, the unique ID suggestion is restricted to a page. It is perfectly fine to have multiple ID's on different pages. The best way to overcome this is to add a ID to the body.
Page1
<body id="Page1">
<ul id="1">
<li></li>
</ul>
</body>
Page2
<body id="Page2">
<ul id="1">
<li></li>
</ul>
</body>
CSS
#Page1 #1
{
//Some style for page 1, ID 1
}
#Page2 #1
{
//Some style for page 2, ID 1
}
Can you attach a class around it ? Have a div or span some other element surround your code that does the generation and assign a class to it.
I'd say you have to use different style sheets on each page if you need different styles for the same ids, but this will be a pain to maintain as you make styling changes.
Alternatively you could you assign a class to one of the page's UL tags and then create a style for that class.
First of all, the plugin is still not generating the correct ids because ids can't be numbers. To answer your question, try to figure out some parent element that might be different between the two pages probably in which case you can use CSS such as this:
#parent ul#1{
/* styles here */
}
#parent2 ul#1{
/* styles here */
}
page1:
<div id="parent">
<ul id="1">
............
page2:
<div id="parent2">
<ul id="1">
............
So you need to find out a some parent element of ul which is not common between the two pages. This is the only possibility that comes to my mind where you have no control over changing the ids or replacing them with classes since they are being generated by the plugin.
You need something to distinguish them if you want them styled separately. If you cannot modify those tag you could probably use some parent container like:
<div id="parent1">
<ul id="id1" />
</div>
<div id="parent2">
<ul id="id1" />
</div>
and then:
#parent1 ul {
...
}
#parent2 ul {
...
}
Also notice that an id cannot start with a number as in your case. You should probably consider switching/modifying this plugin.
One thing I commonly do is attach a class to the body for each page. <body class="home_section"> and then you could style based on that class .home_section ul#1 {}.
Also, IDs must begin with a letter.

Categories

Resources