Targeting CSS on div range - javascript

I have an element I populate with $.ajax now I want to fade all the custom loaded elements, the element is already pre-populated with 20 elements when the page loads, I don't want to target those 20. Essentially, how can I target the latter 17 divs assuming I have 37 divs total? Currently I use:
while ($(".info #future>center>div").length>20) {
$(".info #future>center>div:last-child").remove();
}
to remove them, but now I also want a fading effect to be applied prior, assigning anything to their class is not an option since that property is already taken.

you can use `slice() Slice() method of jquery. Given a jQuery object that represents a set of DOM elements, the .slice() method constructs a new jQuery object containing a subset of the elements specified by the start and, optionally, end argument. The supplied start index identifies the position of one of the elements in the set; if end is omitted, all elements after this one will be included in the result.
$('.info #future>center>div').slice(20).remove(); //Where start and end your index to filter. I omitted end parameter. if you want you can put it. .slice(20,37)
if you want fading effect
$('.info #future>center>div').slice(20).fadeOut(300, function() { $(this).remove(); });

take look on jQuery :gt() Selector.
it used to select all elements at an index greater than index provided to it so you can call it with index = 20
$(".info #future>center>div:gt(20)").remove();

Related

I want to create a jQuery loop out of this function instead of copying this function over and over for 12 times

I need some help with creating a loop in this jQuery function. I have some elements on my HTML page with the attribute [level-data="l1"], and I use them in my function to make some changes on the page. I have 12 different attributes starting with the [level-data="l1"] and finishing with the [level-data="l12"]. What I want is to create a jQuery loop instead of copying this function over and over for 12 times, each element will have a different [level-data='ln'] attribute, where n is a number from 1 to 12.
Here is my code:
$('.chart-level[level-data="l1"]').on("click", function () {
$('.chart-level').removeClass('active');
$('.chart-levels-items .level-info').removeClass('active');
$(this).addClass('active');
$('.chart-levels-items .level-info[level-data="l1"]').addClass('active');
$('.chart-slider-item.page_slider').removeClass('shown');
$('.chart-slider-item.page_slider[level-data="l1"]').addClass('shown');
$('.chart-slider-item.popup_slider').removeClass('shown');
$('.chart-slider-item.popup_slider[level-data="l1"]').addClass('shown');
if(window.matchMedia('(max-width: 768px)').matches){
$([document.documentElement, document.body]).animate({
scrollTop: $(".chart-levels-items .level-info[level-data='l1']").offset().top
}, 2000);
}
});
Thank you in advance!
You don't need a loop. Use .chart-level[level-data] as the selector and read the level-data attribute of the clicked element. [...] is an attribute selector which selects elements that have a certain attribute.
Note that level-data is an invalid attribute. You can use data-* attributes instead. i.e. change it to data-level. Then you can use $(this).data('level') for reading the value of the data-level attribute.
$('.chart-level[data-level]').on("click", function () {
var level = $(this).data('level')
$('.chart-levels-items .level-info[data-level="' + level + '"]').addClass('active');
// ...
});
In case that you are using the attribute just for selecting related elements to the clicked element, then you should consider using jQuery traversal methods (like parent, siblings, ...) for selecting the target elements instead.

Make screenshot of all elements with the same selector on the page

I need to make screenshot of all text with same selectors on the page. For example I have 11 of the same selectors but with different text on the page.
But when I use "repeat" I can't do it. It only capture the first selector 11 times.
casper.repeat(11, function() {
casper.captureSelector(Math.random()+".png", ".annotation");
});
Doing the same thing over and over again and expecting different results ... may happen in web browser testing, but not in this case. In this case you're repeating the same task over and over again with the same selector. You need to iterate over the selectors.
This will not work using CSS selectors because :nth-of-type() for example means the nth element under the same parent, which may not be the case for your site.
You should use an XPath expression to do this. CasperJS provides an XPath utility to make it easier invoking them:
var x = require('casper').selectXPath;
casper.then(function(){
var elements = this.getElementsInfo(".annotation"); // for correct count
elements.forEach(function(_el, index){
// don't need the element info, this was done just for count
casper.captureSelector(Math.random()+"_"+index+".png", x("(//*[contains(#class,'annotation')])["+(index+1)+"]"));
});
});
What this XPath means:
//*[contains(#class,'annotation')] selects all .annotation elements as a node list.
"(//*[contains(#class,'annotation')])["+(index+1)+"]" selects the index+1'th element from the node list. Counting starts with 1 in XPath expressions

jQuery: Using .after() or .before() adds element to last item in selection only

I've been using jQuery for a while but this is a new one. A simplified example:
HTML
<div class='custom'></div>
<div class='custom'></div>
<div class='custom'></div>
jQuery:
var $customElems = $('.custom'),
$spanOuter = $('<span class="outer"/>'),
$spanInner = $('<span class="inner"/>');
$customElems.each( function() {
$(this).wrap($spanOuter).after($spanInner);
});
JSFiddle:
http://jsfiddle.net/a3ZK8/
I would have expected the 'inner' span to be added to all three elements in the selection but it gets always inserted into the last one only (no matter how many). I tried it with .before(), with and without the chaining, same result. What am I missing??
The problem is you are using a reference to a jQuery object.
Hence you keep moving the object reference around within each iteration.
If you have no events attached or no need for the span to be a jQuery object then just pass the parameter as a HTML string literal instead of an object reference
Cloning a jQuery object that doesn't need to be a jQuery object in the first place is just redundant processing and unnecessary overhead.
Change your jQuery object to a string similar to this:
spanInnerString = '<span class="inner"/>';
and your method like this:
$(this).wrap($spanOuter).after(spanInner);
The result is:
<span class="outer"><div class="custom"></div><span class="inner"></span></span>
<span class="outer"><div class="custom"></div><span class="inner"></span></span>
<span class="outer"><div class="custom"></div><span class="inner"></span></span>
DEMO - Passing parameter as HTML string
Off course, the same goes for the outer span. Don't create jQuery objects unless you have to.
If you must use a jQuery object because you want to attach events to the span or similar, than cloning is the way to go, though make sure you use clone(true, true) then to also clone the attached events.
You need to clone the element. Otherwise, after() will relocate the same element 3 times, which results in it being attached to only the last looped element.
$customElems.each(function () {
$(this).wrap($spanOuter).after($spanInner.clone());
});
Demo: Fiddle
You might ask, "Why would wrap() work?" That's because 'wrap()' internally clones the element.
You're moving the same span from place to place. If you acted on all three divs at once, jquery will instead clone the span.
http://jsfiddle.net/a3ZK8/1/
var $customElems = $('.custom'),
$spanOuter = $('<span class="outer"/>'),
$spanInner = $('<span class="inner"/>');
$customElems.wrap($spanOuter).after($spanInner);
From the documentation for .after:
Important: If there is more than one target element, cloned
copies of the inserted element will be created for each target except
for the last one.
which means the last element will always get the original, while all other selected elements will get a clone. That's why when you acted on one element at a time, it simply moved the same span around.

How to loop though elements based on part of the dom name

I want to hide all the elements on the page that end in _dropMenu via javascript...so this is what i have
window.onload = function() {
hideNav();
};
function hideNav(){
myArray = element("_dropMenu");// this is what need changing
for (i=0;i<=5;i++)
{
i.style.visibility = 'hidden';
}
}
This is obviously wrong but how do I first get all the elements on the page that end with _dropMenu then loop through them and set them to hidden... I would prefer javascript since I only have prototype on the page but if I need to add jquery I will...
jQuery has a selector for finding elements that have an attribute that ends with a given string:
$('[id$="_dropMenu]')
This will be faster if you can narrow it by an element type (e.g. if all the elements you care about are divs, or some such) but will work as is.
Behind the scenes, jquery is just looping through a given set of elements, and checking whether element["id"].substring(element["id"].length-"_dropMenu".length)==="_dropMenu".
Just pointing out the Prototype is very similar to jQuery in this case:
$$('[id$="_dropMenu"]').invoke('hide');
Kudos Jishnu & JacobM for getting the selector first.

How to select next 2 (or more than 2) items using jQuery .next()?

using jQuery's .next function I want to show next 2 items. By default it selects only just next item.
I need control, like sometimes I need next 2, sometime next 3
You can use .nextAll() and a :lt() selector, for example:
.nextAll(':lt(2)') //next 2
.nextAll(':lt(3)') //next 3
Try it out here. If you need it to be programmatic (instead of string concatenation) and change it easily, use .slice() instead:
.nextAll().slice(0, 2) //next 2
.nextAll().slice(0, 3) //next 3
This method allows you to pass as a parameter the number you need a bit easier. You can test it here.
If you want to select the next number of elements and include the selected element you can do something like:
$('div#myTarget').nextAll('div').andSelf().slice(0,4)
The above code returns the next 4 div elements after the div myTarget and includes the myTarget div itself.
.slice(0,4) selected the next 4 elements and .andSelf() included the original selected element
Use .nextAll instead of .next to get all following siblings, and then use .slice to narrow that down to a range.

Categories

Resources