Okay. So I've got a a little jQuery gallery scroller I wrote to work with WordPress. It works beautifully in Firefox, but it doesn't work in Chrome or Safari.
Here's the link:
http://thehousinggroup.info/our-gallery/bathroom-renovations/gallery-1/
Here's the jQuery:
var imageQuantity = $('.galleryBox img').size() //finds the number of images
var wrapWidth = imageQuantity * 610 + 'px' //sets inner wrapper to image width*no. of images
//Formating
$('.galleryBox img')
.hide()
.unwrap()
.wrapAll('<ul></ul>')
.wrapAll('<div id="innerWrap"></div>')
.wrap('<li></li>');//wraps images in ul and div, strips off the <p> that WordPress adds
$('#innerWrap').css({
'width' : wrapWidth,
'position' : 'relative'
});
$('.galleryBox').css({'overflow' : 'hidden'}); //this css will be relegated to the stylesheet eventually...
$('.galleryBox ul').css({'list-style' : 'none'});
$('.galleryBox li').css({
'float' : 'left',
'margin-right' : '10px'
});
$('.galleryBox img').show(); //shows the images once the formatting is complete
//Scroll Controls
var currentNumber = 1; //this is for the "1 of 4" counter
var fullNumber = imageQuantity;
$('#innerWrap').before('<p id="scroller"><a id="prevButton" href="">previous</a> <span id="currentNumber">' + currentNumber + '</span> of ' + fullNumber +' <a id="nextButton" href="#">next</a></p>'); //this places the next, previous, and 1 of # counter buttons
$('#nextButton').click(function(event){
event.preventDefault();
var wrapPosition = parseInt($('#innerWrap').css('right'));
var stopPoint = (fullNumber-1)*610;
if(wrapPosition < stopPoint) { //sets the scrolling to stop at last image
$('#innerWrap').animate({'right' : "+=610px"});
++currentNumber;
$('#currentNumber').empty().html(currentNumber); //sets the counter to the proper number
}
});
$('#prevButton').click(function(event){ //same as above, reversed out for the previous button
event.preventDefault();
var wrapPosition = parseInt($('#innerWrap').css('right'));
var stopPoint = (fullNumber-1)*610;
if(wrapPosition > 0) {
$('#innerWrap').animate({'right' : "-=610px"});
--currentNumber;
$('#currentNumber').empty().html(currentNumber);
}
});
I'm going to be setting the css to be in the stylesheets, but this is how it's set up for now. If you've got any further critiques, I'm open!
Thanks.
This line catches my attention:
$('#innerWrap').animate({'right' : "-=610px"});
Specially because there is no "right" property initially set up on WebKit.
Try to have the calculation done one step above:
right_pos = doTheMathHere;
$('#innerWrap').animate({'right' : rigt_pos});
This code is breaking in Chrome : var wrapPosition = parseInt($('#innerWrap').css('right'));
So it's skipping over this block:
if(wrapPosition < stopPoint) {
$('#innerWrap').animate({'right' : "+=610px"});
++currentNumber;
$('#currentNumber').empty().html(currentNumber);
}
Sorry to answer my own question
I think I figured it out. It has to do with the wrapAll() order. I intended for the <ul> to be wrapped inside the <div>, but the opposite is happening. This isn't a problem with Webkit. It's more one of those..."wait...why does this work in Firefox" sorts of issues.
Related
Here's code link: jsfiddle demo
HTML CODE:
<div class="first">
<!-- Part one -->
<div class="acord_col">
<div class="img_class" id="exist_site"></div>
<div class="intro_text">
</div>
</div>
</div>
<div class='total_cost'>
<h1>Your Total Cost is: $<span class="cost_number">0</span><span class="cost_per_page no_display"> + 50/Page</span></h1>
</div>
Javascript
jQuery(document).ready(function() {
var total_price = 0;
jQuery("#exist_site").click(function() {
var bg = jQuery(this).css('background');
var check_string = 'yes.png';
if (bg.indexOf(check_string) > -1) {
jQuery(this).css({
'background': 'url("http://www.itechinstant.com/wp-content/uploads/2014/06/home.png")',
'background-size': 'cover'
})
total_price -= 200;
jQuery('.cost_number').empty().append(total_price);
jQuery("#exist_site").hover(function() {
jQuery(this).css({
'background': 'url("http://www.itechinstant.com/wp-content/uploads/2014/06/home_h.png)',
'background-size' : 'cover'
})
})
// Change the status of detected value
var boolean_next = parseInt(jQuery('.boolean_goNext').text());
boolean_next -= 1;
jQuery('.boolean_goNext').empty().append(boolean_next);
} else {
jQuery(this).css({
'background': 'url("http://www.itechinstant.com/wp-content/uploads/2014/06/yes.png")',
'background-size': 'cover'
})
total_price += 200;
jQuery('.cost_number').empty().append(total_price);
// Change the status of detected value
var boolean_next = parseInt(jQuery('.boolean_goNext').text());
boolean_next += 1;
jQuery('.boolean_goNext').empty().append(boolean_next);
}
})
})
I was actually coding a price system using jquery.
The question is it works fine in google chrome. But not in firefox and IE11.
When I click the cycle, it should increase the cost, and click again it should deselect the cycle and minus the same cost. It all works fine in chrome. But why in firefox and IE11 the cost keep increasing no matter how many times I click?
If you read the .css() jQuery doc it says:
Retrieval of shorthand CSS properties (e.g., margin, background,
border), although functional with some browsers, is not guaranteed.
What we could do is, check for the background-image property.
var bg = jQuery(this).css('background-image');
Updated Fiddle
I need to have 2 of these one page but each with different percentages. When I try re-writing the JS or even use different class/ID names it still always pulls from the first SPAN.
http://jsfiddle.net/K62Ra/
<div class="container">
<div class="bw"></div>
<div class="show"></div>
<div id="bar" data-total="100">
<div class="text">Currently at <br/><span>70</span><br><i>Click To Give</div>
</div>
JS and CSS in the Fiddle.
Much Thanks.
This one will work smoothly:
http://jsfiddle.net/K62Ra/7/
$('.bar').each(function() {
var percentStart = 0;
var total = $(this).data('total');
var percent = parseInt($(this).find('span').html());
$(this).find('> div').addClass("load");
var that = this;
var timer = setInterval(function() {
$(that).siblings('.show').css('height', percentStart/total*100+'%');
$(that).css('height', percentStart/total*100+'%');
$(that).find('span').html('%'+percentStart);
if(percentStart<percent) { percentStart=percentStart+1; return; }
clearInterval(timer);
}, 35);
});
The interval has to be terminated as well, or it will run infinitely (though not doing anything).
I've changed your id="bar" into a class. Then I'm running a each loop for the .bar classes. here is the fiddle: http://jsfiddle.net/K62Ra/3/
here is the code:
$('.bar').each(function (index, element) {
percent = $(this).find('span').html();
total = $(this).attr('data-total');
percentStart = 0;
setInterval(function () {
$('.show').css('height', percentStart / total * 100 + '%');
$(this).css('height', percentStart / total * 100 + '%');
$(this).find('span').html('%' + percentStart);
if (percentStart < percent) {
percentStart = percentStart + 1;
}
}, 35);
});
$(".bar div").addClass("load");
Like some of the comments have stated, having duplicate ids is bad design and can cause some weird errors.
You can find a solution to your problem by changing a number of things. One, instead of
referring to divs in you selectors by id'#', you can infer them by class '.' like
$('.bar')
The next step would be to ensure exclusivity for each div with class 'container' by using a closure
$('.container').each(function(){
var x
var y
.
.
});
And finally, avoid 'selecting' elements in the selector directly, but use $(this) and .find() to ensure you are within the current div with class 'container'.
http://jsfiddle.net/K62Ra/5/
$('.container').each(function(){
var percent = $(this).find('div.bar div span').html();
var total = $(this).find('div.bar').attr('data-total');
var percentStart = 0;
var that = $(this);
setInterval(function() {
that.find('.show').css('height',percentStart/total*100+'%');
that.find('div.bar').css('height',percentStart/total*100+'%');
that.find('div.bar div span').html('%'+percentStart);
if(percentStart<percent) {percentStart=percentStart+1;}
},35);
$(this).find("div.bar div").addClass("load");
});
There are already several good answers here. I would recommend validating your html. Also some of your css was causing weirdness when there was scrolling involved (fixed background images weren't scrolling.)
I took a slightly different approach than everyone else. Instead of using a setInterval I went with $.animate and a step function. Like others, I chose a class to target each of the items: 'fill-me-up'.
Fiddle: http://jsfiddle.net/LFbKs/6/
NOTE: Check the fiddle since I modified the HTML (very slightly) and the css to a larger degree.
// for each item we need to "fill up"
$('.fill-me-up').each(function(){
// cache DOM references
var this$ = $(this)
, bar$ = this$.find('.bar')
, show$ = this$.find('.show')
, span$ = bar$.find('div span')
// the target percentage height for this item
, p = span$.text()
// combine '.bar' and '.show' so we can apply the animation to both
, toAnimate = $().add(bar$).add(show$);
// add class causing fade-in
bar$.find('div').addClass('is-visible');
// animate height to target height over 2 seconds and
// at each step, update the span with a truncated value
toAnimate.animate(
{ height: p+'%' },
{
duration: 2000,
step: function( currentStep ) {
span$.html('%'+currentStep.toFixed(0));
}
}
);
});
Cheers
I've got a number of divs (CSS class 'group'), and when one is clicked in, the others are hidden and the clicked on one is expanded (gaining the 'detailed' CSS class). Then, when the expanded div ('.group .detailed) is clicked on, it should resize and lose the 'detailed' class. My problem is, I can't get click events on 'group' divs that also contain 'detailed' to be ignored by my first jquery function and activate my second jquery function. Here's my code:
$('.group:not(.detailed)').mousedown(function(){
var $self = $(this);
var speed = 3250;
var offset = {x : $self.offset().left, y : $self.offset().top};
readyAnimation();
$('.group').not($self).addClass('hide');
$self.animate({'width' : '100%', 'height' : '+=' + '300px'}, {left: 'offset.x' + 'px', top: 'offset.y' + 'px'}, speed);
function readyAnimation () {
$self.css({display : 'block'});
$self.css({'-webkit-box-sizing' : 'border-box', '-moz-box-sizing' : 'border-box', 'box-sizing' : 'border-box'});
$self.css({margin : '0px'});
};
$self.addClass('detailed');
});
$('.group.detailed').mousedown(function(){
var $self = $(this);
var size = '300px';
var speed = 3250;
console.log("it worked");
resetAnimation();
$self.animate({'width' : size, 'height' : size}, speed)
$('.group').removeClass('hide');
function resetAnimation () {
$self.css({display : ''}); //Empty quotes resets the CSS value to what it was originally (in the CSS file)
$self.css({'-webkit-box-sizing' : '', '-moz-box-sizing' : '', 'box-sizing' : ''});
$self.css({margin : ''});
};
$self.removeClass('detailed');
});
I don't think I need to post my HTML and CSS for this, but they can be seen here in a previous question I asked. Thanks for reading.
EDIT: Here's a link to the fiddle
EDIT 2: See vahapwns, Jonathan and giordanolima's answers for working demonstrations of the code. By combining the two functions togother and using an if statement checking for 'detailed', problems arising from the first function overriding the second are solved. Thanks everybody for your input.
take your two jQuery selections and merge them into one, use an if() to check if it's .detailed or not. you should also move those extra functions outside so that they're only defined once each.
i have rearranged the logic for you, now you need to fine tune the animation sequence: http://jsfiddle.net/V93dq/2/
#vahanpwns is correct, try this one:
http://jsfiddle.net/V93dq/1/
Basically you can use the hasClass jQuery method.
$('.group').mousedown(function(){
var $self = $(this);
if($self.hasClass("detailed")){
}else{
}
});
Take a look here...
I used the condition hassClass... I think was better... And i prevent the link Default...
Finddle
function readyAnimation (mySelf) {
mySelf.css({display : 'block'});
mySelf.css({'-webkit-box-sizing' : 'border-box', '-moz-box-sizing' : 'border-box', 'box-sizing' : 'border-box'});
mySelf.css({margin : '0px'});
};
function resetAnimation (mySelf) {
mySelf.css({display : ''});
mySelf.css({'-webkit-box-sizing' : '', '-moz-box-sizing' : '', 'box-sizing' : ''});
mySelf.css({margin : ''});
};
$('.group').mousedown(function(){
if(!$(this).hasClass("detailed")){
var $self = $(this);
var speed = 3250;
var offset = {x : $self.offset().left, y : $self.offset().top};
readyAnimation($self);
$('.group').not($self).addClass('hide');
$self.animate({'width' : '100%', 'height' : '+=' + '300px'}, {left: 'offset.x' + 'px', top: 'offset.y' + 'px'}, speed);
$self.addClass('detailed');
}else{
var $self = $(this);
var size = '300px';
var speed = 3250;
resetAnimation($self);
$self.animate({'width' : size, 'height' : size}, speed)
$('.group').removeClass('hide');
$self.removeClass('detailed');
}
}).find('a').click(function(e){e.preventDefault();});;
I am looking for some native JavaScript, or jQuery plugin, that meets the following specification.
Sequentially moves over a set of images (ul/li)
Continuous movement, not paging
Appears infinite, seamlessly restarts at beginning
Ability to pause on hover
Requires no or minimal additional plugins
I realize this sounds simple enough. But I have looked over the web and tried Cycle and jCarousel/Lite with no luck. I feel like one should exist and wanted to pose the question before writing my own.
Any direction is appreciated. Thanks.
you should check out Nivo Slider, I think with the right configuration you can it to do what you want.
You can do that with the jQuery roundabout plugin.
http://fredhq.com/projects/roundabout/
It might require another plugin.
Both answers by MoDFoX and GSto are good. Usually I would use one of these, but these plugins didn't meet the all the requirements. In the end this was pretty basic, so I just wrote my own. I have included the JavaScript below. Essentially it clones an element on the page, presumably a ul and appends it to the parent container. This in effect allows for continuous scrolling, right to left, by moving the element left and then appending it once out of view. Of course you may need to tweak this code depending on your CSS.
// global to store interval reference
var slider_interval = null;
var slider_width = 0;
var overflow = 0;
prepare_slider = function() {
var container = $('.sliderGallery');
if (container.length == 0) {
// no gallery
return false;
}
// add hover event to pause slider
container.hover(function() {clearInterval(slider_interval);}, function() {slider_interval = setInterval("slideleft()", 30);});
// set container styles since we are absolutely positioning elements
var ul = container.children('ul');
container.css('height', ul.outerHeight(true) + 'px');
container.css('overflow', 'hidden')
// set width and overflow of slider
slider_width = ul.width();
overflow = -1 * (slider_width + 10);
// set first slider attributes
ul.attr('id', 'slider1');
ul.css({"position": "absolute", "left": 0, "top": 0});
// clone second slider
var ul_copy = ul.clone();
// set second slider attributes
ul.attr('id', 'slider2');
ul_copy.css("left", slider_width + "px");
container.append(ul_copy);
// start time interval
slider_interval = setInterval("slideleft()", 30);
}
function slideleft() {
var copyspeed = 1;
var slider1 = $('#slider1');
var slider2 = $('#slider2');
slider1_position = parseInt(slider1.css('left'));
slider2_position = parseInt(slider2.css('left'));
// cross fade the sliders
if (slider1_position > overflow) {
slider1.css("left", (slider1_position - copyspeed) + "px");
}
else {
slider1.css("left", (slider2_position + slider_width) + "px");
}
if (slider2_position > overflow) {
slider2.css("left", (slider2_position - copyspeed) + "px");
}
else {
slider2.css("left", (slider1_position + slider_width) + "px");
}
}
Im trying to build sort of slide where when click on link ".animate" will change it position ( every time 100px more)
This:
$(function(){
$('#m-main').click(function(){
$('slide').animate({top : "100px"}, {duration:500})
})
});
will work only once.
How can I make this working?
Many thanks for your help.
$(function() {
$('#m-main').click(function(){
$(this).data($(this).data('pos') + 100);
$('slide').animate({top : $(this).data('pos') + 'px'}, {duration:500})
})
});
When it runs it sets the top padding to 100px, so after the first time it's just setting it to the same value it already has. You need to increment the value each time.
$(function(){
$('#m-main').click(function(){
var current = $('slide').css('top');
current = current + 100;
$('slide').animate({top : current+"px"}, {duration:500})
})
});
code above untested
Try using a counter instead of just top : "100px". It is just doing it once because essentially your setting top to 100px and then setting top to 100px again which is just keeping it where it is. You want it to move to 200px and then to 300px, etc.
Try this:
var fromTop = 100;
$(function() {
fromTop = fromTop + 100;
$('#m-main').click(function() {
$('slide').animate({top : '"' + fromTop + 'px"'}, {duration:500})
})
});
It looks like you've got some error in the query string in the click handler. $('slide') will select all <slide> elements, which I assume you have none, perhaps $('.slide') or $('#slide') is what you're after?
If you just keep a reference of the position you'd like the element to move to and increase that by 100 each time (see chaos's answer) then you should be right.
$(function(){
var pos=100;
$('#m-main').click(function(){
$('slide').animate({top : pos+'px'}, {duration:500});
pos=pos+100;
});
});
Try this:
$('#m-main').click(function(){
var slide = $('.slide', this),
posY = parseInt(slide.css("background-position").split(" ")[1]);
slide.stop().animate({backgroundPosition: "0 "+(Math.ceil(posY/100)*100 + 100)+"px"}, {duration:500});
});