Animate behaves wierdly in Chrome and Firefox (ok in IE) - javascript

I use this code:
$("img.cloudcarousel").each(function(i, e){
coords[i] = $(e).offset();
});
to save the position of the images (and it works).
Then I animate them and move them.
Then I use this code:
$("img.cloudcarousel").each(function(i, e){
$(e).animate({top:coords[i].top, left:coords[i].left}, 1000);
});
to animate them back to where they belong.
in IE (at least 8) it works fine but in Chrome and Firefox it animates 40-50 pixels too much to the left and down (like its over-animating).
dont ask me how I discovered this: when i use mousewheel over them they go to where they belong!
I guess it's somehow related to the buildup of the animation queue, however I only use four images and it doesn't fix on its own after x time, only on the mousewheel stuff.
edit : added to jsfiddle.net
I'm not really sure how that site works but I added my HTML and JS into it:
http://jsfiddle.net/3wqYg/

The $(e).offset() is not returning the values that is currently defined in your fiddle. I have not looked up the definition of offset but if you output the coords, you will see it is not the same as in the code
Edit: I see the problem see offset() http://api.jquery.com/offset/ it returns the x, y relative to document BUT when you animated it back it is relative to the parent element (default behavior). So in the doc it mentions using position(). that is relative to the parent element, I have not tried it but if you use that it should work.
Final Edit: yep works fine with position see http://jsfiddle.net/3wqYg/1/ you must copy it into a test page because it does not animate on fiddle

Related

Keeping scroll position when adding elements on top works in Firefox but not Chrome

I have a Meteor app (source code) which has a stream of entries and new entries are being constantly added on top. I am trying to make it so that if an user scrolls down to a particular entry, that entry should stay visible and not move even when more entries are added on top. Adding and removing entries is animated using Velocity.
I have made code which does that, but it works only in Firefox, while in Chrome it quickly starts jumping around as more entries are coming. Why is that and how could I fix it?
I'm going to post this since it took me a while to figure out. For me it had to do with the Scroll Anchoring feature which was introduced as default in Chrome 56.
The overflow-anchor property enables us to opt out of Scroll Anchoring, which is a browser feature intended to allow content to load above the user's current DOM location without changing the user's location once that content has been fully loaded. Source
You might want to try setting overflow-anchor to none, to opt out of the Scroll Anchoring functionality:
body {
overflow-anchor: none;
}
You can find a demo here, showcasing the difference with and without scroll anchoring.
After you insert the elements at the top, you need to manually re-scroll to the correct position:
function insertNewElementAtTop(parent, elem) {
var scrollTopBeforeInsert = parent.scrollTop;
parent.insertBefore(elem, eParent.firstChild);
parent.scrollTop = scrollTopBeforeInsert + elem.offsetHeight;
}

IE, and iframe.elementFromPoint not passing event

Update: Fiddle Demonstration -- http://jsfiddle.net/7tfbtso6/2/ -- Most of the settings work in chrome and firefox, but the only one that works in IE is Left-align: 105px. I do have overflow set to hidden on html and body, but this makes no difference. IE will not work if the element is not visible on screen. And overflow: visible on html and body give the effect of auto and no effect on the problem here.
My site uses two contentEditable divs.
#rInput is part of the document.
#rSyntax is part of an iframe under (z-index) #rInput.
In every browser I've tried so far, except IE (I'll get to that in a moment.), I'm able to determine what element is contained within the iframe using elementFromPoint().
In IE's case, this is only possible if they're not overlapping which isn't possible because a secondary purpose, as the name implies, is to provide syntax-highlighting.
The IE IFrame has to be visible, on screen, not obstructed by any objects. I've tried display: none;, visibility: hidden, and pushing it down in a div with overflow: hidden, but all of these attempts cause it not to work. I've also tried setting the height and width to small proportions.
If any of these could work, I could use two copies of rSyntax, one on top (z-index), hidden somehow, for mouse events and one for syntax highlighting.
Most of these solutions work in every browser but IE. The IE box simply demands that it be on top.
"Flickering" it with css (display, visibility, pointer-events) seems awfully hacky (and just plain awful). I haven't really tried to implement it because it seems like a last resort.
The problem is further complicated because I'm trying to capture clicks and mouseovers, for different purposes (clicks for finding content, mouseovers for tooltips--created with a div mimicking attr("title").
I've briefly tried placing the iframe on top (z-index) of the div, but there's no way to intercept the clicks and pass to the lower object because it runs in to the same problem.
Here's the script I'm using to get the objects, partly in case it's useful to anyone.
$(document).on("mousemove", "#rInput", function (e) {
$element = $(document.getElementById('frSyntax').contentDocument.elementFromPoint(e.pageX+$("#rInputContainer").scrollLeft()-10,e.pageY+$("#rInputContainer").scrollTop()-12));
if ($element.is("span") && $element.attr("title") && $element.attr("title").length) {
$("#syntip").text($element.attr("title"));
$("#syntip").css({"top": e.pageY+10, "left": e.pageX, "display": "inline-block"});
} else {
$("#syntip").hide();
}
});
I have considered transparency, and that works for this element, because it's small, but I use a similar setup with a large element that takes up more than 50% of the screen, there would be problems.
After many frustrating efforts, I concluded that pushing the top (z-index-wise) element offscreen was the only solution for IE/Edge. Flickering it with display: none causes some properties I needed, like width, to not be accurate.
Just make sure you push it farther than the element will ever be. My application is sidescrolling so I merely needed to place the css top to something like 2000.

How to make a pattern "fixed" in Raphael.js / IE?

I'm creating a small tool to illustrate the benefits of polarizing lenses. Basically a user will drag the lenses (a Raphael.js path) over a dazzling scene (the CSS background of the container DIV) and "see through" the lenses. Here is the js code:
var rsr = Raphael("playmask", 720,540);
// Lens path
var path_f = rsr.path("M0,73.293c0.024-39.605,17.289-53.697,35.302-61.34C53.315,4.312,99.052-0.012,119.011,0 c38.56,0.021,43.239,11.164,43.229,29.9c-0.002,3.45-0.76,28.632-16.349,58.949c-10.332,20.092-28.434,60.424-76.452,60.396 C29.821,149.223-0.022,112.898,0,73.293 M200.594,29.922c0.011-18.734,4.699-29.871,43.262-29.851 c19.96,0.013,65.691,4.39,83.695,12.052c18.005,7.662,35.254,21.772,35.231,61.379c-0.023,39.606-29.909,75.896-69.526,75.872 c-48.02-0.027-66.076-40.377-76.384-60.484C201.32,58.557,200.594,33.373,200.594,29.922");
path_f.attr({"stroke-width":2, fill:'url(img/polarized.jpg)'} );
var move = function(dx,dy){
this.translate( dx-this.ox, dy-this.oy );
this.ox = dx;
this.oy = dy;
},
start = function(){
this.ox = 0;
this.oy = 0;
},
end = function(){
};
path_f.drag(move,start,end);
The #playmask div has this CSS (just the "un-polarized" background image and the size):
#playmask{
height:540px;
width:720px;
background: url(img/unpolarized.jpg);
}
What I'm stuck with is:
Chrome/Firefox, as always, play nice: the lenses shape shows up, and the fill image looks "fixed" while dragging the lenses around (see the first pic);
IE versions 7,8,9 work, but (surprise!) they don't behave the same way: the fill image is "glued" to the lens shape (see second attached pic).
What I'm asking here is: can I make IE9/8/7 behave in a similar manner, that is, keeping the fill image fixed while dragging the lenses? If so, how?
Firefox screenshot:
IE9 screenshot:
Edit Using Modernizr to detect browser features, I noticed that this strange behavior seems related to the "no-smil" feature of IE.
I found out a bizarre behavior of IE9... the background does not "stick", but if I drag the mask around, select some text and press the right mousebutton, it refreshes the "polarized" background to the correct position!!
Edit 2 (21 May 2012) No solution yet :( but to be more precise, it does not relate in any way to the "no-smil" feature; and, the correct way to reproduce the bug on IE9 is drag the glass around, select some text in the rest of the page, and roll over the accelerator icon that pops up (the blue one with an arrow in it). The glasses bg magically "refreshes" at the correct position.
Important Edit 3 (28 August 2012)
You can find it all packed in this jsfiddle ( http://jsfiddle.net/q4rXm/17/ )
It seems like a redraw bug in IE. One workaround is to reset the fill image by adding
path_f.attr({fill:'url(http://www.fotoshack.us/fotos/58480536599_97943820.jpg)'});
after the translation. See fiddle here. This works okay in IE9 except for being slightly sluggish, but maybe you can find a cheaper way of forcing redraws. Not tested in older IEs. Also, it causes flickering in Opera and Chrome, so you'll need to detect IE so you only reset the fill if running in IE.
Edit:
A better alternative is to reset the size of the canvas:
group_a.translate( dx-this.ox, dy-this.oy );
rsr.setSize(720,540);
This doesn't cause flickering in other browsers, so no need for IE-detection.
This is something related to the positioning of the elements.
Try giving absolute for #playmask and for its parent give position:relative
I remember something like this encountered sometime before when playing with Raphael. It happened only in IE, I thought it was a bug in Raphael, later found its due to positioning.
I've had a few similar problems with the VML elements created by Raphael in IE, especially when trying to float elements over the top of other elements, etc.
The VML elements seem to end up in weird places in the DOM sometimes, and with strange CSS values, such as "position: static", where you'd expect "position: absolute" or "position: fixed". I'd double-check those CSS values, and make sure that those elements are where you think they are in the DOM.
I've also had Raphael reset the position value of the container in IE to "position: static". In that case, I had to add a line to my stylesheet to force it back. In your case, you could try:
#playmask {
position: absolute!important;
}
Weird things seem to happen to the flow around those VML elements...
For all those answers saying IE9 can only handle VML and not SVG. Not true. IE9 has native SVG support, to certain extent.
OP have you tried doing this with a clipmask instead of dragging around a fill? My understanding is that changing the position of the clipmask path should correctly "reveal" the correct section of the picture. Hopefully shouldn't be too hard after this to add a static image for the background.

iscroll issue with two dimensional ( horizontal + vertical ) scrolling, scrollable are related issue?

Problem in brief
I have got a piece of working two dimensional scrolling code. Scrolling as such is working fine. Scrolling can be done in any direction (not like restricted to only horizontal or only vertical at a ti,e) but there are two problems -
Scrolling beyond the visible area towards top and left, does not bounce back the scrollable area.
Scrolling to right and bottom bounces back.
Problem demo - http://jsfiddle.net/sandeepan_nits/pAhjU/6/
Note - Test in webkit browsers only (Google chrome and Safari).
Solution I am looking for
Either, point out what is wrong in my code.
Or share any properly implemented working demo of both ways scroll (horizontal + vertical) using the same version of iscroll, so that I can follow the same. I am using - version 3.7.1, preferable, or using iscroll version 4, fine as well.
Or any pointers, of course, would be appreciated.
Problem Description
Please check working code here - http://jsfiddle.net/sandeepan_nits/pAhjU/6/
Note -
Test in webkit browsers only (Google chrome and Safari).
I have knowingly put everything inside the HTML section in the jsfiddle, because if I separate things completely, the scrolling does not work, and I am not sure where exactly it stops working. Thanks if you can point out.
Code
Here is the HTML -
<div class="header">
<div class='left_link'></div>Demo</div>
<div id="main_content" class="main_content">
<b><div id=scroller1><br/>
<div class='center_data'>Scrollable area</div>
<div class='center_data'>hello world!</div>
<br/>
</div></b>
</div>
Note - I know there is invalid html there - <div id=scroller1> is inside <b></b> and I am not sure why if I remove the <b></b> tags, horizontal scrolling does not work anymore - check here.
Here is the js -
var myScroll;
var a = 0;
function loaded() {
//setHeight(); // Set the wrapper height. Not strictly needed, see setHeight() function below.
// Please note that the following is the only line needed by iScroll to work. Everything else here is to make this demo fancier.
myScroll = new iScroll('scroller1', {desktopCompatibility:true});
//myScroll2 = new iScroll('scroller2', {desktopCompatibility:true});
}
// Prevent the whole screen to scroll when dragging elements outside of the scroller (ie:header/footer).
// If you want to use iScroll in a portion of the screen and still be able to use the native scrolling, do *not* preventDefault on touchmove.
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
// Load iScroll when DOM content is ready.
document.addEventListener('DOMContentLoaded', loaded, false);
I guess the reason is that the scrollable div is by default rendered at the bottom-right corner of the scrollable area. But I am not sure about the proper way to configure those things - how to set where to render the scrollable div inside the scollable area. So far I did not find any working demo of both ways scrolling - horizontal + vertical scrolling.
I checked out the documentation of iscroll and many working demos, but did not find any demo where scrolling can be done both ways - horizontally as well as vertically. I checked the "Accepted options are:" section under "Syntax" section in http://cubiq.org/iscroll but none of those params seem to be what I am exactly looking for.
Other things
Also, one more thing, I am not able to view the area covered by dom elements in chrome browser, while I inspect the given scroll demo. By viewing the area I mean moving the mouse over the dom inspector panel highlights the dom in the browser view. When does it not appear? I checked with validated HTML as in http://jsfiddle.net/sandeepan_nits/pAhjU/12/.
Somebody please create a tag iscroll or iscroll3 so that I can retag my question.
Update
I just want to have normal two dimensional scrolling with the scroll area being properly inside the visible screen and there should be bounce back on taking outside the screen. Right now there is no bounce back (in my jsfiddle) on scrolling towards top and left, outside screen. Bounce back happens on scrolling to right and bottom. I just want the scrolling area to be well placed inside the screen. I guess bounce back will automatically get fixed then.
I think the last version (4.1.8) on the github repo will fix your problem ;) I'm using it on some projects and it is now optimized for desktop browser ;)
Edit
From the documentation :
hScroll, used to disable the horizontal scrolling no matter what. By default you can pan both horizontally and vertically, by setting this parameter to false you may prevent horizontal scroll even if contents exceed the wrapper.
vScroll, same as above for vertical scroll.
By default, when creating a new iScroll('idOfElement') the scroll is vertical and horizontal. It can be disabled with these parameters. Dual Scroll is totally possible as this video shows it.
So, to force dual Scroll :
var myScroller = new iScroll('idOfElement', {vScroll:true, hScroll:true});
This is not a complete solution, but this might help you.
First of all, The HTML code was not properly nested, and so you were needed to put the <div> inside the <b>. I fixed up the HTML a bit and its working without the <b>
http://jsfiddle.net/Aexhz/
And with properly nested HTML and correct settings, This worked even after dividing the HTML/JS/CSS
For me, it does show some Horizontal as well as Vertical Scrolling, but i don't know if that's how you want it to be. i Edited the Class initialization line as well
myScroll = new iScroll('scroller1', {desktopCompatibility:true});
TO
myScroll = new iScroll('scroller1', {
snap: true,
momentum: false,
hScrollbar: false,
vScrollbar: false,
desktopCompatibility: true
});
This doesn't affects much but i still put that.
I will continue looking into this and update my answer if i find anything new.
I know you want to fix this using iscorll but wanted to share this with you, i had great results using it: http://jscrollpane.kelvinluck.com/#usage
It is highly customizable with css, a demo here with vertical and horizontal scroll: http://jscrollpane.kelvinluck.com/basic.html

JW player resets when CSS position changed to fixed in FF/Safari 5.0

I have a script that changes a div's positioning property from static to fixed when the scroll bar reaches it. (example - you'll see the floating video in the right column).
If you look at the example, when you scroll down the - the video div ("#membership") scrolls down the page with the rest of the content.
Here's the script that does that:
$(window).scroll(
function ()
{
if($(window).scrollTop() > 157){
$("#membership").css("position", "fixed");
var marginTop = $("#headerWrap").height();
$("#membership").css("top", "40px");
}else{
$("#membership").css("position", "static");
}
}
);
Here is the JW player object:
To summarize: When I change the containing div's position property to position: fixed, the JW player resets. I have no clue how to even attempt to debug this. It works fine in Chrome for OSX/Windows and interestingly enough Safari 3.
One observation that may or may not help - the whole video blinks and appears to reload when the position property is changed.
As far as I now this is a bug in FireFox: https://bugzilla.mozilla.org/show_bug.cgi?id=90268
When you change the position property for a static element, the browser has to reflow the page. When this happens, it may or may not decide to reload embedded objects. Try starting with position absolute rather than static and see if that makes a difference.
I would try putting embedded object into iframe... providing this doesn't create too much fuss in your JS code.
I have found putting a div inside a div works. I manipulate the outer div position and referance the inner one in jwplayer.

Categories

Resources