jQuery selector - style values - javascript

I got a series of divs like this:
<div class="message" style="padding-left: 0px;">...</div>
<div class="message" style="padding-left: 20px;">...</div>
<div class="message" style="padding-left: 20px;">...</div>
<div class="message" style="padding-left: 40px;">...</div>
<div class="message" style="padding-left: 20px;">...</div>
And I would like to make a selector that would get me the divs with padding greater then 20px.
Would it be possible with just using jquery? Or I should modify my html tree and add some attribute that would distinguish those elemenents with high padding value?

You can use a filter with a custom function.
$('div.message').filter(function(){
return parseInt($(this).css('padding-left')) > 20;
});
p.s. I don't sure what .css('padding') > 20 will return, I'm guess I need to test it....

You can use filter for this.
var elems = $('div.message').filter(function (){
return parseInt($(this).css("padding-left"),10) > 20;
});
alert ( elems.length );
or using each you can do something like this
$(function(){
var elems = new Array();
$("div.message").each(function(){
if(parseInt($(this).css("paddingLeft"), 10) > 20 )
{
elems.push($(this));
}
});
alert ( elems.length );
});

You could use $('.message') selector, and then loop through your elements finding the one with .css padding-left set to anything you want.
Second solution, involves usage of custom selectors.
You can modify this code I took from my blog:
$.extend($.expr[':'], {
redOrBlue: function(o) {
return ($(o).css("color") == "red")
|| ($(o).css("color") == "blue");
}
});
Usage:
$('div:redOrBlue')

You could use filter()
var col = $('div').filter(function ()
{
return parseInt($(this).css("padding-left")) > 20;
});
or you could create your own selector:
$.expr[':'].myselector = function(obj, index, meta, stack){
return parseInt($(obj).css("padding-left")) > 20;
};
var col = $("div:myselector");

Related

Looping through html elements with the same class and finding the order of elements

I have created an image slider that has 3 images and 3 dots, each dot runs a function that loads an image, the first dot the first image etc.
Now what I'm asking is how can I create a loop for the javascript to do the same result instead of repeating myself for each button?
<span class="kcslider-dot" id="dot-1"></span>
<span class="kcslider-dot" id="dot-2"></span>
<span class="kcslider-dot" id="dot-3"></span>
$("#dot-1").click(function(){
currentSlide(1);
})
$("#dot-2").click(function(){
currentSlide(2);
})
$("#dot-3").click(function(){
currentSlide(3);
})
Another option is to use jQuery Data
<span class="kcslider-dot" data-slide-id="1" id="dot-1"></span>
<span class="kcslider-dot" data-slide-id="2" id="dot-2"></span>
<span class="kcslider-dot" data-slide-id="3" id="dot-3"></span>
$(".kcslider-dot").click(function(){
var slideId = $(this).data('slide-id');
currentSlide(slideId);
});
You can use [id^='dot-'] selector to select all the elements with id value starting with dot- then inside the click function get the numeric part after hyphen by doing split() on the idvalue:
USING jQuery
$("[id^='dot-']").click(function(){
var idNumber = this.id.split('-')[1];
currentSlide(idNumber);
});
function currentSlide(num){
console.log(num);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="kcslider-dot" id="dot-1">1</span>
<span class="kcslider-dot" id="dot-2">2</span>
<span class="kcslider-dot" id="dot-3">3</span>
USING JavaScript
var elem = document.querySelectorAll("[id^='dot-']");
for(var i=0; i<elem.length; i++){
elem[i].addEventListener('click', function(){
var idNumber = this.id.split('-')[1];
currentSlide(idNumber);
});
}
function currentSlide(num){
console.log(num);
}
<span class="kcslider-dot" id="dot-1">1</span>
<span class="kcslider-dot" id="dot-2">2</span>
<span class="kcslider-dot" id="dot-3">3</span>
You should use your class in the selector of jquery and then loop with the function "each". You can use a var that acts as counter o use an attribute in the html for get the parameter of the function "currentSlide"
var i = 1
$('span.kcslider-dot').each(function(){
currentSlide(i);
i++;
})
As long as all of your slides belong to the same class you can use class-selector instead of id. When you select all slides the output of the selection will be an array and the order will be the same as in the DOM. So after the selection you just may loop through that array and add listener to each element separately specifying certain slide using index:
let sliders = $(".kcslider-dot");
for(let i = 0; i < sliders.length; i++) {
sliders[i].click( () => {
currentSlide(i+1);
})
}
Cheers.
If the span elements are the only children of their parent you could use the jQuery .index() function to load the corresponding image.
Also you can attach the click event to the class instead of the id. That way you only need a single event handler.
e.g.
function currentSlide(index) {
console.log(index);
}
$(".kcslider-dot").click(function() {
currentSlide($(this).index() + 1);
});
.kcslider-dot {
display: inline-block;
width: 15px;
height: 15px;
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="kcslider-dot" id="dot-1"></span>
<span class="kcslider-dot" id="dot-2"></span>
<span class="kcslider-dot" id="dot-3"></span>
</div>
You can use .each() of jQuery, it takes index as param. Then you just pass the index to the currentSlide() into the clicked context.
$('.kcslider-dot').each(function(index) {
$(this).click(function() {
currentSlide(index + 1);
})
})

How to show a specific amount of child divs?

I am not sure if this is possible...
If you have f.ex.
<div id="parent">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3"></div>
<div id="child4"></div>
<div id="child5"></div>
<div id="child6"></div>
</div>
How could you, with jquery or javascript (or anything for that matter), just show the first two?
You can use :gt() jQuery selector.
$("#parent>div:gt(1)").hide()
Actually, if you want to show incrementally, it is better to hide everything first and then use :lt() jQuery selector to show.
$("#parent>div").hide();
var n = 2;
$("#parent>div:lt(" + n + ")").show();
el.click(function () {
n += 5;
$("#parent>div:lt(" + n + ")").show();
});
You can do this with CSS:
#parent div:nth-child(n+3) {
display: none;
}
https://developer.mozilla.org/en-US/docs/Web/CSS/%3Anth-child
JsFiddle
Here's a way you could do it in jQuery:
// hide all the children
$("#parent>div").hide();
// unhide the two we care about
$("#child1").show();
$("#child2").show();
If you don't have known IDs for your elements, here's a more general solution:
$("#parent>div~div~div").hide();
You could write jQuery code like so:
var visibleIndexes = [0, 1]
$("#parent").children().each(function(index) {
if(visibleIndexes.indexOf(index) === -1){
$(this).hide();
} else {
$(this).show();
}
});
You can store indexes which you want to show in variable visibleIndexes or any other variable and pass it to this function
A simple iterative approach:
$( document ).ready(function() {
var i = 0;
var somevalue = 3;
$("#parent").children("div").each(
function () {
if(i > somevalue) $(this).hide();
i++;
});
});

How do I search nested divs using regex for class names

I want to search for nested divs like these in my DOM
<div class="two-columns some-other-class">
<div class="two-columns some-other-class">
</div>
</div>
I tried to search nested divs like this
$("div[class$='columns'] div[class$='columns']")
but it's not working :(
Use the Attribute Contains Selector:
$("div[class*='columns'] div[class*='columns']")
Edit:
If you want that exact functionality you might want to extend the jQuery selector engine:
$.extend($.expr[':'], {
classEndsWith: function(e, i, meta) {
var found = false
var classes = e.className.toLowerCase().split(' ');
var suffix = meta[3].toLowerCase();
$.each(classes, function(i, c) {
// Check if className ends with value in suffix
if (c.indexOf(suffix, c.length - suffix.length) !== -1) {
found = true;
return false;
}
});
return found;
}
});
var element = $('div:classEndsWith(columns) div:classEndsWith(columns)');
See JSFiddle.
$("div[class$='columns'] div[class$='columns']")
Is working. Check the fiddle

How to cycle through siblings using jQuery?

I have the folowing code:
html:
<div class="container">
<div class="selected">A</div>
<div>B</div>
<div>C</div>
<div>D</div>
</div>
<button id="next">next!</button>
jQuery:
$("#next").click(function() {
$(".selected").removeClass("selected").next().addClass("selected");
});
What i want is loop through the divs in the container. I can do this to cycle:
$("#next").click(function() {
if ($(".selected").next().length == 0) {
$(".selected").removeClass("selected").siblings(":nth-child(1)").addClass("selected");
}
else {
$(".selected").removeClass("selected").next().addClass("selected");
}
});
But i think there is a simpler way. How can i make it simpler ? (I don't mind if you don't use the next() function).
jsFiddle: http://jsfiddle.net/S28uC/
I 'd prefer siblings.first() instead of siblings(":nth-child(1)"), but in essence you won't be able to wrap around without using some variant of next().length.
Update: If I were writing this from scratch, this is how I 'd do it:
$("#next").click(function() {
var $selected = $(".selected").removeClass("selected");
var divs = $selected.parent().children();
divs.eq((divs.index($selected) + 1) % divs.length).addClass("selected");
});
This approach is motivated by two factors:
When you want to cycle over a collection indefinitely, modulo comes to mind
Getting rid of the if makes for smarter-looking code
When setting the value of divs I preferred $selected.parent().children() over the equivalent $selected.siblings().add($selected) as a matter of taste -- there are practically endless possibilities.
One simple way is this :
$("#container").find("div:eq(0)").addClass("selected");
how about this.
...
var selected = $(".selected").removeClass("selected");
if (jQuery(selected).next().addClass("selected").length == 0
{jQuery(selected).siblings().first().addClass("selected");};
...
In old good AI manner you try to do the deed (addClass), if it worked (length <> 0) nothing more to do, otherwise you try again on the first of the siblings.
You can try this
var cont = $('.container'),
i = 0;
$("#next").on('click', function() {
cont.children().removeClass('selected');
i += 1;
if ( i === document.querySelectorAll('.container div').length ) { i = 0; }
cont.children().eq(i).addClass('selected');
});
var cont = $('.container'),
i = 0;
$("#next").on('click', function() {
cont.children().removeClass('selected');
// increase index for each click
i += 1;
// reset i if it reached to last index
//(hack to force next to go back to first element when we are at the end)
if ( i === document.querySelectorAll('.container div').length ) {
i = 0;
}
cont.children().eq(i).addClass('selected');
});
.selected {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="selected">A</div>
<div>B</div>
<div>C</div>
<div>D</div>
</div>
<button id="next">next!</button>
simply you will increase i for each click and when it reach the end (divs length ) it will be reset.

javascript only - how to filter a specific div class?

I have many DIVs, let's say 100, split by categories like that :
<div id="div1" class="cat01">text</div>
<div id="div2" class="cat02">text</div>
<div id="div3" class="cat01">text</div>
<div id="div4" class="cat02">text</div>
<div id="div5" class="cat03">text</div>
<div id="div6" class="cat01">text</div>
And I want to filter a specific class
Let's say I click on a button "filter only cat02"
I then have only this on the page :
<div id="div2" class="cat02">text</div>
<div id="div4" class="cat02">text</div>
I do not have to use a class to define the categories, but it seems the appropriate solution...
Thanks you VERY much for your help!
EDIT : much clearer
Here is the file :
<div id="principal">
<div class="abc1 categ1">Text0</div>
<div class="abc5 categ3">Text0</div>
<div class="abc4 categ2">Text1</div>
<div class="abc7 categ1">Text0</div>
<div class="abc2 categ2">Text2</div>
<div class="abc4 categ3">Text0</div>
<div class="abc6 categ1">Text0</div>
<div class="abc7 categ2">Text3</div>
</div>
and I want this :
Text1
Text2
Text3
You can do something like this:
var list = document.getElementsByClassName('cat02');
for (var i = 0; i < list.length; i++) {
// this will remove the node from the page
list[i].parentNode.removeChild(list[i]);
// if you just want to hide it, you can do this:
// list[i].style.display = 'none';
}
Note that getElementsByClassName isn't supported by most browsers -- for those that don't, you may have to use a custom implementation such as the one here.
Update: If all your DIVs are direct children of a single DIV and they each contain only one class, it makes the task much simpler. You can skip getElementsByClassName and instead just iterate over the children:
function showOnly(parent, className) {
className = ' ' + className + ' ';
var e = parent.firstChild;
while (e != null) {
if (e.nodeType == 1) {
if ((' ' + e.className + ' ').indexOf(className) > -1)
e.style.display = 'block';
else
e.style.display = 'none';
}
e = e.nextSibling;
}
}
showOnly(document.getElementById('masterdiv'), 'cat02');
Edit: There were a couple of errors previously that I've fixed now. The indexOf comparison should be > -1 instead of > 0 and also the list of children includes empty text nodes (spaces between tags) that should be ignored, hence the check for e.nodeType == 1.
Seem like jQuery would help a lot here. You could just call $("div[class!='class02']") and get an array of items you want. Then, you could call .addClass('hidden') or whatever you need to do to the other items.
A brute force solution:
var list = document.getElementsByTagName('div');
for (var i = 0; i < list.length; i++) {
if (list[i].className != 'cat02') {
list{i].style.display = 'hidden';
}
}
Wrap this in a function to something like this:
function filterDivs(nameToFilter) {
var list = document.getElementsByTagName('div');
for (var i = 0; i < list.length; i++) {
if (!contains(list[i].className.split(' '), nameToFilter)) {
list{i].style.display = 'hidden';
}
}
}
EDIT:
using this function to search for strings in an array that I found here
function contains(a, obj) {
var i = a.length;
while (i--) {
if (a[i] === obj) {
return true;
}
}
return false;
}
With only 100 divs, it should run pretty quickly, but if you increase this amount a lot, it will become slow.
I also recommend that you don't remove items from a collection while iterating through it, that will cause you trouble. Hide them instead, or work with different collections.

Categories

Resources