I'm in the process of updating our site to use modern browsers, but I still need to support the cavemen on IE7. I'm experiencing an issue with jQuery UI's position utility. The strange behavior occurs for the Windows 7 OS, using IE 11, emulating IE7 (document mode 7). The strange behavior is nonexistent to me, Windows 8 OS, using IE 11, emulating IE7 (document mode 7).
I need someone to see if this happens to them using either IE7 (not emulated) or with the same setup as our testers experiencing the issue.
The issue occurs when you hover over the missing image element in the upper right of the div. The unordered list shows up once on hover, then any subsequent hovers nothing appears. Either that or the hover never brings up the unordered list to begin with.
Here's a fiddle where the issue should appear if you have a similar work space to what I've mentioned above.
https://jsfiddle.net/bpdxL1e6/
var hoverCollection = $('.current-menu-item');
$.each(hoverCollection, function(index, object) {
$(object).hover(function() {
$(object.lastChild).position({
my: "right top",
at: "bottom right",
of: object.parentElement,
collision: "flipfit"
});
});
});
Its hard to tell the position utility is working at all in jsFiddle, as the purpose of it is mainly to keep the unordered list visible in the viewport on hover.
I have a local html doc on my desktop with the contents of the fiddle to see the effects of the position working.
Here's a link to a download of the full html file.
http://www.filedropper.com/testhtmlfiddle
I just wrote my own positioning utility. Its called hoverCopter. Supports IE7 as well as all other modern browsers.
var hoverCollection = $('.current-menu-item');
var hoveringCollection = [];
$.each(hoverCollection, function(idx, object) {
hoveringCollection.push(object.lastChild);
});
hoverCopter(hoverCollection, hoveringCollection);
function hoverCopter(objectsToTriggerHover, objectsToHover) {
$.each(objectsToTriggerHover, function(idx, object) {
$(object).hover(function() {
var bool = true;
var objWidth = $(object).offset().left + $(objectsToHover[idx]).width();
var winWidth = $(window).width() + $(window).scrollLeft();
var objHeight = $(object).offset().top + $(objectsToHover[idx]).height();
var winHeight = $(window).height() + $(window).scrollTop();
if (objWidth > winWidth) {
var left = (objWidth - $(object).width() / 2) - winWidth + (winWidth - $(object).offset().left);
$(objectsToHover[idx]).css({
'left': -left + 'px'
});
} else {
$(objectsToHover[idx]).css({
'left': 0 + 'px'
});
}
if (objHeight > winHeight) {
var top = (objHeight - $(object).height() / 2) - winHeight + (winHeight - $(object).offset().top);
$(objectsToHover[idx]).css({
'top': -top + 'px'
});
bool = false;
} else {
$(objectsToHover[idx]).css({
'top': 0 + 'px'
});
}
// this is a zIndex hack for IE7 so that the ul display above the images
var elements = $('[name="homepart_nav_wrap"]');
var int = 100;
$.each(elements, function(idx, object) {
if (bool == false) {
$(object).css("zIndex", idx);
} else {
$(object).css("zIndex", int);
}
int--;
});
});
});
}
And here's a jsFiddle. https://jsfiddle.net/bpdxL1e6/3/
Related
I'm facing the following issue:
I'm working with a site which shows additional information on hover. Whole functionality for hovering and display of content is done via JQuery and it works perfectly in all browsers except for Safari browser past version 6. Specifically it appears that display: block is not being applied properly and content is not showing, even though I can actually see the changes being made when I hover over the elements in the console.
This is the code that does the change
function applyScriptIfNeeded(li) {
var parent = $('.jCarouselLite:not(.paging)');
$('.someClass', li).hover(function() {
var someItem = this;
var child = $('.serviceInfoWrapper', someItem);
var display = child.css('display');
child.css('display', 'block');
if (child.is(":visible")) {
if (!contains(parent, child)) {
child.css('display', display);
var pos = $(someItem).offset();
$(document).scroll(function() {
child.css('top', $(someItem).offset().top - $(window).scrollTop());
});
child.css( {
display: 'block',
position: 'fixed',
top: pos.top - $(window).scrollTop(),
left: pos.left - $(child).width() - 30 - $(window).scrollLeft()
});
}
}
},
function() {
var someItem = this;
var child = $('.serviceInfoWrapper', someItem);
child.css('display', 'none');
});
}
The HTML element to which I'm applying this function is really just a simple div so I'm not sure what might these problems.
Can someone help me with this ? Did anyone else encounter this type of issues with Safari before ?
function getScrollTop()
{
if(typeof(window.pageYOffset) === 'number')
{
// DOM compliant, IE9+
window.scrollY = window.pageYOffset;
}
else
{
// IE6-8 workaround
if(document.body && document.body.scrollTop)
{
// IE quirks mode
window.scrollY = document.body.scrollTop;
}
else if(document.documentElement && document.documentElement.scrollTop)
{
// IE6+ standards compliant mode
window.scrollY = document.documentElement.scrollTop;
}
}
}
function getScrollLeft()
{
if(typeof(window.pageXOffset) === 'number')
{
// DOM compliant, IE9+
window.scrollX = window.pageXOffset;
}
else
{
// IE6-8 workaround
if(document.body && document.body.scrollLeft)
{
// IE quirks mode
window.scrollX = document.body.scrollLeft;
}
else if(document.documentElement && document.documentElement.scrollLeft)
{
// IE6+ standards compliant mode
window.scrollX = document.documentElement.scrollLeft;
}
}
}
// Summed-Up
function imgButtonClick()
{
getScrollTop();
getScrollLeft();
/*Some simple hidden code*/
window.scroll(window.scrollX, window.scrollY);
}
The getScrollTop() and getScrollLeft() functions are obtained from Internet - in a legal way, but the simple code addition does not work ( scroll(window.scrollX, window.scrollY); ). Mozilla's Developer Tools' Web Console (in Firefox) does not show errors. However, once filled with constants in place of scrollX and scrollY global variables - it does the simplified functioning by scrolling the page. The rest of the code, which had not been shown in this post - functions as asked. Other global variables on the page are also performing as asked.
If you are trying to animate a scrolling effect, you will need some additional code to animate the scrolling of the page. Here are some example functions to set the scroll location instantaneously:
function scrollToElement(element, scrollToTop)
{
var element = document.getElementById(element);
var elLoc = element.getBoundingClientRect();
var topCoord = elLoc.top + (scrollToTop ? window.innerHeight : 0);
console.log("About to scroll to: " + topCoord + ":" + elLoc.left);
window.scroll(elLoc.left, topCoord);
}
function scrollBackToTop()
{
window.scroll(0,0);
}
If you are looking to animate your scrolling effect, check out these:
Click here for a javascript solution.
Click here for a css solution.
You can also accomplish this using one line of code anywhere in your application or project using jQuery with no plugins:
$('html, body').animate(
{
scrollTop: $("#target-element").offset().top
}, 1000);
Taken from here.
I'm having a little problem with Safari - When i want to update a DOM element's position on scroll event, Safari seems not to catch up with the changes (resulting in a jumpy lag effect).
I checked it on other browsers (Chrome, FF, IE8+) and this seems to be specific to Safari.
I made a jsfiddle to illustrate my problem:
$("#container").on("scroll", function() {
$("#slide").css({
left: $("#container").scrollLeft() + "px"
});
var leftPos = 0;
for(var i = 0; i < 2000 ; i++) {
leftPos = $("#slide").css("left");
}
$("#info").text(leftPos);
});
http://jsfiddle.net/a4b86et3/2/
As you can see, I added an additional loop of DOM reading on each scroll to simulate "more operations going on" on each event occurrence, as this mechanism is a part of a bigger project, which contains many other DOM operations. (Notice, that this example works smooth everywhere except Safari)
Also, i used jQuery just for the convenience, the actual project uses pure js.
I managed to partially fixed the issue
by changing the left = x property to transform = translate3d(x,0,0), so the browser would use the GPU.
$("#container").on("scroll", function() {
$("#slide").css({
'-webkit-transform': 'translate3d(' + $("#container").scrollLeft() + 'px, 0, 0)'
});
var leftPos = 0;
for(var i = 0; i < 1900 ; i++) {
leftPos = $("#slide").css("left");
}
$("#info").text(leftPos);
});
http://jsfiddle.net/a4b86et3/3/
However, sometimes I'm still experiencing a slight lag/glitching while scrolling.
But, what's more important, this fix doesn't affect the scrolling, when I'm using a mouse scroll or touchpad! While dragging the scrollbar works way better, using any of the above brings me back to my initial problem.
Any ideas why this happens and how to fix it?
tl;dr; - Safari is slow when changing element position on scroll; translate3d seems to not work properly when using mouse scroll/touchpad.
I had the exact same issue, and it took me some time to figure out the fix. Here is an updated jsfiddle showing you how to resolve the issue in Safari: http://jsfiddle.net/a4b86et3/4/
function handle_scroll() {
$("#slide").css({
'-webkit-transform': 'translate3d(' + $("#container").scrollLeft() + 'px, 0, 0)'
});
var leftPos = 0;
for(var i = 0; i < 1900 ; i++) {
leftPos = $("#slide").css("left");
}
$("#info").text(leftPos);
}
$("#container").on("scroll", handle_scroll);
$("#container").on('mousewheel', function(e) {
e.preventDefault()
var maxX = this.scrollWidth - this.offsetWidth
var maxY = this.scrollHeight - this.offsetHeight
this.scrollTop = Math.max(0, Math.min(maxY, this.scrollTop - e.originalEvent.wheelDeltaY))
this.scrollLeft = Math.max(0, Math.min(maxX, this.scrollLeft + e.originalEvent.wheelDeltaX))
handle_scroll(e)
})
In brief: if you handle the mousewheel event yourself, calculate the correct scroll values there, and then call your handler code, things start working.
I'm not sure why Safari makes you jump through this hoop, but luckily the fix isn't too involved.
Hope this helps.
I'm using jquery/javascript to work with a hoverover that should follow the users mouse around over an image map. It works but one direction it's fine (to the left) but when you go to the right it's reallly really jumpy. I've made a video showing the problem here:
http://screencast.com/t/rnm1jUkvv8P
Heres my code:
if (sPage == "fireplan.aspx") {
jQuery('area').mousemove(function(e) { deshowtooltip(e, this) });
// jQuery('area').mousemove(function(e) { demovetooltip(e) });
jQuery('area').mouseout(function() {
jQuery('#tooltipwindow').empty();
delasturl = '';
});
}
function deshowtooltip(e, element) {
var url = jQuery(element).attr('tooltiphref');
if (delasturl != url) {
jQuery('#tooltipwindow').empty();
jQuery('#tooltipwindow').load('tooltip.aspx?soid=' + url);
delasturl = url;
}
var $this = jQuery(element);
$this.data('title', $this.attr('title'));
$this.removeAttr('title');
jQuery("#tooltipwindow").css("position", "fixed").css("top", (e.pageY - jQuery(window).scrollTop()) + "px").css("left", (e.pageX) + > "px").css("display", "none").show(); }
function demovetooltip(e) { jQuery("#tooltipwindow")
.css("top", (e.pageY - jQuery(window).scrollTop()) + "px")
.css("left", (e.pageX) + "px"); }
One other thing, the hyperlink clickthroughs seems to be disabled now i've done this hover over?
Tom
I worked it out... I just moved the hover over away from the mouse a little bit
I had a very similar issue to this. It turned out to be the math functions resulting in NaNs or negative values.
I'd check the maths in parts like this: e.pageY - jQuery(window).scrollTop()
I've written some jQuery code to display a box with data in the corner of the users' web browser. I'm using the .scroll event to make the box stay in the corner as the user scrolls up and down the page. Let me emphasize that I am not using jquery-ui dialog.
The only problem is that the box flickers as the page scrolls. I'm afraid that there will be no cross-browser solution to this problem as the different browsers seem to behave differently with scrolling. Barring a cross-browser solution, an IE solution would be nice (My web application is designed to be used by a specific group of about 100 users in my organization.)
Here are snippets of the relative code:
ExternalScroll: function () {
LittleBlackBook.setPosition();
}
setPosition: function () {
var scrollPosition = $(self).scrollTop();
var cssTop = LittleBlackBookStatic.determineCssTop(this.height, this.isTop, this.vOffset, scrollPosition);
var cssHeight = LittleBlackBookStatic.determineCssHeight(this.height);
var cssLeft = LittleBlackBookStatic.determineCssLeft(this.width, this.isLeft, this.hOffset);
var cssWidth = LittleBlackBookStatic.determineCssWidth(this.width);
this.jQueryObj.css('top', cssTop);
this.jQueryObj.css('height', cssHeight);
this.jQueryObj.css('left', cssLeft);
this.jQueryObj.css('width', cssWidth);
}
var LittleBlackBookStatic = {
determineCssTop: function (height, isTop, vOffset, vScroll) {
var windowHeight = $(self).height();
var scrollPosition = $(self).scrollTop();
var newModalTop = isTop ? vOffset + vScroll : windowHeight - height + vScroll - vOffset;
return newModalTop + 'px';
},
determineCssHeight: function (height) {
return height + 'px';
},
determineCssLeft: function (width, isLeft, hOffset) {
var windowWidth = $(self).width();
var newModalLeft = isLeft ? hOffset : windowWidth - width - hOffset;
return newModalLeft + 'px';
},
determineCssWidth: function (width) {
return width + 'px';
}
} // end LittleBlackBookStatic
I'm using jQuery to look up the scroll position as the page scrolls and change the CSS.
Is there a better way; a way that will make it scroll without flickering? If no, then why not?
You should use fixed positioning for that box instead instead of animating it to keep it in the corner.
You'll use less javascript and avoid flickering that comes with animation.