I have an HTML grid where we use arrow keys to navigate the cells (like a spreadsheet made of divs). Each cell has an INPUT textbox. We use javascript to catch keyboard arrow keys to move around the grid. This has worked fine in all browsers for over a year. Now, with Chrome 39, the grid will no longer scroll properly so that the input with focus is visible on screen.
Here is a fiddle to demonstrate the problem: scrolling list.
// This causes scrolling into view on focus to stop working
$('#grid').on('focus','input',function(e){
this.select();
});
Use the up and down arrows to scroll through cells in the list. When it hits top or bottom, it should scroll into view if the new cell is not already in view.
This fiddle example still works fine in IE10+ and Firefox, but in Chrome 39 (latest version), it will not scroll when you arrow into a new cell off the bottom or top. Also, it looks like the textboxes redraw off by a few pixels sometimes.
When a new cell (input) gets focus, we call this.select() to select any existing text. If we remove the call to select(), then Chrome 39 works fine again. But, users would like to see text selected.
The question is: Is there something I am doing that would cause this, or is it a bug in Chrome 39?
If it is a bug, does anyone know a workaround to select input text without breaking the native scrolling into view behavior? Any ideas would be appreciated.
Update:
It appears that even removing ALL JS code, leaving just a bunch of inputs in a scrolling div also fails (only on Chrome). You can only navigate with tab/shift-tab without JS, but scroll problem still occurs. Am I going crazy, or do other people see the same screwy scrolling when running this fiddle?
See Updated Fiddle for example.
The problem seems to occur, in my experience, from a parent container with position absolute/fixed with z-index value. This affects Chrome 39+
Try setting that parent container to have the following CSS declaration:
-webkit-backface-visibility: hidden;
Well, it looks like it is just a bug in Chrome 39. Hopefully, they will get it fixed before too long.
Luckily, Chrome is also one of the few browsers that supports the scrollIntoViewIfNeeded() method, so as a workaround I was able to do something like this in the focus event handler:
this.select();
if (typeof this.scrollIntoViewIfNeeded === "function")
this.scrollIntoViewIfNeeded(true);
So, that solves the immediate problem.
Related
Update: found possible cause, when I confirm it I will post it as an answer
I found something interesting about IE behaviour.
Opposed to the example I posted on jsfiddle, my original page shows an image in the background (sorry for omitting it, I considered it not relevant). Not as a css background property but as an img element that comes before the divs with the mouseenter/mouseleave event handlers. I do not use z-index property (and I already confirmed that use it changes nothing) I found that when this is the case (an img element followed by absolute positioned divs that should render on top of it) IE only fires mouseleave/mouseenter events on visible parts of the divs. In my case, I discovered this by adding (border-style: solid) and a (border-width) of considerable size to all the divs. IE fires mouseenter when mouse pointer enters the div's border and then fires mouseleave when mouse pointer is no more over the border pixels even if it is inside the div (probably because the div is transparent). If no borders (as my original code) no mouseenter events.
In jsfiddle this was not reproduced. But if I add the img element should be 100% reproducible.
Possible workaround (I will test it right now and update): div background pixels must not be transparent or mouseleave will be fired right after the pointer is no more over the border pixels, if no borders then no mouseenter/mouseleave will be fired. Use a png background image for the divs with all pixels 1% opaque should do the trick. Maybe the css opacity property (without any background image but with a solid background color) may work too.
More info:
my doctype is <!DOCTYPE html>
I need the background image to be an img element, is not practical
in this case to use a css background property.
Original question:
IE 10 console is not providing any useful information. I started to use console.log in different parts of the script and come to the conclusion that mouseenter and mouseleave aren't fired for IE 10, don't sure in other IE versions. Works OK in Chrome and Firefox, and probably Opera.
This code result in no output in the console (for IE). It should at least prints "IE TEST 2".
console.log("IE TEST 1"); // OK
$(".show_on_mouseenter").mouseenter(function (evt) {
console.log("IE TEST 2"); // nothing is print
showContent(this);
});
$(".hide_on_mouseleave").mouseleave(function (evt) {hideContent(this)});
console.log("IE TEST 3"); // OK
For now I will try to emulate mouseenter/mouseleave using mouseover. But It would be great If the code just works on IE as It is now.
I tried to replicate only the relevant part of the code in jsfiddle. This time It worked for IE 10 too. I'm doing nothing really before those lines of code, maybe are my styles that are causing the problem. I modified my css to make the content divs and control divs visible from the start and they position and size is as expected in IE 10. My original hideContent and showContent functions have more code that the one I showing at jsfiddle but they aren't the problem because in my IE 10 they aren't being called as the previous console.log() line is not executed.
Code at jsfiddle showing how the script should behave. You move the mouse over the div, and another div appears, then you move the mouse out of the first div, and the content is hidden again. You will see a lot of suspicious values like "left: 14.321px". That is because my original code calculates left, top, width and height and produces not truncated values, as every browser I have tested accepted those values, I simply let them as doubles. Also some of them are as percentages, but in jsfiddle I used px in all cases because I'm entering them manually.
http://jsfiddle.net/xhzCL/
For some reason this code works in IE 10. jquery version is the same I'm using. I cannot replicate the problem in jsfiddle.
More info: Console is clear except for my own console.log() lines. I'm downloading my page from an http server running in another machine connected to my router. I remember something about an IE security police causing troubles with scripts of pages loading from intranet. May be this the problem?
The reason why the console is clear except for the console.log() lines is because there is nothing wrong in the Javascript code. Nothing wrong with the css or html. The problem is how IE 10 (and probably other versions of the same browser) behaves.
It seems that IE understands that mouseenter must be fired when the mouse pointer enters a visible part of the element and mouseleave must be fired when mouse pointer leaves a visible part of the element. This is not the case if nothing is below the element (visually) but things change when there is something below the div and due to div having no content or background-color the other element's pixels can be seen through it. Adding the css properties background-color: white and opacity: 0.0001 easily makes IE behave like all other browsers for this specific situation without the background-color becoming noticeable to the eye.
The following links must be visited using IE 10 (probably 9 and maybe 8) as other browsers (Firefox, Chrome, Opera, Safari) will fire the events in any case.
Demo reproducing the problem: http://jsfiddle.net/xhzCL/5/
Demo solving the problem: http://jsfiddle.net/xhzCL/6/
Update: by using two inner divs is possible to have visible borders and still have consistent cross browser behaviour: http://jsfiddle.net/xhzCL/9/
The difference are in these two css lines:
background-color: white;
opacity: 0.0001;
Or with jquery:
$(".show_on_mouseenter").css("background-color", "white").css("opacity", "0.0001");
Note that the proposed solution will hide also the borders of the div that should fire the mouse events. That's OK with OP needs, may not be OK for other situations. Try to remember where the div was in demo 1, then go there with the mouse pointer, the text will be visible while the pointer is over the full div body, no matters where exactly, while in demo 1 the text will be visible only when the pointer is over the border's pixels and will hide when the pointer is near the center of the div (opposed to the behaviour of all other browsers).
If OP had included the img element from the beginning others would run into the same problem and found a similar solution. Sorry for that, I was sure the img was not related to this and paste the full page code into jsfiddle was not practical.
Try using this instead
$(".show_on_mouseenter").on("mouseenter", function (evt) {
console.log("IE TEST 2"); // nothing is print
showContent(this);
});
So I'm trying to have a mobile menu that slides out on the left when an icon is clicked, and disappears again after you click outside the menu. Like this:
http://codepen.io/anon/pen/LzJuq (old, see new codepen below)
And it works fine on desktop and in Android's default Browser.
On my phone, in Chrome, the menu will only open the first time. Each subsequent time it closes itself before it finishes opening.
I can see that it tries to open... so I assume, because the #menu-icon is actually within the #content, it tries to run them both... but I don't exactly know what to do.
Edit: So I've changed it to just manually set the width instead of adding/remove a class that specifies the width: http://codepen.io/anon/pen/Bmdny
The menu consistently opens now, however the links in the menu seem to be 'transparent' on subsequent opens. I.e, I see the blank background of the menu, but nothing in/on it, but I can still click the links. If I zoom in, even just a little bit, it seems to force the browser to repaint and the menu items appear.
Everything seems to work fine in Android's default browser, just not in Chrome for Android.
I've tried commenting out the css transitions, to no effect. I've tried giving the menu items a z-index higher than the menu itself (I'm desperate, lol), no change.
I just don't understand what's going on.
Thanks.
Info:
Chrome for Android v32
Android 4.3
Samsung Galaxy Nexus
What navigator are you testing it on? I can't reproduce the error on my phone nor my tablet.
However, it seems that as the button is over the #content div, when you click on it, you are clicking both elements.
Try to remove the class only when the menu has it:
$("#content").bind( "click", function() {
if ($('#mobile-menu').hasClass('open'))
$('#mobile-menu').removeClass('open');
});
EDIT
Let's try to put an intermediate layer between the menu and the content. Let's bind the menu-closing event to this layer.
Have a look at this: http://codepen.io/anon/pen/jiyHI
After much searching, tweaking, and hair pulling I began to narrow the problem down to having overflow:hidden; on my menu.
I came across a few random posts of various sources that described a problem similar to mine, and there were always suggestions that it had something to do with the overflow property, but at first I didn't understand.
I was 'hiding' the menu by setting width:0;, so in order to hide the content as well, I had to set overflow:hidden;. If I commented that line out, the menu opened fluidly and consistently, but of course: I could see the menu items all the time. Not what I wanted.
I tried transition the display property to learn that you can't do that. So I tried the visibility property, and at first that didn't work either. However, I came across this post from a guy trying to transition the display property, and this answer happened to work for me.
I still don't understand exactly why this works, I think it has something to do with delaying the second transition so it doesn't stop the first... Here's the article he linked in his answer.
So I guess the problem really had something to do with Webkit and fixed/absolute elements with ul's in them... not repainting after certain... anchor tag clicks? Or transitions? Yeah, I still don't really understand. But it works now!
Because there are a couple of skinned select boxes on my site, I am using dropkick.js, which essentially replaces the select boxes with interactive divs. If the list is larger than the max-height, the overflow-auto makes scrollbars appear. It works fine on Firefox, Chrome and Safari.
On Windows 8 + IE9 & IE10 a scrollbar appears, but when I click or try to drag it, the div hides!
> Link to the page
I have only found a slightly similar issue on a Bootstrap UI combobox but that script did not work for me, because dropkick.js does not use Bootstrap and adapting the script did not solve the problem.
> Link to similar bug
I was hoping it could be fixed with stopPropagation on the div but no luck on that either. Tried -ms-overflow-style:scrollbar but that does not change the behaviour.
Has anyone stumbled across a working fix for this in IE9+?
I had the same problem last week on one of my projects.
I solved it by changing the "click" event for closing the dropdown to "mousedown".
For some strange reason IE9+, on Windows 8, considers the scrollbar outside of the DOM element for click and mouseup events but for mousedown event it accepts the scrollbar as part of the DOM element.
By the way, I tried to reproduce the bug on your site but couldn't(Tested on IE10/Windows 8).
I am experiencing an incredibly bizarre issue with the isotope plugin in Firefox only. I have a textarea in each of my isotope elements and when I scroll down to the bottom and type in one of the textareas, the screen jumps to the top. I have reproduced this in jsfiddle:
http://jsfiddle.net/galtschul/WfTZ5/
I have been looking at this for hours and cannot figure out what is causing this scroll even to fire. Would love some help!
So, the problem is not with isotope. The problem is that there's a bug in how firefox renders textareas after a scale3d and/or transform3d occurs. It winds up "thinking" that the textarea is at the top left, which is why it jumps to the top. Here's are two bugs that were filed on Mozilla's bugzilla:
November 2011: https://bugzilla.mozilla.org/show_bug.cgi?id=703241
July 2012: https://bugzilla.mozilla.org/show_bug.cgi?id=778761
Chrome also suffers from rendering issues after the same transforms are applied. Namely, rendering of the caret. I filed a new but on Webkit's bugzilla that was quickly confirmed by a Webkit developer.
Here's an example of the bug: http://jsfiddle.net/galtschul/StbKg/
Click in any of the editable boxes before clicking the button ans see that the caret renders correctly. Then click the button, which will scale the textarea and observe that the cursor doesn't blink... type a few characters and then arrow left to observe the caret not moving... then type again to observe characters being inserted where expected.
Here's the bug report: https://bugs.webkit.org/show_bug.cgi?id=94985
Eagerly awaiting fixes!!
As I observed, its due to .isotope-item { position :absolute} property.
Tried lot, but really couldn't make out the solution.
I'm having a problem related to WebKit:
http://demo.frojd.se/webkit/index.html
When you click "Menu item 1" it shows it's children.
This renders fine in Firefox 3.5, IE8 and in Opera 10.
In WebKit-browsers (Safari 4 and Chrome 3) it doesn't.
However, if I preset all the different classes and css-settings in the
html, it renders correctly (without the javascript click events). I've got an URL to show you, but can't since this is my first post.
Any ideas on why this might be?
Cheers,
Robin.
I really haven't looked at the code closely, but something to look at in this situation is the padding or margin set on the menu item divs. In Safari, those are not taken into account with respect to width, so they may make the div or contents of the div expand wider than you expect, and that would cause the next element to be pushed to somewhere you don't expect it.
Not sure if that'll help, but it's some place you can look if you're still stuck.
Edit: After looking at the source using Web Inspector, it seems the divs with class = 'parentHook' are not wide enough after getting clicked on. After getting clicked on the class changes to 'parentContainer', which sets 'margin-left:-18px; margin-top:-15px;', and that seems to throw off the width of that div. In Web Inspector I changed the width of that div to 150px, and it worked as expected.
A true and ugly hack- but hey it works.
try hiding and showing on the click of the <li>
for a simple test: try this in console
$('#nav li:first').hide(50).show(50)