jQuery add class based on CSS characteristics - javascript

I am looking for a method with jQuery (or plain JS) in which to build a conditional on whether a div has a specific CSS characteristic.
For example, I want jQuery to add position:fixed to an element's CSS when another element is set to display:none, though change back to position:relative on the first element when the second element changes to display:block.
Any ideas?

If your change is event driven you just add the code to your event handlers
so if element one is made hidden by a click - make element 2 position fixed
$("#element_one").click(function(){
$("#element_one").hide();
$("#element_two").css({"position":"fixed"});
})
if you just want to watch elements you will need timers (although I cannot really imagine a scenario where you do not trigger the change by either an event of programaticaly)
watchInterval = setInterval("watchMe()",10)
function watchMe(){
if ($("element_one").is(":hidden") ) {
$("#element_two").css({"position":"fixed"});
}
}

$('#elOne').css('display') == 'none' ? $('#elAnother').css({'position':'fixed'}) : $('#elAnother').css({'position':'relative'});
Would that do the trick?
or perhaps :
$('#elOne').is(':hidden') ? $('#elAnother').css({'position':'fixed'}) : $('#elAnother').css({'position':'relative'});

There's not any nice way of doing this as you cannot "spy" on CSS changes, though jQuery does have a watch plugn which can monitor changes on certain properties. Your best bet is to use getComputedStyle which will get the real CSS values used for any object and act accordingly.

Related

Elegant way to return element to display:none?

I have a dropdown, and a list of elements that default to display:none with css.
Currently, when an element is selected from the dropdown it's changed to display:block
What I'm missing, is how to change the element back to display:none once a new one is selected. I know I could write a loop to constantly check every element and change it to display:none but that seems cumbersome.
My real problem has about 100 elements, and it seems wasteful to re-hide all of them when 99 of them will already be hidden.
Curious what the most elegant way to do this in jQuery (or javascript) is. A fiddle of what I have is here:
https://jsfiddle.net/3w66k51z/4/
Thanks!
I've added $(".sReport").hide(); before your .show() call in order to hide all of the elements.
jQuery.hide() will set the element's display to none
jsfiddle
You could add state so that you know the currently shown item (if any) and hide just that one element. I understand you don't want to hide all items when most of them will already be hidden.
Here is a simple implementation of this idea.
(I imagine your real problem involves many more hidden items than the fiddle. If not — maybe even if so — this may be a premature optimization, and there’s nothing wrong with calling .hide() or whatever on all items.)
Create array of your element then create a function to hide all elements but not the one you want to be display.

How to make style of an element dependent on another element's style

I need to set some special style for an element if some other element is visible (which is indicated by a special css class and can change dynamically). I need to do this because the page rendering and it's behavior is fully controlled by some framework's code and I don't want to change it. I can put any content anywhere in the body of the page. Is there a non-hacking way to do it?
My only idea was to use some plug-in like "watch" for jquery, but it's very ugly.
try using the properychange/attributemodified event
$("object-in-question").bind("DOMAttrModified propertychange", function(e) {
if($(this).is(":visible")).... etc
});
http://jsbin.com/abece4

How to detect if an element is not visible in a fast way in JavaScript?

In the past we used the CSS attribute "display" to show and hide DOM elements. To check if an element is visible, we could just use:
element.offsetWidth > 0
Since we had some problems with Flash and Java Applets (they stop when they get display:none) we switched to the CSS attribute "visibility".
I am now looking for a fast and easy way to check if an element is not visible.
I have tried the following:
Checking the attribute itself on the element and and all parents => too slow
Checking the calculated style directly from the browser (element.currentStyle or window.getComputedStyle() plus getPropertyValue(style property)) => also too slow
Do you know any other way or shortcut to see if an element is visible?
use JQuery and the you can do this
var isVisible = $('#foo').is(':visible');
Remember that visibility:hidden makes an element hidden, but that element still occupies its space, which may have some unexpected consequences on the layout (it may be an advantage as well if you are aware of this).
I would use absolute positioning to move the element far to the left, outside possible screen width. This gets the element out of the flow so the hidden element has no impact on layout, makes the element practically invisible, and it doesn't have the disatvantages of display:none.
.hide {
position:absolute;
left:-3000px;
}
Then to determine if an element is hidden you can use its offsetLeft property:
if( myElement.offsetLeft < 0 ){ /* it's hidden */ }
If you need to determine if a child element is off the screen (you don't know if it's the hidden element or its child) you can use .offsetParent and a while loop, as described in PPK's Find Position article.
Toggling Element Visibility by Kent is an unobtrusive, semantically valid way of presenting content that will degrade nicely for non-CSS-aware browsers.
After the page loads completely, we crawl through the entire document tree and look for block-level elements styled with class name toggle. If we find one that says toggle closed, we immediately hide its next sibling element, by styling it with class name hidden.
When we find one, we tell it to listen for mouse clicks.
When one of our pet elements hears a click, it leaps into action, hiding (or showing) its next available sibling, the same way we did it during the initial crawl.
All three class names (toggle, closed, and hidden) are fed in at the bottom in the init call, and may be changed to any valid class name.
Also look at this DevX article which compares the Display and Visibility properties.
Checking the focus would work, either parent is visible or not.
var isVisible = true;
try{
document.getElementById("target").focus();
}catch(err){
isVisible = false;
}
It obviously should work on input or link, but for other element, I'm not sure.
I have studied the same problem before using jQuery, but that time my aim is to focus the first availabe field on a form. The resulting code is like:
$(":text:visible:enabled").filter(function(){
return $(this).parents.filter(function(){
return this.style.display == "none";
}).size()==0;
}).slice(0,1).focus();
It would also work for hidden/invisble parent.
CSS selectors are optimised to find sets of matching elements. There are several libraries implementing this functionality. JQuery, ExtJS Core to name a couple.
Using Ext Core, I could write a javascript function that checks for visibility as follows:
// Checks whether the element is currently visible using
// both visibility and display properties
if(Ext.get(el).isVisible()){
alert('it\'s visible');
};
see http://extjs.com/products/extcore/docs/?class=Ext.Element for more Ext Core Ext.Element functionality.
function isVisible(elem) {
return elem.style.visibility !== "hidden";
}

Call Javascript function when a div turns from visibility : hidden

I want to call a Javascript function when a div is turned from "visibilty : hidden" to "visibility : none;"
Also note that I don't have control over the script which turns this style property of the div. I just want to hook into this. Any possibilities? Or like onFocus() etc?
UPDATE : I do not want to use JQuery or other frameworks. Is it possible?
In mootools you can create custom events. However, I would do something like this:
document.getElementById('foo').triggerMyEvent = function() {
if (this.style.visibility == 'hidden') {
// do something
} else {
// do something else
}
}
And add a call to the object's 'triggerMyEvent' method in whatever code switches the object's visibility.
There's the propertychange event in IE that responds to changes in an element's properties, including properties of its style object. However, this only works on properties set directly on the element's style object and doesn't work for CSS changes (e.g. changing the class of the element's parent element) that indirectly affect the element's style. Using the DOMAttrModified in other browsers will work similarly and has the same shortcomings, so this may not be workable for you.

jQuery Hide using ID

I'm trying to change the border color of an image using its id with jquery
( photo['id'] is passed in from a previous function )
the ids of the photos are of the form 'photo239839'
$('#photo'+photo['id']+'').click(function(){
$('#photo'+photo['id']+'').css('border-color','#777');
});
When I try to use this same code using its class it works,
but I can't use this method since there are multiple images on the same
page with the same class
$('img.flickr_photo').click(function() {
$("this.flickr_photo").css('border-color','#777');
});
This is what you need to do:
$('img.flickr_photo').click(function(){
$(this).css('border-color','#777');
});
I would always always add a css class rather than an inline style.
Much more maintainable and extensible.
Example:
$('img.flickr_photo').click(function(){
$(this).addClass('greyishBorder');
});
Either photo['id'] is wrong, or is changing after you set up the click handler.
To test for the first case, you can alert (or console.log with FireBug, or whatever) the length of the jQuery selection:
alert($('#photo'+photo['id']).length);
The solution in the second case is to use 'this'. In the click handler, 'this' is set to the element that caused the click event.
$('#photo'+photo['id']).click(function(){
$(this).css('border-color','#777');
});
Edit: #Dreas Grech is right, as long as you want to apply the behavior to all the elements with the flickr_photo class. If you can generalize the selector to select all the elements with a single query, it's better to do that.

Categories