I have some jQuery animations in my code to slide divs up and down in response to some mouse clicks and other logic. This is all working just peachy, however in IE 6 some of the smaller icon images on the page don't slide along with the rest of the div for some strange reason. They kind of stay put then flicker into the new position and I've chalked this up to an IE6 'feature'.
Considering that I have to support IE6, I wanted to just hide the icons anytime an animation started, and show them again when the queue was empty.
I couldn't find a reference to any kind of events or hooks into the queue itself and I'd rather not add the hide code, then the show code to every animation as a callback.
Thanks if you can help-
b
Probable cause for IE6 goofiness: hasLayout. http://www.satzansatz.de/cssd/onhavinglayout.html
Try adding zoom: 1 to the css of the images.
You can do this with the livequery plugin like so:
$(':animated').livequery(function() {
// firing code here
}, function() {
// anything you want to run when all animation stops
});
This type of functionality is the only reason that the livequery plugin is still useful actually, since otherwise its functionality has been replaced by live() and delegate()
And since this only happens in IE6, it would be silly to hide them in all browsers, so in the firing function you can add a class with an IE6 hack like .hide4IE6 { _display:none; } to let them remain shown in other browsers.
Does it do the same in IE7? Is the div or icon relative positioned?
Related
I have this animation setup to indicate which SVG was selected. The animation adds a svg:use element, and 3 animate or animateTransform elements within the svg:use element. Thanks to some great help here on SO I was able to get this working properly.
My new problem however is that the animation only works once as designed once. If a second element is selected, the animation appears to try to take place, as you can see the stroke-width increase, but the scale doesn't happen.
I thought this would be a simple fix by using a setTimeout to call a function and remove the svg:use after the animation completed. I wasn't so lucky.
An example of my problem can be seen here: http://codepen.io/JoeyCinAZ/pen/GHhbw
The function I wrote to remove the animation is here
setTimeout( function() {removeAnimation(objID)}, 5000);
function removeAnimation(objID) {
var useEl = document.getElementById(objID);
useEl.nextSibling.remove();
}
You've two issues within the animation. The simplest is duration, it can't per the SVG specification begin with a . so
flash.setAttributeNS(null, 'dur', '.5s');
is strictly speaking not valid and Firefox rejects it. I believe there are plans to change the SVG specification to match Chrome's laxer behaviour but until that happens write it as
flash.setAttributeNS(null, 'dur', '0.5s');
Secondly your main issue is that once you run the animation the document timeline goes from 0 to 5.5 seconds (that's how long all your animations take). The next time you create the animation, the document timeline is therefore at 5.5 seconds and the initial animation doesn't run because it's in the past as it's supposed to start at 0s. You could solve this either by
a) calling setCurrentTime to reset the timeline to 0, or
b) having the initial animation trigger from the button press event.
I had a similar issue before and solved it by completely removing the content of the element that contains the generated SVG, and then simply reload the new SVG in the empty element.
Instead of using a setTimeout which make the whole thing a bit weird, I would simply call it on clicking the element selector:
var elem = document.getElementById('myElementSelector');
elem.addEventListener('click', function() {
document.getElementById(surroundingElementID).innerHTML = "";
//Check what has been clicked and call function that creates the SVG on the surroundingElementID
}, false);
Background:
I'm making a portfolio site utilising both Swipe.js and Infinite Ajax Scroll (JQ).
Problem:
When the content from extra pages is loaded into the current page, it is not processed by the already-loaded Swipe.js script. This means that the new content doesn't have it's mark-up changed (needed for the swipe functionality to work).
I think I need to get the Swipe.js script to fire after each page re-load. Would that fix it? Please explain this to me like I'm an 8yr old. JS is not a strong suit...
Demo:
http://hatchcreative.co.nz/tomo
You can see that as the page loads new content, the buttons on either side of the sliders no longer work.
Yes you're right, after the images are loaded you have to create a new Swipe instance on these new elements (as they weren't there at the beginning, when the page was loaded).
Based on the docs of infinite scroll you can use onRenderComplete.
So you had your jQuery.ias constructor like this:
jQuery.ias({
// ... your settings...
onRenderComplete: function(items) {
$(items).each(function(index, element) {
new Swipe(element);
});
}
});
This should work this way somehow, but I am not exactly sure; I haven't worked with these libraries yet.
Edit:
After some more inspection of your code, I saw you had some inline click handler like: onclick='two.prev();return false;'.
You need to remove this and add your onclick handle in the same onRenderComplete function.
onRenderComplete: function(items) {
var swipe;
$(items).each(function(index, element) {
swipe = new Swipe(element);
});
// find tags with the class 'forward' inside the current element and add the handler
$(element).find('.forward').on('click', function() {
swipe.next();
});
// ... also for previous
}
By the way: Usually you should provide a jsFiddle with your important code parts, so it's easier for us to get the problem, and the question is not getting obsolote when the linked page changes.
I'm trying to do a simple slide out effect, then add a class with display:none;
But for some reason, the jQuery animation is completing instantly, instead of using the duration as the docs say. I tried using different values, and 'slow' / 'fast'.
Looking at the source in Chrome's developer tools, the DOM is updated instantly. Removing the callback doesn't make the animation work either, it just does nothing in that case.
$('.type-panel').slideDown(500, function () {
$(this).addClass('panel-hidden')
});
<div class="ed-panel type-panel">
//bunch of stuff
</div>
What am I missing?
(I have jQuery and jQueryUI referenced)
I think you meant to use .slideUp() to hide it.
$('.type-panel').slideUp(500, function() {
$(this).addClass('panel-hidden');
});
Notice, .slideUp() will add automatically set the display to none.
I have a long jQuery mobile page and would like to scroll to an element halfway down this page after the page loads.
So far I've tried a few things, the most successful being:
jQuery(document).bind("mobileinit", function() {
var target;
// if there's an element with id 'current_user'
if ($("#current_user").length > 0) {
// find this element's offset position
target = $("#current_user").get(0).offsetTop;
// scroll the page to that position
return $.mobile.silentScroll(target);
}
});
This works but then the page position is reset when the DOM is fully loaded. Can anyone suggest a better approach?
Thanks
A bit late, but I think I have a reliable solution with no need for setTimeout(). After a quick look into the code, it seems that JQM 1.2.0 issues a silentScroll(0) on window.load for chromeless viewport on iOS. See jquery.mobile-1.2.0.js, line 9145:
// window load event
// hide iOS browser chrome on load
$window.load( $.mobile.silentScroll );
What happens is that this conflicts with applicative calls to silentScroll(). Called too early, the framework scrolls back to top. Called too late, the UI flashes.
The solution is to bind a one-shot handler to the 'silentscroll' event that calls window.scrollTo() directly (silentScroll() is little more than an asynchronous window.scrollTo() anyway). That way, we capture the first JQM-issued silentScroll(0) and scroll to our position immediately.
For example, here is the code I use for deep linking to named elements (be sure to disable ajax load on inbound links with data-ajax="false"). Known anchor names are #unread and #p<ID>. The header is fixed and uses the #header ID.
$(document).bind('pageshow',function(e) {
var $anchor;
console.log("location.hash="+location.hash);
if (location.hash == "#unread" || location.hash.substr(0,2) == "#p") {
// Use anchor name as ID for the element to scroll to.
$anchor = $(location.hash);
}
if ($anchor) {
// Get y pos of anchor element.
var pos = $anchor.offset().top;
// Our header is fixed so offset pos by height.
pos -= $('#header').outerHeight();
// Don't use silentScroll() as it interferes with the automatic
// silentScroll(0) call done by JQM on page load. Instead, register
// a one-shot 'silentscroll' handler that performs a plain
// window.scrollTo() afterward.
$(document).bind('silentscroll',function(e,data) {
$(this).unbind(e);
window.scrollTo(0, pos);
});
}
});
No more UI flashes, and it seems to work reliably.
The event you're looking for is "pageshow".
I was digging a lot this issue, also at jQuery mobile official forum.
Currently it seems that there is no solution (at least for me).
I tried different events (mobileinit, pageshow) and different functions (silentscroll, scrolltop) as suggested above, but, as a result, I always have page scrolled until all images and html is finished loading, when page is scrolled to top again!
Partial and not really efficient solution is using a timer as suggested in comment to sgliser's answer; unfortunately with a timeout is difficult to know when page will be fully loaded and if scroll happened before that, it will scroll back to top at the end of load, while if it happens too long after page has fully loaded, the user is already scrolling page manually, and further automated scroll will create confusion.
Additionally, would be useful to have silentscroll or other function to address a specific id or class and not plain pixels, because with different browsers, resolutions and devices it may give different and not correct positioning of the scroll.
Hope someone will find a smarter and more efficient solution than this.
I have a web interface to a system which has a left navigation. On the navigation, I can expand/collapse some menus. I use jQuery slideUp/slideDown to animate them like this:
if (enable)
{
navbar_slide_down = true;
$j(l1_folder).slideDown("normal", function() {
navbar_slide_down = false;
on_navbar_animation_complete();
});
}
else
{
navbar_slide_up = true;
$j(l1_folder).slideUp("normal", function() {
navbar_slide_up = false;
on_navbar_animation_complete();
});
}
Both animations run simultaneously to provide an accordion-like effect. This works in nearly all cases.
The problem I'm encountering now is that after performing some actions in a content frame (not the same frame as the navigation), the slideDown and slideUp functions no longer work. The animations start, but stop nearly immediately, and the callback is never fired. This causes the menu to lockup. I can only reproduce this issue in FireFox 3.5.7 (other versions seem OK). If I turn on Firebug, the problem doesn't occur.
I've tried upgrading from jQuery 1.3.2 to 1.4.1, no luck.
Is there any reason the animations would fail and not call the callback? How can I debug this with an unminified jQuery?
The problem was sequence dependent (ie: click on this, and then that, and the hang will occur). I found the problem in the first page:
addEvent(window, 'unload', end_page);
And changed it to:
addEvent(window, 'onbeforeunload', end_page);
I'm still not sure why this would effect the outer frame (and cause jQuery animations to break), but my best guess is that code in the unload handler was running on the second page and conflicting somewhere.