after removing element from dom the length property doen't reflect that - javascript

I have this html created on the fly with javascript:
<div class="panel panel-default theaterPlayer">
<div class="panel-body panelbody69875341">
<div class="paneltop paneltop69875341">
<span class="glyphicon glyphicon-remove close closePlayer"></span>
</div>
<iframe width="560px" height="340px" id="id69875341"
src="" style="margin- top: 50px;"></iframe>
</div>
</div>
Then when i hit the closePlayer button in Jquery:
$('body').on('click', '.closePlayer', function(event) {
$(this).parent('div').parent('div').parent('.theaterPlayer').remove();
});
Then when i want to now the length off the element with class theaterPlayer so i know how much off those elements exist:
$('.theaterPlayer').length;
shows the ones removed + 1
How can i remove from the dom AND remove from that other collection that seams to exist?

May be the number of div changes at runtime. try removing it like:
$('body').on('click', '.closePlayer', function(event) {
$(this).closest('.theaterPlayer').remove();
});

Using this
$(".closePlayer").closest('div').parent('div').remove();
console.log($('.theaterPlayer').length);
Now you are able to remove all the inner divs, which contains in the outer div which has class panel panel-default theaterPlayer. So here i am assuming that on fly you are appending html to the div which contains class theaterPlayer:
Hence,
$('.closePlayer').on('click',function() {
$(this).closest('div').parent('div').remove(); // Here removes all inner Divs
console.log($('.theaterPlayer').length); // Length will be 1, and Outer Div remains there.
});
Or if u want remove all the div including outer div on Clicking of Close button, then use simply
$(this).closest('div.theaterPlayer').remove(); //Removes all given(html) Div's and show length as 0;
Hope this will help you.

I should be realy very ashamed of myself!!! Appendeing it to .container wasn't a smart thing to do because i'd forgotten i use another element with the same class that was'nt visible so i didn't noticed it. I'm very sorry for wasting all you time!

Related

each loop should only run once when button is clicked

I want to hide a div when a button is clicked and then show the next div with the same class. I have tried using this code, but when I do this, the next div that I want shown also fades out.
$('.arrow:last-of-type').on('click', function(){
$( ".collaboration" ).each(function( index ) {
if($('.collaboration').css('display') == 'block'){
$(this).fadeOut()
$(this).next().fadeIn()
}
})
})
Is there a way to stop the each() from running when it is executed once and then run again when the click action happens?
Here's the HTML:
<div id="collaborations">
<p class="arrow"><</p>
<div class="collaboration">
<img src="./img/test.png" />
<p>Text</p>
<button>Visit</button>
</div>
<div class="collaboration">
<img src="./img/test.png" />
<p>Text</p>
<button>Visit</button>
</div>
<div class="collaboration">
<img src="./img/test.png" />
<p>Text</p>
<button>Visit</button>
</div>
<p class="arrow">></p>
</div>
</div>
Thanks
Solution
You could solve this by not iterating through the .collaborations at all.
The key thing is that you need to keep track of which one is currently being shown.
If you know that, then what your click handler can do is show the next one and hide the current one.
I would suggest doing that with a class .active on the same div as .collaboration. You can then select the next div by $('.active').next().addClass('.active'), and deselect by $('.active').removeClass('.active').
You might need to store a reference to your first element before you select the next one 👍
Example
Here's a quick example of how this might work: https://codepen.io/juancaicedo/pen/LYGgPWa
I moved around the html to group all the collaborations into a div by themselves.
Other approaches
You'll find that you have to think through some other behaviors with the solution above. For example, in my example, there is a moment when two items are on the screen, causing their container div to grow and later shrink.
For these reasons, I don't like handling presentation from within javascript (i.e. using jquery's fadeIn/fadeOut).
If you can find a way to instead using only css, I think that's preferable. Here's an example using css transitions
https://codepen.io/juancaicedo/pen/ZEQqzrR
The each method of jQuery can be stopped whenever you want by returning false inside of the callback, so you can probably fix your code by doing this:
$('.arrow:last-of-type').on('click', function(){
$( ".collaboration" ).each(function( index ) {
if($('.collaboration').css('display') == 'block'){
$(this).fadeOut()
$(this).next().fadeIn()
return false;
}
});
});

Adding and removing classes not working

I've used this exact code on a different div element and it works perfectly. When I went to add the same code to another div element with a different id it registers the element has been clicked but it doesn't add or remove any of the classes.
$('#quoteClick').click(function(){
$('#cbox-1').addClass('displayCboxBackground');
$('#cbox-2').removeClass('displayCboxBackground');
$('#cbox-3').removeClass('displayCboxBackground');
$('#dbox-1').addClass('displayBlock');
$('#dbox-2').removeClass('displayBlock');
$('#dbox-3').removeClass('displayBlock');
console.log("clicked");
});
The html structure is as follows:
<div id="cbox-1">
<div id="dbox-1">
content...
</div>
</div>
<div id="cbox-2">
<div id="dbox-2">
content...
</div>
</div>
<div id="cbox-3">
<div id="dbox-3">
<div id="quoteClick">
a quote
</div>
</div>
</div>
JSFiddle: https://jsfiddle.net/m81c23cx/1/
In the fiddle you can see the content will changes when each header is clicked. When the "quoteClick" element is clicked I want it to change to the second headers content exactly how it does when the second header is clicked.
I can see in Chrome's console that when I click the div element that it highlights all the classes but it doesn't change any of them. I have the jQuery inside a document.ready() function so it should be waiting for the DOM to load and it works perfectly when I just write the lines into the console.
I'm surprised that nobody actually questioned your use of ids (instead of suggesting that you should double-check for dupes). The reason why this code is hard to debug is because it's too complicated. As a result, you'll have a hard time fixing issues similar to this in the future too.
Drop it, do it better.
I didn't even go through your fiddle. Instead, I'm going to propose that you change your approach altogether.
Update your HTML and use classes instead of ids. Something similar to this:
<div class="cbox">
<div class="dbox">
content...
</div>
</div>
<div class="cbox">
<div class="dbox">
content...
</div>
</div>
<div class="cbox">
<div class="dbox">
<div id="quoteAdvert">
a quote
</div>
</div>
</div>
Update your JavaScript and use this to get the context of the current box:
$('.cbox').click( function cboxClicked () {
// Remove the previous class from all .cbox & .dbox elements; we don't care which
$('.cbox').removeClass('displayCboxBackground')
$('.dbox').removeClass('displayBlock')
// Add a new class to the clicked .cbox & it's child .dbox
$(this).addClass('displayCboxBackground')
$(this).children('.dbox').addClass('displayBlock')
})
The beauty of this? You can have 1000 boxes, it'll still work. No need to add any extra lines of code.
Here's a fiddle showing it in action.
The example code you provided is not consistent with the jsfiddle you created.
In your fiddle, you use the jquery selector $('#quoteClick') but there is no element with that id. There is a #quoteAdvert element however. Change that and you'll see the click in the console.
The classList property returns a token list of the class attribute of the element in question. Luckily for us, it also comes with a few handy methods:
add - adds a class
remove - removes a class
toggle - toggles a class
contains - checks if a class exists
// adds class "foo" to el
el.classList.add("foo");
// removes class "bar" from el
el.classList.remove("bar");
// toggles the class "foo"
el.classList.toggle("foo");
// outputs "true" to console if el contains "foo", "false" if not
console.log( el.classList.contains("foo") );
// add multiple classes to el
el.classList.add( "foo", "bar" );

jQuery code is hiding all content inside my div

I have the following code:
jQuery(document).ready(function($) {
$("ul.accordion-section-content li[id*='layers-builder'] button.add-new-widget").click(function() {
$("#available-widgets-list div:not([id*='layers-widget'])").css('display','none');
});
});
The idea is, when i click a button that contains the class "layers-builder", all divs in "available-widgets-list" that DO NOT contain the class "layers-widget" are hidden.
The problem I'm facing is that using this code also hides all the divs inside "layers-widget" (as not all of them have "layers-widget" in the id.
for example, here is a mockup markup:
<div id="some-id">
...
</div>
<div id="this-layers-widget-89">
<div id="hello"></div>
<div id="yes"></div>
</div>
In the above example, the first div "some-id" would be hidden, along with all the child divs inside "this-layers-widget-89"
How can I make it so that all the content within the div containing "layers-widget" still shows?
The ">" operator specifies that the div must be a direct child of #available-widgets-list:
$("#available-widgets-list > div:not([id*='layers-widget'])").css('display','none');
You should add a class instead of relying on finding parts of some-id but this will work also work: $('[id*="some-id"]');
You should also be using jquery's built in hide()method instead of css('display', 'none'). They do literally the exact same thing but using the built in methods is more readable.

Javascript to change entire div on click

i have a website in which products are listed.There are around 30 products.Now there are links to go to details of each product.I want to put them all on one page and through javascript,change the content of a particular div on click.
What i know is that i can create 30 functions to change the display of 1 div to none..and displaying the other one....
how to achieve this..I am doing something like this
function changeImg2()
{
$('#change_content').stop(true, true).fadeOut({ duration: slideDuration, queue: false }).css('display', 'none');
$('#change_content2').stop(true, true).fadeIn({ duration: slideDuration, queue: false });
}
here is the type of div's that i have
<div id="change_content1">
<div class="viewport">
<a id="btn" href="http://www.flickr.com/photos/matt_bango/3479048548/">
<span class="dark-background">Northern Saw-whet Owl <em>Photo by Matt Bango</em></span>
<img src="images/HAND HELD POWER CUTTERS.jpg" alt="Northern Saw-Whet Owl" />
</a>
</div>
<div class="viewport no-margin">
<a href="http://www.flickr.com/photos/matt_bango/3478879694/">
<span class="dark-background">Red-shouldered Hawk <em>Photo by Matt Bango</em></span>
<img src="images/LIGHTING TOWERS.jpg" alt="Red-shouldered Hawk" />
</a>
</div>
<div class="viewport">
<a href="http://www.flickr.com/photos/matt_bango/3478189088/">
<span class="light-background">Blue-headed Vireo <em>Photo by Matt Bango</em></span>
<img src="images/MAGNETIC STAND DRILLS.jpg" alt="Blue-headed Vireo" />
</a>
</div>
<div><input name="back" value="back" id="back_btn1" type="button"></div>
</div>
But this code is not ok...because i'll have to repeat it for 30 div's.Is there a cleaner way to achieve this.
Use something like this:
$('.myDiv').click(function() {
$('.myDiv').hide(); //Or whatever function you like
$(this).show(); //or whatever function you like
});
The idea is it hides all divs with the same class and then $(this) is used to manipulate the individual div that was clicked on.
You can either target all the divs by giving them a similar class, or if they are all within a parent wrapper use something like $('.parent-wrapper > div')
ANSWER to Comment:
$(this) when used within an event such as a click function relates to the element which the event was triggered on. In this instance it would be a click event on a single div, which means you can use it to manipulate that div without targeting the others.
As mentioned above using a similar class or selector will allow you to target all divs so you can manipulate them as a group. Note that the target div will likely be included, so manipulate the group BEFORE the target div.
Alternatively you can use $(this).siblings() to manipulate all the other divs, if they are on the same level as the div that was clicked, i.e. they are siblings.
You can add a class to all your div, then do something like this. This way you won't have to write 30 functions
function changeImg(id) {
$('.your-divs').stop(true, true).fadeOut({ duration: slideDuration, queue: false });
$('#change_content'+id).stop(true, true).fadeIn({ duration: slideDuration, queue: false });
}
Looks like you need on() function.
This may be implemented like:
jQuery.yourCallback = function () {
//this here is object, on which triggered event
//your code may be below
jQuery(".currentactivediv").removeClass(".currentdiv").hide();
jQuery(this).addClass(".currentdiv").show();
}
jQuery(".yourdivs").on("click",jQuery.yourCallback);
If you want it work with links, you need to locate needed div at DOM where you use jQuery(this).
How it works: when div is showing - script assigns calss .currentactivediv to this div.
When other div is showing - script closes current div, removes .currentactivediv class from it and assigns this class to new div, what is showing.

How to control a div, jquery?

Okay, so basically I can't get it to work with parent as the class isn't in the parent div.
CSS:
.contentSlide{
display:none;
}
HTML:
<div class="contentSlide">
<p>Members image on left and comments on the right. Date floated on right, and link to user.</p>
</div>
<div id="button" class="open">Comments(6) ▼</div>
JS:
$(".open").live('click',function(){
$(this).parent(".contentSlide").slideDown();
$(this).html("Close \u25b2 <span style='float:right;' onclick='reply=true;' class='reply'>Post a <a href='javascript:void(0);'>comment</a></span>").removeClass("open").addClass("close");
});
Basically, we want the div class "open" to make the "contentSlide" div slideDown if it is clicked.
We don't want to use $(".contentSlide").slideDown(); as we want this to be global in the event that we have more than one of these contentSlide divs displaying on the page.
In the case of the HTML you've provided and that it's all we have to go by, you would want to use the .prev() function.
$(this).prev().slideDown();
But I would suggest giving it an ID of some sort or a data type.

Categories

Resources