How do I target an <a> inside a <div>? - javascript

I have this code : http://jsfiddle.net/Qchmqs/BSKrG/
<div class="step"><-- this is darned wrong
<div id="step2"><a>Darn</a></div>
<div id="step2"><a>Darn</a></div>
<div id="step2"><a>Darn</a></div>
</div>
<div class="step"><-- this works fine
<div id="step2"><a>Darn</a>
<a>Darn</a>
<a>Darn</a></div>
</div>
The first block is three links inside three separate divs inside a surrounding div
The bottom block has the links inside one parent div
I am trying to change the background of an active link, but it won't turn off in the upper block.
The script works well with the bottom links but not working as expected with the upper ones
PS : The active class should be toggled only from the Links i have a lot of other scripts in the page that uses the .active links from this list.

For starters, do what JamesJohnson said and remove the multiple IDs. They can only cause you problems down the road.
In the upper links, the a tags aren't siblings because you put each one in its own div. So you need to do this to remove classes from the other as:
$(this).parent().siblings('div').children('a').removeClass('active');
http://jsfiddle.net/mblase75/BSKrG/1/
Unfortunately, that breaks the functionality on the lower links. You can achieve success in both places by adding andSelf to the parent siblings:
$(this).parent().siblings('div').andSelf().children('a').removeClass('active');
http://jsfiddle.net/mblase75/BSKrG/2/

It's not working on the upper ones because you're assigning the same id to the divs. You should probably use the class attribute instead:
<div class="step2"><a>Damn</a></div>
<div class="step2"><a>Damn</a></div>
<div class="step2"><a>Damn</a></div>
After making the above changes, you should be able to do this:
$(".step2 a").text("Hello World!");

maybe this:
<div class="step">
<div id="step2"><a>Damn</a>
<a>Damn</a>
<a>Damn</a></div>
</div>
<div class="step">
<div id="step2"><a>Damn</a>
<a>Damn</a>
<a>Damn</a></div>
</div>

Using radio inputs you can create this effect without any JS at all, which degrades gracefully from its intended appearance (a red backgrounded "damn") to damn with radios next to it (sending the same information).
ironically, this example at JSfiddle: http://jsfiddle.net/YvQdj/
My memory is a bit fuzzy, but I'm pretty sure this doesn't work in older versions of IE without some finagling.

Related

Angular switch Outer Div based on boolean

I am using Angular 1.4.7 and need to do the following
<div ng-if="varIsTrue">
<div ng-if="!(varIsTrue)" my-custom-directive>
A lot of content
</div>
So basically, if the div is set only the proper div shows up. I tried do a few variations of this with ng-if and ng-show but I believe because how the browser renders the dom it is messing it up with the multiple divs, but that is the concept I am going for. Does anyone know how I can accomplish this?
You cannot do this you should have 2 closing tags
<div ng-if="varIsTrue">
</div>
<div ng-if="!(varIsTrue)" my-custom-directive>
A lot of content
</div>
or you will have to switch in my-custom-directive

Hiding an element doesn't redraw page correctly in IE8 if the parent elements have a specific combination of display types

I have a problem when hiding/showing certain elements in IE8. If an element with display:inline-block has any child (including nested children) with display:block, then any child of that element has problems when hiding/showing. The page does not redraw correctly, and other elements position do not change to reflect the newly hidden/shown elements.
The minimal markup that shows the problem is below. In the example, when you click 'Clickable element', then the three divs directly below are hidden. However, the Footer Div does not change position - a large gap is left. If you do something to force a page redraw, such as selecting all text on the page, then the footer jumps to the correct position.
Something similar happens when showing the elements. Instead of the footer div being pushed to the bottom, it is overlapped by the newly shown elements.
<div style="display:inline-block">
<div>
<!-- Any number of other HTML elements -->
<div style="display:block">
<div class = "clickable" >Clickable element.</div>
<div class = "toggleable">Hideable element 1.</div>
<div class = "toggleable">Hideable element 2.</div>
<div class = "toggleable">Hideable element 3.</div>
</div>
</div>
</div>
<div>Footer Div</div>
<script type="text/javascript">
$('.clickable').click(function(){
$('.toggleable').toggle();
});
</script>
I've been trying to break this down for a fair while now, and I'm almost certain that I've got the minimal problem down (inline-block element followed by block element, and perform a show/hide on a child element). Has anybody encountered this before - or any suggestions on how to work around this?
This should do the trick. As the answer below states, inline-block isn't supported in older browsers and shows some quirky behaviour in certain versions of IE8. I've remembered this fix from something I did a while back, but I'm sorry, I can't give you a full explanation as to why this is happening. Anyhow, add a float to your main div, and clear your footer and, fingers crossed, it should work.
<div style="display:inline-block;float:left">
<div>
<!-- Any number of other HTML elements -->
<div class="div-2" style="display:block">
<div class = "clickable" >Clickable element.</div>
<div class = "toggleable">Hideable element 1.</div>
<div class = "toggleable">Hideable element 2.</div>
<div class = "toggleable">Hideable element 3.</div>
</div>
</div>
</div>
<div style="clear:left">Footer Div</div>
Seems to be working fine in here... But note that IE8 have some problems rendering jquery, and the css property 'inline-block' is not really supported by old browser versions (ie7, doesn't work, ie8, i'm not sure). Try adding the "zoom:1;" fix to the css of your tags that have the inline-block going on. Hope that helps somehow.

Clear text inside DIV

I'm using the following HTML structure:
<div id="clock">5:30 AM
<div id="day">Wednesday
</div>
<div id="date">14 December
</div>
</div>
I update the contents of these elements using Javascript. For "day" and "date" I use $("#day").text(day) and $("#date").text(date). Because "clock" is a parent element I had to use $("#clock").prepend(clock) to succesfully add the text.
The problem with the latter function, is that new text is prepended every time the clock is refreshed, i.e. it builds up a list of clock times. For the first two functions the text is just replaced, like it should. Is there a way to make this happen for the "clock" function as well?
EDIT: Sorry, should have been a bit more clear about the clock. Have edited the code, so you understand. BTW, the reason the clock is parent element is that could make the other two elements depend on the clock's position and styling.
I also created a jsFiddle: https://jsfiddle.net/daanodinot/NZtFA/
I left the list building thing (annoyingly) in!
BTW, I'm not too sure if function(); setInterval('function()', 1000) is the best way to refresh, so if you something better I'd be happy to know :)
What you need to do is change the structure of your html to this.
<div id="wrapper">
<div id="clock"></div>
<div id="day"></div>
<div id="date"></div>
</div>
Then for the javascript
$('#clock').text('12:45');
$('#day').text('Wednesday');
$('#date').text('12/14/2011');
This way you can just change/refresh the text of clock instead of prepending values to it.
Another approach, with your current html, which i do not recommend.
<div id="clock">
<div id="day">
</div>
<div id="date">
</div>
</div>
The js
$('#clock').contents().get(0).nodeValue = '12:45';
$('#day').text('Wednesday');
$('#date').text('12/14/2011');
If you have HTML
<div id="clock">
<div id="day"></div>
<div id="date"></div>
</div>
Then you don't have to modify #clock at all. By doing $("#day").text(day) and $("#date").text(date) content of those divs is changed and you don't have to touch #clock.
But in case you want to replace a content of a element then use .html(newContent). See documentation.
You should first add a new element with prepend and then replace it's content, now you just constantly keep prepending new elements instead of working on the same element again.
What do you mean by
Because "clock" is a parent element I had to use
$("#clock").prepend(clock) to succesfully add the text.
?
It seems redundant. Since $('#day') and $('#date') uniquely address your targeted elements.
My tip:
Do not use clock. $("#day").text(day) and $("#date").text(date) already update the numbers inside your #clock element.
Hy,
my consideration for your problem is, IF you choose to manipulate the Content of the #clock div you could simply do this:
var newContent="";//in here comes whatever you want to add to your clock div
$('#clock').html($('#clock').html()+newContent);
That's the way I use it most of the time but you could also do this:
var curContent=$('#clock').html();
curContent+="<>put in your code to add</>";
$('#clock').html(curContent);
This is I guess a bit slower than the first one, but it works.

Adding Additional Div breaks Existing Jquery Code

I have a very simple div with an image inside:
<div class="stack4">
<img src="images/002m.jpg" width=200>
</div>
And a very simple Jquery function for when you hover over the image:
$(function () {
$('.stack4>img').hover(function(){
prompt('hello');
});
});
This all works fine. However, I'm trying to add additional content to the page, and so put the following HTML directly after the end of the first div:
<div id="menucontainer" class="menuContainer">
<div id="menu" class="menuContent">
<img src="images/003m.jpg" />
<img src="images/004m.jpg" />
</div>
</div>
After I add this, the jquery prompt no longer works. Why would adding anothing div break my existing javascript command like that?
There has to be a script error in the page that is causing a failure. Or there is a very slight chance that your new html in some way introduces an invisible element that covers your stack4 image. If you can provide a link somebody could debug it for you.
It breaks because the selector no longer matches any elements (because the class selector .stack4 does no longer match any element).
<div id="menucontainer" class="menuContainer">
<div id="menu" class="menuContent">
<img src="images/003m.jpg" />
<img src="images/004m.jpg" />
</div>
</div>
$(function () {
$('.stack4>img').hover(function(){
prompt('hello');
});
});
If you look at your javascript, it will:
match any child image of an element with class name stack4
Add a hover listener to each image
Display a prompt on hover.
IF you look at your updated DOM structure, class stack4 no longer exists. To make it work again, you have to replace this selector with your new equivalent, which would be the div with id=menu and class=menuContent.
Now, depending on your needs, you can target either #menu>img or .menuContent>img. If you go with the first one, the javascript fragment will only work for a single menu, with the id of menu. However, if you choose the second approach, any content with the class menuContent will have this functionality. So I'd go with:
$(function () {
$('.menuContent>img').hover(function(){
prompt('hello');
});
});

jquery mutually exclusive click

I have 3 divs with 2 possible image tags for each (active or inactive). If one div is clicked to be active the other divs must be set to inactive. How do I accomplish this with img tags and what happens if user has javascript disable?
Do you mean something like this?
<div class="block" id="block1">
<img src='inactive_block1.jpg'>
</div>
<div class="block" id="block2">
<img src='inactive_block2.jpg'>
</div>
<div class="block" id="block3">
<img src='inactive_block3.jpg'>
</div>
Using a library like jQuery, the javascript would look like:
$(function() {
$('.block').click(function() {
$('#block1').find('img').attr('src', 'inactive_block1.jpg');
$('#block2').find('img').attr('src', 'inactive_block2.jpg');
$('#block3').find('img').attr('src', 'inactive_block3.jpg');
$(this).find('img').attr('src', 'active_' + $(this).attr('id') + '.jpg');
});
});
With the above, if you have inactive_block1.jpg, inactive_block2.jpg, inactive_block3.jpg and active_block1.jpg, active_block2.jpg and active_block3.jpg you should get what you want.
It's up to you whether its worth it or not to have javascript disabled fallbacks, mostly depending on whether you expect a large amount of your audience to have javascript disabled.
if a user has JavaScript disabled, there is nothing you can do that is JavaScript-based to deal with dynamically modifying the page. The only other option you have is to create a "deprecated" version of your functionality that requires a page request after each click.
I would recommend researching how to dynamically add/remove classes from elements in the DOM, that is how I would approach this problem. You could easily do a jQuery select for all elements who are "active" on click and set a "disabled" class on them, that way you are essentially blacking out everything except the element you've clicked.
Does that make sense?

Categories