Issues with addclass and selectors - javascript

I'm pretty green with jQuery so I'm sure this is an obvious error - but nonetheless it has me stumped. I'm trying to make a pretty simple navbar that shifts from 500px down the page to absolute positioning at the top after you scroll past it.
The issue: I can't seem to get the js to find the navbar when I'm using a div ID of navbar and a selector of #navbar.
Here is the js:
$(document).ready(function () {
$(window).bind('scroll', function () {
var scrollDepth = 500;
if ($(window).scrollTop() > scrollDepth) {
$('#navbar').addClass('fixed')
} else {
$('#navbar').removeClass('fixed')
}
})
})
Here is a jsfiddle of the issue: http://jsfiddle.net/ayGwn/475/

It is an issue with specificty. A CSS rule for an id will override a CSS rule for a class. If you change the .fixed { ... } to #navbar.fixed { .. } it should work. Assuming you are not using .fixed for anything else.
MDN article about CSS selectors specificty
The following list of selectors is by increasing specificity:
Universal selectors
Type selectors
Class selectors
Attributes selectors
Pseudo-classes
ID selectors
Inline style

You should use #navbar.fixed, instead of .fixed only. Because id style gets more priority than class style. In your case javascript is working fine. the .fixed class is being added. But as you have defined position:absolute for you #navbar id, it is overriding style rules for .fixed class.

Related

Pseudo element manipulation

I have this DOM
<div class="slotvideo">
<div class="posterimage"></div>
</div>
I can't modify this html code but I need to add an SVG icon. This SVG is used for a function. On click I need to reach the bottom of the page. I create this CSS
.posterimage::before {
content: "";
background-image: mysvg;
}
Now, I can't manipulate pseudo element but I can't find another solution for doing it. How could you fix this problem?
I couldn't find what do you actually want. but about manipulating pseudo-elements, it's not possible. But there is a work-around.
You can define another class name like .active change the element's class to it for controlling pseudo-element.
.posterimage {
/* anything... */
}
.posterimage.active::before {
content: "";
background-image: mysvg;
}
don't forget, psuedo-elements are inline by default, so if you want this background-image to show up, you need to make it display: block and define a set of width and height though.
and it's done. you can use that .active class to have controll of showing ::before or not by JavaScript.

Use Slick.js custom pseudo-classes in regular CSS

I want to create some custom pseudo classes using Slick like this
Slick.definePseudo('in-fold', function(){
var isInFold = false;
// code to determine if the element is visible in the viewport
return isInFold;
});
and then use those pseudo-classes in regular CSS like so
nav:in-fold {
display: static;
width: 100%;
font-size: 1.2em
}
If this is possible at all, I couldn't get it to work. Am I missing anything?
If this is not possible using Slick.js, is there another way of doing the same thing?
Slick pseudos can only be used when querying elements with Slick (and Mootools), you cannot use them in CSS. You could try to add some JS code to apply and remove regular CSS classes when the in-fold pseudo can change (scroll and resize), but be aware of performances:
var updateInFoldStyle = function() {
$$('nav.in-fold-class').removeClass('in-fold-class');
$$('nav:in-fold').addClass('in-fold-class');
};
window.addEvent('scroll', updateInFoldStyle);
window.addEvent('resize', updateInFoldStyle);
Some ideas if performance is poor:
avoid removing and re-adding class when not needed;
use the :pause pseudo event to avoid firing scroll and resize events too frequently.

Applying a style to a specific body class

I need to apply an additional "margin-top" to a specific class in the body. This class' name is already in a CSS file and reads:
html body.admin-menu {
margin-top:29px !important;
}
However, I need a place in my jQuery to change this margin-top to 60px.
I have tried these 4 options with no cigar:
$('html body.admin-menu').addClass('marginfix');
$('html body.admin-menu').attr('style', 'margin-top:60px !important');
$('html body.admin-menu').attr('style', function(i,s) { return s + 'margin-top: 60px !important;' });
$('<style>.marginfix { margin-top:60px !important; }</style>').appendTo('html body.admin-menu');
The only element I can seem to affect is "html" but I need to apply this style to this very specific case (html body.admin-menu), and not just the "html" tag.
Anyone know what will work?
Not sure but what seems to me is that you are missing the doc ready method. It seems that you are adding the class to the element before it is ready.
This should work:
$(function(){
$('html body.admin-menu').addClass('marginfix');
});
or try this:
$(function(){
$('html body.admin-menu').css({marginTop: '60px'});
}); // above code will make a inline css to the body.
try to wrap it in doc ready method and i guess you have style for this css class .marginfix in your css file somewhere. Although you can omit the html from the selector.
this css should be available like this:
html body.admin-menu {
margin-top:29px !important;
}
.marginfix{
margin-top:60px !important; // this overrides above class applied to body.
}
You can do something like that to add the style to your <head>
$('<style type="text/css">.marginfix { margin-top:60px !important; }</style>').appendTo($('head'));
You then call your addClass() methods:
$('body.admin-menu').addClass('marginfix');
Try this:
$('body.admin-menu').css({'margin-top':'60px'});
and remove that !important from your CSS. Just add the body.admin-menu section after all other CSS so it overrides any previous styles.

Changing Visibility of HTML elements

I want to change the visibility of HTML elements except some particular elements. I want the elements to be at the same positions and alignments and just the visibility of elements to be changed. Can somebody please help me doing that?
I tried doing the same using jquery by seeing the answer to How to hide all elements except one using jquery? but this changes the positions and alignments of elements.
$('body > :not(#averageCustomerReviews)').hide(); //this hid everything
$('#averageCustomerReviews').appendTo('body'); //but this changed the position
I currently have locators to elements like xpaths/CSS Selectors which I don't want to hide.
For e.g. I have this link. And I want to view only at the place it is right now by hiding all other elements.
VISIBILITY USAGE
jQuery
$("#element").css("visibility", "hidden");
CSS
#element {
visibility: hidden;
}
If you want all the others elements than #element to be "invisible":
jQuery
$(":not(#element)").css("visibility", "hidden");
CSS
:not(#element) {
visibility: hidden;
}
ANSWERING YOUR 'AFTER' QUESTION - LET ALL INVISIBLE EXCEPT ONE
If you can't assign an 'invisible' class to the elements that should be invisibile (best solution), you can render visible only one child element in this manner, see JsFiddle.
That mean:
set all 'invisible': $("*").css("visibility", "hidden");
set visible the element you want to show: $("#element").css("visibility", "visible");
In your case the element you would like to show is a little 'nested' and you can do in this manner:
// set all 'invisible'
$("*").css("visibility", "hidden");
// set visible the element with their 'sub-child'
$("#averageCustomerReviews_feature_div, #averageCustomerReviews, #averageCustomerReviews a, .reviewCountTextLinkedHistogram, .reviewCountTextLinkedHistogram a, .a-popover-trigger, .a-popover-trigger i").css("visibility", "visible");
Not nice, but it works.
With a html tree complex like this one and without any possibility to assign some custom class. I think that this is the only solution...
Use visibility: hidden;. Unlike display: none; the element will still be there.
Too apply to all elements except one use a style like this:
* {
visibility: hidden;
}
#element {
visibility:visible !important;
}
JSFiddle
Information on visibility.
If you are looking to hide everything but #element then use this:
:not(#element) {
visibility: hidden;
}
See here for more info on the :not() selector: https://developer.mozilla.org/en-US/docs/Web/CSS/:not
UPDATE
You can also chain :not() selectors together to exclude multiple elements. For example, if you have #element1 and #element2 that should not be hidden from view, then do something like this:
:not(#element1):not(#element2) {
visibility: hidden;
}
You can set up in CSS, where class is the class that's on all the elements you want to hide:
.class {
visibility: hidden;
}
and then
$('#element').css('visibility', 'visible');
use this
jquery
$("#elementid").onclick(function() {
$('body').css({ 'visibility': 'hidden'});
$('#elementid').css({ 'visibility': 'visible'});
});

Update CSS rule property value

I have a html element which is styled (using jquery) with a background image targeted thru its class name.
When I remove the class the background image stays - which is not what I expected or want.
test.html
<div id='log' class='tile'>HELLOWORLD</div>
test.css
.tile{
background: none;
}
test.js
$('.tile').css("background-image", "url(tile.jpg)"); // We see image
$('#log').toggleClass('tile'); // We still see image
After banging my head I think I know whats happening. The css is being applied to the element - NOT to the 'class'.
How can I target a specific css rule so that its key values can be updated?
If that makes sense.
If you wan to change the css rules of the ".tile" class, then you can do it.
There is a post that explains it very well :
function changeBackgroundImage(className, value){
var ss = document.styleSheets;
for (var i=0; i<ss.length; i++) {
var ss = document.styleSheets;
var rules = ss[i].cssRules || ss[i].rules;
for (var j=0; j<rules.length; j++) {
if (rules[j].selectorText === className) {
rules[j].style.backgroundImage = value;
}
}
}
}
You can call it like this :
changeBackgroundImage(".tile","url(tile.jpg)");
The problem is that you´re setting the background-image as an inline stlye that overrides any stylesheet rules. Toggling the class won´t have any affect.
You can either have set the background through a styleheet rule and then add a class that removes it;
#log {
background-image: url(tile.jpg);
}
#log.tile {
background: none;
}
or you could just use !important as;
.tile {
background: none !important;
}
...it might be the other way around but you get the point? :)
try removing class tile and applying new class with bg: none
in effect - when needed apply class with bg, when not needed - without
No need for jQuery in this case. You can use plain old JavaScript. Check out this tutorial:
javascriptkit.com - Changing external style sheets using the DOM
You can't change the class itself without re-writing that declaration in the stylesheet, you ARE working only with the element in the selector.
Try:
$('.tile').css("background-image","none")
$('#log').toggleClass('tile',true);
I would make the background image part of the class as a css style:
.tile {background-image: url('tile.jpg')};
and then remove the class when necessary with jquery
$('#log').removeClass('tile');
you could have two classes in your css...
.tile{
background: none;
}
.tile-w-image
{
background-image: url(tile.jpg);
}
and then with jquery just toggle the classes...
$("#log").toggleClass('tile').toggleClass('tile-w-image');
I'm sure this is just one of many ways of doing this. I hope it helps.
You are very close.
It seems like you are adding inline CSS to your element and then trying to toggle the class. You should keep CSS styling separate in most cases:
HTML:
<div id='log' class='tile'>HELLOWORLD</div>
jQuery (I imagine this should be done on click or another event):
$('#log').toggleClass('tile'); // We still see image
If the "tile" class is already written to the HTML, then toggle-ing it will remove it.
CSS:
.tile{
background-image: url(tile.jpg);
}

Categories