Strange Javascript Behavior IE8 with Jquery and Animations - javascript

I am working on a project right now that uses an accordion style menu, but I think this is more of a general question reguarding IE8 and Jquery .animate(). For some reason, even though the animations seem like the are completed (tested with callback functions) what is showing on the screen is incomplete. It seems like it's completing because whenever I use the browser zoom in and out, try highlighting the region, or other similar things to cause a change in appearence it corrects itself (ie the end result of the animation is shown). I have tested in the latest version of Chrome and the animation looks perfect, so it is an IE issue.
I am animating the property "margin-top" for the next element a certain distance when a element is clicked using .animate(), reveiling the submenu underneath. When a element is "opened" in this manner and another is clicked, a function is called to check all elements for being opened and closes the one that is using .animate() also.
I've only typed a description of the code because I feel like the is an issue with browser performance (possibly just on this machine?). Has anyone heard of this happening in IE8 or below in regaurds to the animations or just Jquery/Javascript and IE8 in general?

In IE8 I sometimes have to manually cause the parent element to reflow in order to get other elements to move correctly after an animation.
function repaint(jElement) {
if (!$.browser.msie) return;
for (var i = 0; i < jElement.length; i++) {
jElement[i].className = jElement[i].className;
}
}
Try running this function on the parent of the animated element after the animation is complete and see if it fixes the issue.

Related

.scrollTop(0) not working for getting a div to scroll to the top

I have a feeling what ever gave me problems that I tried to find a solution in this question - Can't trigger a jquery function with scroll on a particular div - might be responsible for scroll related issues here.
Short version: Can't get this, or anything similar, to work
$("#Container3").scrollTop(0);
Nothing happens really, no error in the console, no wierd behaviour, just seems to ignore the scrollTop(0) request.
Long version: I'm sorry but posting a code snippet isn't feasible as it's a complex app-like interface but I'll try to explain the issue to the best of my abilities:
Mobile responsive website that loads different interfaces depending on screen real-estate.
Smallest interface composed of 3 parts - navigation at the top, search at the bottom and content in the middle.
Content is mostly loaded during use and not at page load.
At the push of a button that re-loads the contents of a particular div I also need to scroll that div to the top for usability purposes.
While it doesn't seem to influence my problem (removing it doesn't solve the issue) I should disclose that I'm using hammer.js to simulate touch events as it might influence the solution.
The load is done outside the viewport so animations aren't needed but I'll take them as long as they get this to work.
This is what my jquery request looks like
$(document).on("click",".NavRowButton",function(event){
$("#Container3").scrollTop(0);
var $targetButtonId=$(event.target).attr("id");
$("#Content").load("/load/login/"+$targetButtonId+".php");
$("#DisplayContentName").html("<span class='NavColSpan'>"+$targetButtonId+"</span>");
$("#Container3").find(".WindowBorder").css("top","0");
});
#Container3 has the scroll bar and is the immediate parent of #Content.
This is a function I'm still building and is the solution for the problem I had before and also what I'm using now to help debugging this one:
document.addEventListener('scroll',function(event){
if(event.target.className==='Container'){
var $currentScroll=$(event.target).scrollTop();
console.log($currentScroll);
var $targetId=$(event.target).attr("id");
console.log($targetId);
}
},true);
Thanks in advance.
Edit: I just noticed that if I put a $(event.target).scrollTop(0); at the end of the scroll distance debugging function it actually resets the scroll so it seems that as long as the div is the event.target it works while from the outside as during the click function I might not selecting it appropriately.
Edit2: I just learned I can cache event.targets into variables and with a .get() inside the click function I'm sure I'm selecting the right element so it just leaves how the scrollTop(0) method works.
They now look like this(also had to add a condition to limit load events):
global variable:
$DivTestVar="";
click:
$(document).on("click",".NavRowButton",function(event){
var $targetButtonId=event.target.id;
if($targetButtonId != $("#DisplayContentName").html()){
$($DivTestVar).scrollTop(0);
console.log($($DivTestVar).get());
$("#Content").load("/load/login/"+$targetButtonId+".php");
$("#DisplayContentName").html($targetButtonId);
$("#Container3").find(".WindowBorder").css("top","0");
};
});
scroll debugging:
document.addEventListener('scroll',function(event){
if(event.target.className==='Container'){
$DivTestVar=event.target;
var $currentScroll=$($DivTestVar).scrollTop();
console.log($currentScroll);
var $targetId=event.target.id;
console.log($targetId);
}
},true);
If I click before scrolling the console.log($($DivTestVar).get()); returns empty but if at the first scroll it starts returning the correct DOM element. The scrollTop(0) is ignored anyway.
Edit3: I just want to leave a small update. I have since given up on the method I was trying to use here for something with a similar effect but not as user friendly as what I was trying to achieve. As such I no longer care about this personally but if you're reading this and have a similar problem I have come across this issue a couple more times to a smaller effect and I now think it's related to position:fixed; elements and how scrollTop() deals with that but I don't have the time to delve into it more so good luck and godspeed.
Did you try the pure JS version ?
document.getElementById('Container').scrollTop = 0
You have two possibilities, as far as I know.
1-Scroll the whole page until it reached the top of your #Content div position with jQuery.
2-Your #Content is inside a div with scroll, which scrollTop(0) will work for that (example: http://jsfiddle.net/zkp07abu/).

jQuery click events erratic, placeholder stuck

I'm messing around with porting an image selection tool into jQuery. I'm having a couple little issues that are annoying me--
First, the sortable placeholder appears to be stuck at the top of the UL-- it doesn't move down to show the proposed new position if the item were dropped.
Second, the click events attached to the buttons don't fire reliably-- sometimes they work fine, other times it takes 2, 3 or 4 clicks before they fire.
I have been reading a ton of tutorials and the jQuery docs, and I believe I've done this properly, but I'm sure there's better ways to handle what I've attempted.
Here's a jsfiddle showing the behaviour. Any help appreciated!
http://jsfiddle.net/Y2tRW/9/
tested the first problem with
ie9 (the placeholder work as expected if the document is loaded in ie8 compatibility mode)
chromium21 (on a pc works and on another doesn't, i'm disappointed)
opera11
the placeholder works as expected, the second problem is that you need to click exactly on the <i> element, if you click on the button but not on the image it just scroll to the top of the page.
this will fix the problem, change
$("#sortable").on("click", "i.icon-pencil", function(e) {
to
$("#sortable").on("click", "a.btn:has(i.icon-pencil)", function(e) {
EDIT:
FOUND IT
you have float:left; (it's in the bootstrap-combined.min.css for .span12) for all your li element but not for the highlight
add it in your fiddle and it will work.
it worked at home on ie cause i have the compatibility always set to IE8 now i get rid of that setting and it doesn't work. by the way ie8 doesn't apply float:left to display:list-item;

Combining jQuery Isotope and Lazy Load

Have started a project using jQuery Isotope. Initially integrated with Infinite scroll, but thought it was a little clunky.
Was hoping to replace Infinite Scroll with Lazy Load, and wondered if anyone has had any luck combining the two. Any tips to get them to play nice would be great.
Thanks a mill
If you want to use isotope's sorting/filtering functions, you will need to set the failure_limit of lazyload and trigger the event with isotope's onLayout callback.
jQuery(document).ready(function($) {
var $win = $(window),
$con = $('#container'),
$imgs = $("img.lazy");
$con.isotope({
onLayout: function() {
$win.trigger("scroll");
}
});
$imgs.lazyload({
failure_limit: Math.max($imgs.length - 1, 0)
});
});
Explanation
According to the docs ( http://www.appelsiini.net/projects/lazyload )
After scrolling page Lazy Load loops though unloaded images. In loop it checks if image has become visible. By default loop is stopped when first image below the fold (not visible) is found. This is based on following assumption. Order of images on page is same as order of images in HTML code. With some layouts assumption this might be wrong.
With an isotope sorted/filtered list, the page order is certainly different from the HTML so we need to adjust our failure_limit.
As you can see we store the jQuery object so that we can use its length-1 as our failure_limit. If you're curious as to why it is length-1, it's because of the following check in lazyload's update method.
if (++counter > settings.failure_limit) {
return false;
}
Lazy load on other events
If you are not triggering your lazyloads on scroll, you will need to swap the "scroll" trigger for whichever event you are using.
Demo
http://jsfiddle.net/arthurc/ZnEhn/
I think you might have some luck using this instead : https://github.com/fasterize/lazyload
It's library independent so won't break.
Here's working code using both jquery isotope and lazyload together successfully (tested in Chrome)
http://jsfiddle.net/wN6tC/62/
In the browser console you will get console.log('loaded image') confirmation when an image is loaded, as you scroll down. Drag the jsfiddle html box to change the width and you will see the layout change dynamically.
I added the background red class so you can see how isotope alters the dom after it loads. Most of the problems while trying to set this up come from, IMHO, isotope's dom manipulation.
I hope this is enough to get you started. Have fun.
Update:
I never tested example in other browsers, and apparently IE or FF failed to work because of the HTTPS references for the javascript resources (for some odd security reason). Replacing them was all that was needed to get it working in IE and FF as seen here:
http://jsbin.com/ajoded/
and
http://jsfiddle.net/wN6tC/73/

Why is this jQuery animation so SLOW on Firefox 4/5?

EDIT by Phrogz: This appears to be a problem with the framerate of jQuery animation when this particular complex CSS is applied. See the video at the bottom for an example of the problem.
I think is hard to copy and paste the whole code here. So I've create a fiddle for this.
To be honest, CSS is not so important on this (I putted it for have a decent grid). I also removed many functions from my original version, in fact they aren't so important.
The only one that works is by clicking on the buttons + Tracks (which call addTrack()) that adds a new track/line in the grid. Tested on Chrome, IE, and Firefox < 4 version. There isn't much problem. It's really rapid and fluid.
The problem is on Firefox 4 or 5. It's really slow to add the new track/line. It's fast like a turtle.
What the function done is to clone (copy with handler) an element trackOn, which is already written in a hidden field (tracklistOff) and add it (insertAfter) applying a fade effect. (thats means a new line in the grid).
Why this behaviour on Firefox? Too many elements to browse on the DOM I suppose. I need to get rid about this slow attitude... so what can I do?
EDIT
You can hear the difference about Chrome and Firefox (5, last version) on this video. Try to hear/see the difference between clicking on mouse and add new line (with the effect). It's too frozen (also when I try to add more tracks quicly).
Still a problem for me, any suggestion will be appreciate :)
This is not very slow for me. On my computer running Firefox 5 I can add many tracks in less than a second. What performance are you seeing? ("Fast like a turtle" is not a very quantitative measurement. :)
When you have trouble with JavaScript speed, profile it, using the Developer tools for Chrome/Safari/IE or Firebug for Firefox. Here's what I see when I run the profiler on your JSFiddle and click on the +Track button twice:
From this we can see that most of the time is spent in some set function from a mootools library. Since I don't see this library included in your code, I'm assuming the profile is tainted by JSFiddle.
So, we create a standalone test case without the unnecessary CSS and profile that. Now we see this (for several presses of the +Track button):
Almost all of your time is spent in the clone() function.
So what can you do about it? You could try pre-creating the HTML string (in JS) for a template row, and instead of using 'clone' try creating that with:
$(templateString).hide().insertAfter(...).fadeIn(600);
would it be ok if you get just the last element?
something like:
$('.tracklistOff div:last-of-type')
.clone()
.hide()
.insertAfter(($(param).parents('.trackOn')))
.fadeIn(600);
or you could addClass(last) to the last element to get only one
I just tested your fiddle on the following browsers and they all worked well: FireFox 5, Opera, Google Chrome, Safari & IE9.
There were no speed issues but each browser handled the fade slightly differently however everything else seemed to work fine. Not sure what the problem is here. It could be your computer speed but as you're on this site I presume it's decent.

Div not properly hiding in IE

I've got few divs on my website - on the load I want some of them to be hidden, some shown. I am hiding the ones I don't want like this:
$(".divToHide").hide();
It works well in Chrome, Firefox, IE8 an Opera... It doesn't in IE6 (I haven't tested on previous version yet...) - when I load the page all the divs are hidden properly. When I click a link that makes one of them visible it appears correctly. The problems shows when I click on a different link that's supposed to hide the first div and show another. The text of the first div is hidden, but the image stays and obstructs the newly shown div. I'm pretty sure it's a bug - when I zoom in or out of the page the divs that were supposed to be hidden disappear suddenly - they're only visible when I load the page.
Is there a way around it?
EDIT: I'm using jQuery v1.3.2
EDIT: Unfortunately the solution of using addClass to add css class that states display: none doesn't really work - it seemed like it did at first, but the problem is still there.
UPDATE: The js file I wrote can be found here, while the html here. The problem I have is that when you go from one portfolio to the other, the image of the first one stays there obstructing the next, even though it should be hidden (text underneath changes correctly). Wrong disappears when you try to zoom in/out of the page.
I used to hide all portfolios using $("#divId").hide(), but as was pointed out below, I now use $(".classToHide").hide().
UPDATE: The problem is solved on IE8 - I forgot to include the standards mode declaration... However, on IE6 it's still the problem.
You're hiding multiple div's by using an ID selector?
Try giving those div's a class "divToHide" and then use:
$(".divToHide").hide();
Maybe IE8 handles duplicate id's in another way than those other browsers..
Just a thought: you're not using an old (pre-IE8) version of jQuery, are you?
Edit: No, grycz is using the current version.
Edit: simplified to use toggleClass()
You could try doing it manually, like toggling a css class called "hidden." It might look something like this:
function myToggle(element_id)
{
mydiv = $('#' + element_id);
mydiv.toggleClass("hidden");;
}
And your css file would have:
.hidden
{
display:none;
}
I haven't tested this, but this is the kind of workaround I imagine you'd want to think about if this is, indeed, a bug in jQuery/IE8.
Are you sure that hide() function call is even getting called on the page load? Try putting an alert('hi') right before that function call, and see if that happens in IE8.
try
$("#divToHide").css('display:none');

Categories