Converting Classes All at Once - javascript

I have four classes show,hide1,hide2, and hide3. I want to change each of these classes and replace it with the one next to it. In other words, my jQuery code looks like this...
$(".show").removeClass("show").addClass("hide1");
$(".hide1").removeClass("hide1").addClass("hide2");
$(".hide2").removeClass("hide2").addClass("hide3");
$(".hide3").removeClass("hide3").addClass("show");
The problem is that the four classes end up all having the show class which is not what I want. I just want the classes of show to convert to hide1, hide1 convert into hide2, etc. How could I write the code so that those four lines all happen at once, instead of one at a time?

Just select each group first, then alter:
// read
var $show = $('.show');
var $hide1 = $('.hide1');
var $hide2 = $('.hide2');
var $hide3 = $('.hide3');
// write
$show.removeClass('show').addClass('hide1');
$hide1.removeClass('hide1').addClass('hide2');
$hide2.removeClass('hide2').addClass('hide3');
$hide3.removeClass('hide3').addClass('show');

If you save the classes in an array like this:
var classes = ['show','hide1','hide2','hide3'];
You can do fancy stuff like this:
$('.'+classes.join(',.')).attr('class', function(i) {
return classes[i+1] || classes[0];
});​
Demo: http://jsfiddle.net/7DuEV/

Do it this way,
function circulateClass(c){
var i, cl=[];
for(i=0;i<c.length;i++)
cl[c[i]]=$("."+c[i]);
for(i=0;i<c.length;i++)
cl[c[i]].removeClass(c[i]).addClass(c[(i+1)%c.length]));
}
circulateClass(["show","hide1", "hide2", "hide3"]);

Just change the order...
$(".show").removeClass("show").addClass("hide1");
$(".hide3").removeClass("hide3").addClass("show");
$(".hide2").removeClass("hide2").addClass("hide3");
And for the last one, filter by the class name:
$(".hide1").filter(function(){
return !$(this).hasClass('show');
}).removeClass("hide1").addClass("hide2");

jsBin demo
c = 0; // zero based index n (set initial one)
var $el = $( '#parent' ).find( 'div' );
$el.hide().eq( c ).show();
$( '#button' ).click( function() {
$el.hide().eq( ++c % $el.length ).show();
});

Related

use multiple image lightboxes on one page without knowing how much

I'm using a lightbox script which uses a data attribut to know which images are part of a gallery.
To initialize a gallery, I have to do the following:
var selector = 'a[data-imagelightbox="a"]';
var lightbox = $( selector ).imageLightbox({});
If I wan't another gallery on the same page I have to add another:
var selector = 'a[data-imagelightbox="b"]';
var lightbox = $( selector ).imageLightbox({});
I tried to use another selector and the .each function to get it working without writing this 2 code lines for each gallery. But it is not working. The problem is the data attribute groups all images with this attribute to one gallery. If I'm trying it without a, b, c or d - i always get one large gallery and not 3 seperate gallerys.
So, does anybody have a solution how I can use an unknown number of gallerys on one page, without having to define each gallery in Javascript?
I made a JSBIN, so it should be easier to try it out:
http://jsbin.com/goqije/1/
Thanks for your help!
Fixed it myself by doing it this way:
$('ul').each( function() {
var id = $(this).find('a').attr('data-imagelightbox');
var selector = 'a[data-imagelightbox="' + id +'"]';
var lightbox = $( selector ).imageLightbox({
quitOnDocClick: false,
onStart: function() { overlayOn(); closeButtonOn( lightbox ); arrowsOn( lightbox, selector ); },
onEnd: function() { overlayOff(); closeButtonOff(); arrowsOff(); },
onLoadStart: function() { },
onLoadEnd: function() { $( '.imagelightbox-arrow' ).css( 'display', 'block' ); }
});
});
Attribute selector maybe?
instead of doing :
var selector = 'a[data-imagelightbox="b"]';
var lightbox = $( selector ).imageLightbox({});
and
var selector = 'a[data-imagelightbox="b"]';
var lightbox = $( selector ).imageLightbox({});
Just do it with a attribute selector :
var selector = 'a[data-imagelightbox]';
var lightbox = $( selector ).imageLightbox({});
Or even better, you can use a naming convention for all the gallery data attributes as follows:
gallery-1 , galery-2 , gallery-3 and then use a attribute selector as follows:
var selector = 'a[data-imagelightbox^="gallery"]';
var lightbox = $( selector ).imageLightbox({});
Solution two
The above solution seems to have a conflict, here's a slightly different solution that leverages "naming convention" (gallery-1 , gallery-2 ... etc.) and a for loop , see this example here. Notice how I am using a for loop to iterate over all the a elements and turn their color red:
HTML code here:
One
Two
Three
jQuery code here:
$(function () {
str_elm = $('a');
for (var i = 0; i < str_elm.length ; i++) {
data_val = $(str_elm[i]).attr('data-test');
str_temp = "a[data-test=" + '"'+ data_val + '"' + "]";
$(str_temp).css({'color' : 'red'});
};
});
Fiddle here.
You can change the JS as follows to suit your needs:
$(function () {
str_elm = $('a[data-imagelightbox^="gallery"]');
for (var i = 0; i < str_elm.length ; i++) {
data_val = $(str_elm[i]).attr('data-test');
str_temp = "a[data-test=" + '"'+ data_val + '"' + "]";
$(str_temp).imageLightbox({}); // initialization here
};
});

...scrollTop($(this)...)

I have a few divs with the .class class whose scroll position is defined by another child of its parent, so I need to assign a scrollTop() with $(this), something like
$(".class").scrollTop($(this).parent().find('.child').scrollTop());
But that code doesn't work...
$(".class").scrollTop(
function(){
$(this).parent().find('.child').scrollTop()
}
);
Doesn't work either. Any clue?
This is assuming that I am reading your question right. You have mulitple "class" elements that have their own "child" elements. You would need to use each to set every element separately.
$(".class").each(
function(){
var elem = $(this);
var childsScrollPosition = elem.parent().find('.child').scrollTop();
elem.scrollTop(childsScrollPosition);
}
);
ScrollTop wants an integer for the position so passing the DOM node wont help.
Try caching your selector and pass it with the position method:
var scrollTo = $(this).parent().find('.child');
$(".class").scrollTop( scrollTo.position().top );
Or you use offset depending on your use case:
var scrollTo = $(this).parent().find('.child');
$(".class").scrollTop( scrollTo.offset().top );
I am doing this blind here but this should work too:
var scrollTo = $(this).parent().find('.child');
$(".class").scrollTop(
function() {
return scrollTo.offset().top;
}
);
Does this help?

jQuery hide inner html, except for a tags

I have the following HTML:
<div class="content-body attribute-pdf">
<a href="/_fragment/content/download/296/1935/file/blabla.pdf">
blabla.pdf</a> 1.2 Mb
</div>
This is coming out of a CMS, and I would like to hide this "1.2 MB",but still keep the A href part
is this possible to do in jQuery ?
I tried this:
$(".attribute-pdf").children().hide();
which hides the A href, but still shows the text. I want it vice-versa - hide the text, but still show the A href.
A quick way, in jQuery - empty the div, replace its contents with just the <a> tag:
$('.attribute-pdf').each(
function() {
var container = $(this);
var a = container.find('a').detach();
container.empty().append(a);
}
);
Example: http://codepen.io/paulroub/pen/iaFnK
You could set the contents of the parent to be the contents of the childeren ...
$(".attribute-pdf").each(function(){
var $this = $(this); // cache for performance
$this.html($this.children());
});
grab the content ( a link ) , empty the div ( removes 1.2 mb ) and again append a link.
http://jsfiddle.net/vpVMK/
var content = $(".attribute-pdf a");
$(".attribute-pdf").html('');
$(".attribute-pdf").append(content);
you could do:
// contents() gives children, all including non-element nodes.
// Then, we can filter those down to the final text one.
var textNodes = $( ".attribute-pdf" ).contents().filter(function() {
return this.nodeType === 3;
});
var lastTextNode = textNodes.last();
//and replace
lastTextNode.replaceWith('');
You could do this:
var children = $(".attribute-pdf").children();
$(".attribute-pdf").html(children);
http://jsfiddle.net/H2WVt/
Here is another method that hasn't been posted yet:
$(".attribute-pdf").html(function(){
var $this = $(this),
$tmp = $('<div>');
return $.makeArray( $this.children('a').map(function() {
$tmp.html(this)
return $tmp[0].innerHTML
}) ).join('')
})
The fiddle

jQuery+ PHP adding new attributes to elements with specific value

I need to create a function that will add an attribute to elements that have an attribute with specific values.
$index have values 0-10, Code is working to this point: var element = $("a[data-slide-index*='"i"']");
Firebug gives me:
Blockquote
SyntaxError: missing ) after argument list
Rest looks like that:
<script type="text/javascript">
jQuery(document).ready(function($){
for(var i=0; i<parseInt(<?php echo json_encode($index); ?>);i++){
var hoverAtt = "onHover"+i+"()";
var element = $("a[data-slide-index*='"+ i +"']");
element.next().attr("onmouseover", function(){
return hoverAtt;
});
}
})
</script>
There is jFidle example for $index=6:
http://jsfiddle.net/Fuh9P/
Edit: I changed concatenation as Sjoerd suggested but still doesn't work.
The error message is because you concatenate strings the wrong way. You have this:
var element = $("a[data-slide-index*='"i"']");
Within the $() you try to concatenate three parts, like this:
"a"i"b"
Instead, you should use something like this:
"a" + i + "b"
var element = $("a[data-slide-index*='" + i + "']");

How to set filter on div html attribute

I have some divs and one button. Divs have zozo [j] attribute .
When I click on the button, I want their id to be set, but not all divs, just those that have j > k. In fact I want to use a filter.
<div zozo="sim [0]"></div>
<div zozo="sim [1]"></div>
<div zozo="sim [2]"></div>
.
. // and some div else
.
var k = 1;
I know the below code is wrong, but I want something like this:
$("div [zozo='sim ["+ > = k + "]' ]").attr('id' , k+1);
I think you are trying to do:
$("div[zozo^=sim]" ).attr('id' , function(i){ //Use attribute startswith seletor
//return i+1; //return index + 1 as the id
return +$(this).attr('zozo').match(/(\d+)/).pop() + 1;
});
Or just set a common class name to all those elements and use class selector
$("div.myClass" ).attr('id' , function(i){ //Use attribute startswith seletor
return i+1; //return index + 1 as the id
});
Also remember that zozo is not a valid attribute, prefix it with data-* would be more appropriate.
Demo
Ok, so what you'll have to do here is iterate over each element and then do your calculations on the value of each one individually. You're talking about a selector based on some arithmetic calculation - I don't believe that exists.
Here is how I would do it:
var k = 1;
$( "div[zozo^='sim']" ).each( function(){
var value = $( this ).attr( "zozo" ).match(/(\d+)/)[1]; // remove all except the number
value = parseInt( value ); // convert it into an actual number
if ( value >= k ){
// if a condition is met - we update the attribute of the current element
$( this ).attr( "id", (value + k ) );
}
});
I'm using jquery's "attribute starts with" selector here that matches all elements that have a zozo class value that starts with the string "sim".
Note that in your example you're wanting setting the id attribute to k+1. This will always remain the same number and so you'll be setting multiple elements with the same id. You don't want to be doing that. In my example I've made sure that each id attribute is unique.
Check out this demo, you'll see that all but the first red box have their id set.
Assuming the value of data-zozo is always in the same format, and assuming I've understood your question correctly, this should work. You'd want to use a more specific selector, of course.
$('div').click(function () {
var myK = $(this).attr('data-zozo');
myK = myK.charAt(5);
myK = parseInt(myK);
if (myK >= 1) {
$(this).attr('id',myK + 1);
}
});
http://jsfiddle.net/isherwood/5g7yU/
Something like this? WARNING, UGLY CODE
$('#parentdiv > div').each(function () {
var $that = $(this);
var zozo = parseInt($that.attr('zozo').replace('sin[', '').replace(']', ''));
if (zozo >= k)
$that.id = k + 1;
});

Categories