iframe shimming or ie6 (and below) select z-index bug - javascript

Uhm I'm not sure if anyone has encountered this problem
a brief description is on IE6 any <select> objects get displayed over any other item, even div's... meaning if you have a fancy javascript effect that displays a div that's supposed to be on top of everything (e.g: lightbox, multibox etc..) onclick of a certain element and that div overlaps a <select> your div get's to be displayed as if it's under the <select> [on this case a max and minimum z-index doesn't work ]
I've tried googling and found the iframe shim solution
but I wanted some pretty clean alternatives
or better yet has anyone found a better solution?
since the method using iframes uses around 130mb of ram might slow down poor people's machines

You don't have to hide every select using a loop. All you need is a CSS rule like:
* html .hideSelects select { visibility: hidden; }
And the following JavaScript:
//hide:
document.body.className +=' hideSelects'
//show:
document.body.className = document.body.className.replace(' hideSelects', '');
(Or, you can use your favourite addClass / removeClass implementation).

There is a plugin for jquery called bgiframe that makes the iframe method quite easy to implement.
Personally, as a web developer, I'm to the point where I no longer care about the user experience in IE6. I'll make it render as close to "correct" as possible, and make sure it's functional, but as far as speed goes, too bad. They can upgrade. IE7 (though still quite slow, compared to every other browser) has been out for 2 years (almost to the day!). IE8 is going to be out shortly. Firefox is available for every platform. Safari is also an option (and super fast). Opera is available for most/every platform.
IE6 was released in over 7 years ago. IMHO, there is no reason to still be using it, other than lazy users and incompetent IT departments (or if you're a web developer).

in case anyone is interested, here's some IE shimming code.
* html .shimmed {
_azimuth: expression(
this.shimmed = this.shimmed || 'shimmed:'+this.insertAdjacentHTML('beforeBegin','<iframe style="filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0);position:absolute;top:0px;left:0px;width:100%;height:100%" frameBorder=0 scrolling=no src="javascript:false;document.write('+"''"+');"></iframe>'),
'inherit');
}
ref: this gist by subtleGradient and this post by Zach Leatherman

Prior to IE7 the drop down list was a "windowed" control meaning that it was rendered as a control directly by Windows rather than the browser synthesizing it. As such, it wasn't possible for it to support z-indexing against other synthesized controls.
In order to appear over a DDL, you must use another windowed control, like IFRAME. You can also use a little known IE-only feature called window.createPopup() which essentially makes a chromeless popup. It has limitations, like unstoppable click-out, but they are actually kinda helpful if you are building a hover menu system.

The simplest and most elegant solution to that annoying IE bug is found at: http://docs.jquery.com/Plugins/bgiframe using jQuery.
I reached that conclusion after trying for 2 days to make it work with WebSphere Portal / Portal Applications where everything is dynamic, including the fly-over menu.

There's also the activex method, which I'm starting to explore. It requires creating conditional code to use an activex control instead of a select box for ie6. There's a demo script showing the technique, which is discussed in more detail here.
Update: it appears that MS Office is required for the active-x control to be on the user's machine. In theory, it might be possible to include that somewhere, somehow, but that's getting a lot messier.

I know many people suggested their own tips, but in my case, I just simply hide select using jquery like the below.
$(':date').dateinput({
format: 'dd/mm/yyyy',
onBeforeShow: function(event) {
$('select').hide();
},
onHide: function(event) {
$('select').show();
}
});

Related

On mobile phone, detect when user scrolls "past" top of screen

Imagine a mobile webpage with a navigation bar at the very top of the page.
Using javascript/jQuery I'd like to be able to detect when a user scrolls "past" the top of the screen.
Let me try to explain: Imagine that the webpage just loaded and you see the navigation bar at the very top of your screen. Now, you put your finger on the screen and drag down. On an iPhone, this will look something like:
I'm looking for something similar to the following:
$(document).ready(function () {
$(window).scroll(function (event) {
var y = $(this).scrollTop();
if(y < -20)) {
//do something
}
Unfortunately, this won't work on Android phones because they don't have the same elastic behavior as iPhones:
The bad news
So, let's start with the bad news: there is no way to get the information you wish for natively. Why? Because once you get into the 'elastic' zone you're dragging the entire webview component down rather than just the content of the document like in your pseudo code.
What does this practically mean? Emulation or Native wrapping
Emulation, the choices
So you will have to run your own solution and you will have to make a couple of choices. First of all if you wish to use elastic scrolling you should note that this is patented by Apple Inc. in patent US7469381 B2. Please go through this patent carefully to ensure you won't be infringing (even if you're building an iOS only app this does not change anything).
Secondly the question is whether you really want to emulate a native experience. There is a big lobby against native experience emulation due to 1) a believe that it can't ever be perfect enough and 2) as operating systems and browser change your code will stay out of date and thus look terrible/weird or possible can even cause entirely unexpected behaviour/combinations.
Secondly you will have to decide whether you wish for the same elastic behaviour on android or whether you wish to give a more native like experice on android. Personally I believe it makes for some excellent UX, so I wouldn't explicitedly disadvice you from using an elastic effect, however it is something you should consider carefully.
Emulation, the scripts
Most scripts that provide similar emulation to what you want are "pull to refresh" scripts. Depending on your specific wishes you should simply use one of those scripts and either alter them or use some CSS to hide the message inside them.
Hook.js - Not perfect emulation of the native experience and uses the old iOS background, but a pretty good option none the less, to hide the spinner just use
.hook-spinner{
display:none;
}
iScroll.js - Very well developed code and behaves excellently. Disadvantage is that it provides a lot more than what you're looking for which might be either a good thing or a bad thing. You can find a sample implementation of pull to refresh behaviour here, but do note it's for an older version of iScroll, in the last version the example seems not to have been implemented, but it should be quite similar. Just look at the code to see how to remove the pull to refresh message.
jQuery scrollz - Just one more option. Seems to be comparable to hook.js, but does have some iScroll like features as well. You can 'remove' the message by specifying the pullHeaderHTML with empty HTML strings.
Native wrapping
The alternative, which I am convinced you do not want to do, but I do want to add for the sake of completeness, is to distribute your app as a native app for example bundled up in phonegap. However to get this working would require a fair number of changes to the phonegap code itself and would not be an advisable approach (I have once developed a phonegap app using native components and interactions 'around' it triggering various javascript events, although doable and presenting certain advantages it's not something I would advice).
So..I'm not sure what do you need this for.
If it's for a ListView - you can override onOverScrolled
If you need this for ScrollView - there's a way by also extending it. I don't remember now, but if you need it - I can find it.
If it's for a WebView inside your app - I'm pretty sure it's not possible. The amount of control you have on the way web pages are rendered and manipulated is limited.
If you want the Chrome/stock browser to act the way it does on iOS - I don't think it's possible unless you get the browser's code and change it yourself :)

Support for turn.js in older browsers

I'm using turn.js for a page-flip effect, and it doesn't seem to work very well on IE7/IE8 (load up the website in IE7 mode and you can see for yourself).
What's the best way to support old browsers, while keeping the cool page-flip on modern browsers? (Note: I don't need the hot corners at all on IE, as I also have dedicated arrow links which flip the page via Javascript, similar to the turn.js demo.)
Do you have a sample of how you're applying turn.js? As in, do you have a link or how is your page structured? These are a good place to start.
More the the point of gracefully failing when you detect an older browser: There are multiple options, some make more sense than others depending on how much of the site is already done. First off, how does the site look with Javascript disabled completely? I know this isn't the case for IE7/8, but start there. Can it be used with no JS whatsoever? If the answer is "no," think of ways to make that answer "yes" if you can. This is always a good question when thinking about how to handle older browsers.
If you're early in the site's programming, or the content is laid out in a clear way, then you can work around the limitations of older browsers. A practice I try to follow is designing the site without JS or with as little as absolutely possible, and then program in functionality for "whizzing and banging" afterwards.
In your case, I would suggest something along the lines of: if you detect IE7/8 (or mobile browsers that may not be up to snuff, etc) then load in a secondary stylesheet with rules that give your content as much of the feel of the "original" as you can. Next, have the JS for the older browsers show/hide the pages of content instead of page-flipping them - this can be achieved with some divs on the left and right that move the page and then track the current page vs possible pages (are there any before this page? after this page?) in order to show/hide the navigation divs. turn.js just looks like fancy animations for the same thing, so you should be able to say "Hey, this browser is IE 7 or IE 8 - so, let's not initialize turn.js and just turn control over to the page previous and page next divs."

Javascript widget implementation

I have a question about Javascript widgets. The widget I am working on simply embeds content on a page instead of using iframes. So far it looks good. But there are cases where some users layouts are messing up the widget. For example, the widget might require a width of 300px to appear. But the parent div is set to 250px and hence the right part of the widget is cut off.
I was wondering what sort of precautions should be taken to prevent this? I was talking to the product manager who mentioned he wanted me to check the parent div elements and get the size and then show an alternate message if their size is not accurate. But again, since this is Javascript and the widget is supported in many diff browsers(including IE6), I am wondering how fail-safe this method would be? What if I need to iterate the DOM all the way up before getting a valid size? I am also worried about performance here. This extra checks would slow down the delivery of my widget content to "good users" since I am adding a layer of complexity to all users. I don't want to penalize good users just because of the few errant ones.
I am not using any sort of JS library here, so any solution should not suggest the use of one. Also, the reason for not using a library was simply not to add extra weight to the page load to deliver a widget. I understand that "jquery" for example is small, but in my case, even 24k compressed seems like an overkill for a widget delivery that contains no core code for the widget.
Has anyone dealt with such issues before? What are your solutions to these?
There are reliable ways of determining the size of an element using JavaScript. You're quite right that you may need to iterate up the tree in some cases, but the answer you get will ultimately be quite valid.
Although you don't want to directly include any library code in this project, you may consider looking at how the major libraries implement their "what's the width of this element" functions to drive your own implementation.
Beware of quirks mode too.
I'd check to see of the page has Jquery, if not load it into the page using no-conflict mode. Then use jQuery to examine the page.
See: How to embed Javascript widget that depends on jQuery into an unknown environment

Editable DOM in HTML, like Google Docs

I'm a little curious about how the editing of Google Docs works. How did they implement an editor within the DOM? It does not really looks like a form with a textarea, but rather a normal document body with an additional cursor. I guess it is some javascript technique behind.
Is there any free library that I can use for achieving this kind of functionality, or how can I implement it myself?
2019 Update
I'm pretty certain the answer below was accurate at time of writing in 2010 but has been substantially inaccurate for several years. Here's an answer of mine to a similar question in 2012 that may be more accurate, although still possibly not massively helpful.
How does Google Docs achieve content editing?
Original answer
It uses editing functionality built into all modern desktop browsers, accessed at document level via setting the designMode property of the document to "on", or at an element level by adding a contenteditable attribute with value "true" (also triggered by setting the contentEditable property of an element to the string "true").
A very common strategy for editing a piece of content in a web page is to include an iframe whose document has designMode turned on.
Coupled with this is document.execCommand, which in an editable document can be used to apply various kinds of formatting. For example:
document.execCommand("bold", false, null);
... will toggle whether the selected text is bold. There is a pool of common commands between browsers but there are some discrepancies as to exactly how some are implemented. More info can be found here at MSDN for IE and here at MDC for Firefox. Can't seem to find documentation for WebKit.
Since mid-2010 Google Docs seems to completely having switched away from relying on the browser for editing mode.
Instead they built their own text/HTML editor using JavaScript and DOM.
They explain it in a lengthy blog posting on how they implemented the functions.
Having searched for 3rd-party vendors offering similar concepts, I found no one so far. Would have been a great for iOS since they seem to not support the contentEditable attribute until iOS 5 (and even then, there are issues)
For mee it looks like any HTML editor. They just coded their own JavaScript HTML editor. Even the HTML edit view doesn't have any magic.
A good and free HTML editor is TinyMCE but there are many others out there, even some very powerfull proprietary like CuteEditor which is available for PHP and ASP.NET.
BTW: The content of the document (in Google Docs) is placed in an iframe, just as it is in CuteEditor (and probably also in TinyMCE).
As other people have said, google is very uptight about what information they share. However, they have posted a lengthy blog idea about how they built their own word processing system FROM SCRATCH. Building this, would require you to have your own experience team with several days needed to complete it.
Link to lengthy blog is here:
https://drive.googleblog.com/2010/05/whats-different-about-new-google-docs.html
Essentially, they capture where your cursor is, place a div that looks like a line, and manually insert a letter at the place your cursor is

What happens to my web application if JavaScript is disabled?

I'm learning jQuery and am about to write some pages using intensively that library. I just learned that some user disable JavaScript on their browser (I didn't even know that was possible and/or necessary).
Now, here's my question: What happens to my web application if a user disable JavaScript? For instance, I'd like to display some screens using AJAX and commands such as 'InsertBefore' to bring in live a DIV that will display the result.
So, if JavaScript is disabled, I wonder what going to happen to all this work that relies on JavaScript?
I'm kind of lost.
Thanks for helping
You may want to start by reading on Progressive Enhancement and Unobtrusive JavaScript.
I would also suggest to investigate how popular rich web applications like GMail, Google Maps and others, handle these situations.
I just learned that some user disable javascript on their browser
I do. The "NoScript" plugin for FireFox does the trick.
So, if Javascript is disabled, I wonder what going to happen to all this work that relies on Javascript?
It won't be functional.
A good practice suggests designing a site not to rely on JavaScript for major functionality. At least, accessing its content (in read-mode) should be possible. JavaScipt should only add interface enhancements like Ajax techniques etc. But the fallback version should always work.
I feel really sad when I see a site which is completely broken without JavaScript. Why can't people use CSS to put elements in proper places? Why do they try to align elements with JavaScript even if there is no dynamics involved?
The same goes for Flash sites. Once in a while a land upon a "web-design-agency" site which makes picky comments about me not allowing JavaScript. When I do I only see a basic primitive site with a few menus and that's it. What was the point of using Flash when the work is so primitive it can be done with raw HTML and CSS in an hour? For me it's a sign of unprofessional work.
All what's done in JavaScript won't work. Some users disable it for security reasons, NoScript is an excellent example. You can try it yourself by removing the scripts from your page or installing the NoScript-plugin for Firefox.
As a rule of thumb:
Make the website working with only semantic HTML
add the CSS
add the JS
But the website should be (almost) fully functional in stage 1.
If you disable Javascript in Safari things like Lexulous in Facebook won't work properly, the mouse letter carry function doesn't work.

Categories