Detect if an element is visible with jQuery [duplicate] - javascript

This question already has answers here:
How do I check if an element is hidden in jQuery?
(65 answers)
Closed 8 years ago.
Using .fadeIn() and .fadeOut(), I have been hiding/showing an element on my page, but with two buttons, one for hide and one for show. I now want to have one button to toggle both.
My HTML / JavaScript as it is:
<a onclick="showTestElement()">Show</a>
<a onclick="hideTestElement()">Hide</a>
function showTestElement() {
$('#testElement').fadeIn('fast');
}
function hideTestElement() {
$('#testElement').fadeOut('fast');
}
My HTML / JavaScript as I would like to have it:
<a onclick="toggleTestElement()">Show/Hide</a>
function toggleTestElement() {
if (document.getElementById('testElement').***IS_VISIBLE***) {
$('#testElement').fadeOut('fast');
} else {
$('#testElement').fadeIn('fast');
}
}
How do I detect if the element is visible or not?

You're looking for:
.is(':visible')
Although you should probably change your selector to use jQuery considering you're using it in other places anyway:
if($('#testElement').is(':visible')) {
// Code
}
It is important to note that if any one of a target element's parent elements are hidden, then .is(':visible') on the child will return false (which makes sense).
jQuery 3
:visible has had a reputation for being quite a slow selector as it has to traverse up the DOM tree inspecting a bunch of elements. There's good news for jQuery 3, however, as this post explains (Ctrl + F for :visible):
Thanks to some detective work by Paul Irish at Google, we identified some cases where we could skip a bunch of extra work when custom selectors like :visible are used many times in the same document. That particular case is up to 17 times faster now!
Keep in mind that even with this improvement, selectors like :visible and :hidden can be expensive because they depend on the browser to determine whether elements are actually displaying on the page. That may require, in the worst case, a complete recalculation of CSS styles and page layout! While we don’t discourage their use in most cases, we recommend testing your pages to determine if these selectors are causing performance issues.
Expanding even further to your specific use case, there is a built in jQuery function called $.fadeToggle():
function toggleTestElement() {
$('#testElement').fadeToggle('fast');
}

There's no need, just use fadeToggle() on the element:
$('#testElement').fadeToggle('fast');
Here's a demo.

if($('#testElement').is(':visible')){
//what you want to do when is visible
}

Related

jQuery: Hide parent if child contains text number range?

I use a current jQuery selector to apply css to any elements containing certain keywords on YouTube as listed below:
$( '.feed-item-container:contains("Blah Blah") ') .css( {"display":"none"} );
My question is, how can it be changed so instead of using keyword detection, it can instead use a number detection range for each youtube feed on the subscriptions page(signed in)? If the element used to display the view count in the specific element ".feed-item-container", then how can that element(".feed-item-container") that displays each video/feed to apply css to hide it, but detect a number range for an element in it for ".yt-lockup-meta-info" containing 0 to 300 views?
To be clear, I do not need it to detect keywords and view count, only removing the parent element (by class selector) if the child element (by class selector) contains 1-300 views; already have jQuery to hide by keyword.
The closest I have gotten but incorrect:
$( ".feed-item-container:has(.yt-lockup-meta-info > :last-child)" ).slice(1, 300).css( "display", "none" );
I just realized moments later of why it wasn't working; thus realizing .slice, only selects elements and not number ranges such as 1-300.
I understand this may or may not be a complicated problem, but my knowledge of jquery does not go down this path of understanding. Any help is much appreciated, but if solvable it would be very appreciated. This may help: http://jsfiddle.net/fVtaF/7/ + http://jsfiddle.net/eWweU/4/ (doesn't work)
I wonder if this FIDDLE, as a concept, would be helpful.
Using the JS $('#containme').text().indexOf( i ) > -1you can assign a variable to the .indexOf, and loop through a series of variables to see if there is a matching number in your element.
Lots of "overhead". I'm sure there are more elegant ways.
I'm not 100% sure of what you're asking, but if I understand you correctly maybe this fiddle will help you: http://jsfiddle.net/eWweU/3/
It uses jQuery to test every child of the feed-item-container class to see if it has a number from 0-300. If it does, it will hide that feed-item-container container.
Good luck.

selecting one of the rules of the style attribute [duplicate]

This question already has answers here:
Select all elements that have a specific CSS, using jQuery
(6 answers)
Closed 9 years ago.
please help to solve the problem
on the page, there are several img. some have the attribute
style="line-height: 1.538em; float: right;"
, some have attribute
style="line-height: 1.538em; float: left;"
I would like to js or jquery to select only those img, whose float: right;
In this mode you loop each image inside your dom and search only elements image with css: float:left
Try this:
$('img').each(function(index){
if(this.style.cssFloat =='left'){
//your code here
}
});
A bit tricky, but i would try something like:
$('img').each(function() {
if ($(this).css('float') === "left") {
//my stuff
}
});
Then again, giving a custom class to what you want to select is probably a better idea.
You could use an "attribute contains" selector (*=):
var imgs = $('img[style*="float: right"], img[style*="float:right"]');
(Note I've allowed for there being a single space, or not.) But it seems quite delicate and may be slow (doesn't really matter if you do it once, might matter if you do it a lot). Instead, I'd probably add a class to the relevant images. This will be faster on modern browsers than the each loops other answers suggest, however, as the work can be done within the browser's selector engine rather than in the JavaScript layer.
Also note that that will only match if the actual img tag has float: right within its style attribute.
try $('img[style*="float:left"]')

Optimising Jquery code - Adding and removing classes on click

I am currently learning js and jquery to assist me with my designs, a common problem that I am having is that I can get it to do what I want it to but I have no idea if the way in which it has been coded is efficient. Could anyone see a better way to code this:
$(".cal-check a").click(function(e) {
e.preventDefault();
$(".agenda").addClass("active");
});
$(".agenda .close-panel").click(function(e) {
e.preventDefault();
$(".agenda").removeClass("active");
});
I want to click on a calendar event then it adds the class active to another class within the calendar called agenda which then brings up the agenda. I then remove it by clicking on a close panel element. Many thanks
You could cache the .agenda selector like so:
var $agenda = $(".agenda");
$(".cal-check a").click(function(e) {
e.preventDefault();
$agenda.addClass("active");
});
$agenda.find(".close-panel").click(function(e) {
e.preventDefault();
$agenda.removeClass("active");
});​
I recommend not changing classes, that will usually be rather intensive on the browser, because one class change will mean that all the classes have to be reparsed. This is usually very bad for more aggressive stuff, like animation, but if you have performance considerations, you should take that into advisement.
I think this is already efficient.
Just something that might help in the future is to try and dive into the DOM as little as possible. In this small example it wont make a difference but for example create a variable for agendaClass instead of using jquery every time to fetch it.
var agendaClass = $(".agenda");
$(".cal-check a").click(function(e) {
e.preventDefault();
agendaClass .addClass("active");
});
$(".agenda .close-panel").click(function(e) {
e.preventDefault();
agendaClass .removeClass("active");
});
That should be efficient enough. How you can optimize your code strongly depends on your DOM structure.
Behind the scene, jQuery with its Sizzle search engine will use built in methods for DOM search, if those are available (native search will be always faster than search done with JS). In your case everything should be Ok, especially in modern browsers, as they have querySelectorAll and .cal-check a and .agenda selectors will be executed with that built in method. Also, there is getElementByClassName which could be used to find .agenda.
Both of those methods are supported by most of modern browsers (provided links have a list of supported browser), so talking about browsers like IE8+, Firefox and Chrome will be fast enough with your selectors. At the same time IE7 has no functions like above and Sizzle will be forced to go through numerouse elements to find elements you are looking for. Maybe you can limit that amount specifying some container with id, in that case it will look inside that elements only:
$("#someId .agenda"), for instance. You may want additionally add some tag: $("#someId div.agenda"). This way you will limit amount of elements to search with divs (getElementsByTagName could be used) inside #someId (getElementById). That way you may increase speed in IE7 and other old browsers with no support of getElementByClassName and querySelector
Plus, you may cache search results as it was already mentioned here.

Will jQuery search for the ID before filtering other parameters in the selector?

This question is related to performance.
If I use a selector like the following
$('#myID a') // Does this find #myID and filter by a?
Or should I write the statement like this?
$('#myID').find('a')
I'm not sure if jQuery is smart enough to execute this statement using the ID first or if it operates exactly like CSS and reads right to left. It's not such a big deal using tags but when you run something like
$('#myID .myClass')
It makes a HUGE difference in performance.
From a NetTuts article: http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-think-right-to-left-with-jquery/
As an example, if Sizzle comes across a selector like $('#box p'),
it’s true that it works right-to-left, but there’s also a quick regex
optimization that will first determine whether the first section of
the selector is an id. If so, it’ll use that as the context, when
searching for the paragraph tags.
Relevant comment from SizzleJS:
// Take a shortcut and set the context if the root selector is an ID
// (but not if it'll be faster if the inner selector is an ID)
When an Id is in the selector. jQuery will first execute document.getElementById then begin filtering for child elements.
basically this is why it is never a great idea to use just attribute or class selectors $('.someclass') or $('[name=myname]') without being more specific. Because it causes the code to traverse the DOM and look at every element to find that class.
By just adding a tagname to the same selector $('div.someclass') or $('div.[name=myname]') you improve efficiency becuase it will first run. document.getElementsByTagName narrowing the number of elements to search.

jquery selector help

i have a event i trigger on every link in my site.
but then i want it to NOT trigger on links i've got class='nofocus' on.
for example
<a>link</a>
<a class='nofocus'>register</a>
$('a').live('click', function() {
$('#searchbox').focus();
}
how do i rewrite the $('a) so the second link wont trigger the event?
Theoretically, there are three options.
1. Using the “attribute not equal to” selector
The “attribute not equal to” selector matches elements that either don’t have the specified attribute or do have the specified attribute but not with a certain value.
$('a[class!=nofocus]')
This will only work as long as you don’t use multiple classes on your A elements in your markup, e.g. foo.
See Selectors/attributeNotEqual in the jQuery docs for more information.
2. Using .not()
Another option is to select all the A elements first, then filter the results, removing elements with class="nofocus" from the result set.
$('a').not('.nofocus')
This is more flexible, because it allows the use of multiple classes on A elements.
Also, it’s slightly faster than using The Attribute Not Equal To Selector™ in Firefox, but slightly slower in Safari.
See Traversing/not in the jQuery docs for more information.
3. Using the :not() selector
The fastest (and shortest) option is to use the :not selector:
$('a:not(.nofocus)')
Also, my tests point out that this is by far the fastest method of the three — more than twice as fast as using the attribute not equal to selector!
Performance comparison of the three options
I created a jsPerf test case so you can test this yourself: http://jsperf.com/get-elements-without-specific-class.
TL;DR: Use $('a:not(.nofocus)').
Try the :not() selector (docs):
$('a:not(.nofocus)').live('click', function() {
$('#searchbox').focus();
}
Selector: $("a:not(.nofocus)") will select all links without the nofocus class.
Use $("a:first"). http://docs.jquery.com/Selectors/first to just get the first one.
$('a:not(.nofocus)')
should do the job
http://docs.jquery.com/Selectors/not

Categories