Monday 4 February 2013

JQUERY & BROWSER ISSUES

During the time that I've been using jQuery (about a year now), I've run into three fairly significant browser issues. Between IE, Firefox, Safari, and Opera, Firefox is the only browser that I have yet to experience any issues with (related to jQuery, of course).

IE 7

In certain situations, jQuery's $.browser.version will report IE 7 as version 6. Jamie Thompson noted one possible situation on his blog, but typically the issue is caused due to the fact that some copies of IE 7 included MSIE 6.0 within itsuser-agent string.
There is a jQuery Ticket open for the issue, but a solution has not been chosen. Based on some ideas that Jamie had, I came up with a possible solution by overriding the $.browser.version value:
jQuery.browser.version = jQuery.browser.msie && 
    parseInt(jQuery.browser.version) >= 6 && 
    window["XMLHttpRequest"] ? 
        "7.0" : 
        jQuery.browser.version;
Additionally, there are situations when I'm just looking for IE 6:
jQuery.browser.msie6 = jQuery.browser.msie && 
    parseInt(jQuery.browser.version) == 6 && 
    !window["XMLHttpRequest"];
It appears that these issues were resolved in IE 8 (at least in the beta version), but until jQuery releases a "fix", you'll have to deal with unreliable browser version detection in IE 7, or use one of the suggestions above.

OPERA 9.5

I discovered an issue getting the viewport height in Opera 9.5 while testing my rewrite of SimpleModal. It turns out that Opera, in an effort to follow standards, changed where it was storing the value for the viewport height...breaking the way jQuery was getting the value. Previously, the value was stored indocument.body["clientHeight"], but in 9.5 it was moved todocument.documentElement["clientHeight"]. There is also a jQuery Ticket open for this issue, and a patch has been added by Ariel Flesler.
For SimpleModal, I've added code that will fix the issue until it is fixed in jQuery:
// fix a jQuery/Opera bug with determining the window height
var h = $.browser.opera && $.browser.version > "9.5" && 
    $.fn.jquery <= "1.2.6" ?
        document.documentElement["clientHeight"] : 
        $(window).height();

SAFARI 3 (WINDOWS)

This is the smallest of the three issues, but annoying none-the-less. Take the following example:
$("<div/>").css({
    background: "#336699",
    color: "#fff",
    padding: "8px",
    width: "200px"
}).html("Loading...").hide().appendTo("body");
In Safari, the "loading" element will be visible when the page loads. In all other browsers, it is hidden (display:none). The issue occurs because the jQuery hide()function is supposed to look for "visible" elements and set the CSS display property to 'none'. However, in Safari, it appears that an element not yet in the DOM, already has a display property of 'none'...which sounds fine, right? It's not! Since it fails the visibility test, jQuery does not explicitly set the display property to "none".
Then, once the element is added to the DOM, it appears that Safari sets the elements display property to 'block'. So even though the intention was to have it "hidden", due to a Safari quirk (and lack of a jQuery internal solution), the element will be visible.
As I'm sure you've guessed by now, there is a jQuery Ticket open, but the suggestion is to just change the way you use jQuery. One suggestion is to move the .hide() after the .appendTo("body"). My problem with this is that it introduces the possibility of a flicker on the screen as the element is added and then hidden. The workaround I am using is to manually set the display property on the element:
$("<div/>").css({
    background: "#336699",
    color: "#fff",
    display: "none",
    padding: "8px",
    width: "200px"
}).html("Loading...").appendTo("body");
That concludes my notes about three browser issues I've encountered while using jQuery. If you've run into any issues where you've had to use a workaround, or have any other suggestions for the workarounds I used, feel free to mention them below!
And the moral of the story...use Firefox! :)

Sunday 3 February 2013

How to use jQuery to solve Javascript browser compatibility problems


How to use jQuery to solve Javascript browser compatibility problems

Anybody who's ever had to code JavaScript for public access sites knows what a headache it can be to make that scripting language behave as needed in IE, Firefox, Opera, Safari and Chrome. I'm sure others have wished, as I have, for a one-script-fits-all form of JavaScript that would cure the browser compatibility headache once and for all. I can't yet say that jQuery is a universal panacea for this particular problem, but I can say it's handled everything I've thrown at it so far and has let me (mostly) quit worrying about who's using which browser to visit my Web pages.
I'd like to share three great jQuery capabilities featured in Steven Holzner's jQuery Visual QuickStart Guide, which I recently reviewed for the publisher. Each starts with a link to a sample page that shows off the corresponding jQuery feature; where code samples aren't available on the page, you can of course take a look at the page's source.
  • Accordion style menu: Lets you present any number of distinct text areas on a single page, and expand/contract individual areas to maximize display space and information reach. This is a great visual tool for technical documentation. The jQuery Accordion Menu Tutorial has all the coding details (which are quite simple, actually).
  • Datepicker plug-in: This nifty plug-in provides an easy, convenient way to include an attractive and highly configurable date picker (much like the month-by-month display in Outlook Calendar's left-hand column or the Vista Calendar gadget). The jQuery datepicker (options) API page takes you through everything you need to know here.
  • Tabs widget: This great tool lets you break content up into tabbed page content. You can stack multiple sets of content on a single page , and you can even update pages to add or remove tabs on the fly. The UI/API Tabs page has pages upon pages of information for this fabulous tool.
As part of my testing for a book on jQuery I'm reviewing, I had to check these and all the other sample pages in IE 7 and 8, Firefox, Opera, Chrome and Safari. I never hit a single hitch along that path related to browser differences, interestingly enough. What an eye-opener this was for me, and what a pleasure it is to work with jQuery.
Visit the jQuery site for more information, tutorials, examples and more. You won't be sorry.
Ed Tittel is a full-time writer and trainer whose interests include XML and development topics, along with IT Certification and information security topics. E-mail Ed atetittel@techtarget.com with comments, questions or suggested topics or tools to review

Friday 1 February 2013

jQuery.support


The tests included in jQuery.support are as follows:
  • ajax is equal to true if a browser is able to create an XMLHttpRequest object.
  • boxModel is equal to true if the page is rendering according to the W3C CSS Box Model (is currently false in IE 6 and 7 when they are in Quirks Mode). This property is null until document ready occurs.
  • changeBubbles is equal to true if the change event bubbles up the DOM tree, as required by the W3C DOM event model. (It is currently false in IE, and jQuery simulates bubbling).
  • checkClone is equal to true if a browser correctly clones the checked state of radio buttons or checkboxes in document fragments.
  • checkOn is equal to true if the value of a checkbox defaults to "on" when no value is specified.
  • cors is equal to true if a browser can create an XMLHttpRequest object and if that XMLHttpRequest object has awithCredentials property. To enable cross-domain requests in environments that do not support cors yet but do allow cross-domain XHR requests (windows gadget, etc), set $.support.cors = true;CORS WD
  • cssFloat is equal to true if the name of the property containing the CSS float value is .cssFloat, as defined in the CSS Spec. (It is currently false in IE, it uses styleFloat instead).
  • hrefNormalized is equal to true if the .getAttribute() method retrieves the href attribute of elements unchanged, rather than normalizing it to a fully-qualified URL. (It is currently false in IE, the URLs are normalized).
  • htmlSerialize is equal to true if the browser is able to serialize/insert <link> elements using the .innerHTMLproperty of elements. (is currently false in IE).
  • leadingWhitespace is equal to true if the browser inserts content with .innerHTML exactly as provided—specifically, if leading whitespace characters are preserved. (It is currently false in IE 6-8).
  • noCloneChecked is equal to true if cloned DOM elements copy over the state of the .checked expando. (It is currently false in IE). (Added in jQuery 1.5.1)
  • noCloneEvent is equal to true if cloned DOM elements are created without event handlers (that is, if the event handlers on the source element are not cloned). (It is currently false in IE).
  • opacity is equal to true if a browser can properly interpret the opacity style property. (It is currently false in IE, it uses alpha filters instead).
  • optDisabled is equal to true if option elements within disabled select elements are not automatically marked as disabled.
  • optSelected is equal to true if an <option> element that is selected by default has a working selected property.
  • scriptEval() is equal to true if inline scripts are automatically evaluated and executed when inserted into the document using standard DOM manipulation methods such as .appendChild() and .createTextNode(). (It is currently false in IE, it uses .text to insert executable scripts).
    Note: No longer supported; removed in jQuery 1.6. Prior to jQuery 1.5.1, the scriptEval() method was the staticscriptEval property. The change to a method allowed the test to be deferred until first use to prevent content security policy inline-script violations.
  • style is equal to true if inline styles for an element can be accessed through the DOM attribute called style, as required by the DOM Level 2 specification. In this case, .getAttribute('style') can retrieve this value; in Internet Explorer,.cssText is used for this purpose.
  • submitBubbles is equal to true if the submit event bubbles up the DOM tree, as required by the W3C DOM event model. (It is currently false in IE, and jQuery simulates bubbling).
  • tbody is equal to true if an empty <table> element can exist without a <tbody> element. According to the HTML specification, this sub-element is optional, so the property should be true in a fully-compliant browser. If false, we must account for the possibility of the browser injecting <tbody> tags implicitly. (It is currently false in IE, which automatically inserts tbody if it is not present in a string assigned to innerHTML).

Examples:

Example: Returns the box model for the iframe.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<head>
<style>
p { color:blue; margin:20px; }
span { color:red; }
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<p>
</p>
<script>
$("p").html("This frame uses the W3C box model: <span>" +
jQuery.support.boxModel + "</span>");
</script>
</body>
</html>

Demo:

Example: Returns false if the page is in QuirksMode in Internet Explorer

1
jQuery.support.boxModel

Result:

1
false

Angular Tutorial (Update to Angular 7)

As Angular 7 has just been released a few days ago. This tutorial is updated to show you how to create an Angular 7 project and the new fe...