Archive

Posts Tagged ‘Javascript’

Javascript: Exception thrown and not caught

May 14th, 2011 Nick No comments

I recently started getting this Javascript error message on every page in my application:

Exception thrown and not caught

Interestingly, I only got this message in Internet Explorer (IE7) and only on the first page view after clearing my temporary internet files (cache). If I refreshed the page, the error was gone and only reappeared when I cleared my browser cache – again disappearing after a page refresh.

My suspicion was that some Javascript in the HTML was trying to call a function or a method on an object that was declared in an external Javascript file, crucially before that external file had loaded from the server. This would explain the fact that the error disappeared after a page refresh, as the external file would already be available from the browser cache.

The solution was simple – I wrapped the Javascript that was in the HTML file using jQuery’s $(document).ready() function and the problem was solved.

Interesting note for Wicket users:

My application is built in Wicket and I embed the Javascript into the HTML response using AbstractBehavior.renderHead(IHeaderResponse response). Initially I used response.renderOnDomReadyJavascript(String javascript) which executed the Javascript once the DOM was ready but before the external Javascript dependencies were loaded. My first attempt to fix this was to used response.renderOnLoadJavascript(String javascript) which, as the JavaDoc states, executes the Javascript after the the entire page is loaded. This worked fine, except when the behavior was applied to components rendered in an Ajax response, as of course there was no page load event when the ajax request completed.

My solution was to move back to using response.renderOnDomReadyJavascript(String javascript) and, as stated above, wrap my Javascript in jQuery’s $(document).ready() function.

Categories: Javascript Tags: , ,

Dynamic CSS pseudo class styles with jQuery

November 10th, 2009 Nick 4 comments

The problem

On Glogster we recently made a new little Flash widget to allow users to “skin” their profile pages – allowing them to change the colour of text, backgrounds and so on to make their part of Glogster more personal.

It works by saving all the definitions (i.e. div.p = #ff0000, etc) to the database and then generating a custom CSS file which is loaded on the profile page to override the default style.   We also needed a “preview” mode whereby the changes made in the Flash widget would be immediately visible on the page to allow the user to see what the page would look like before saving the skin.

No problem, I thought, when I first saw the brief.   We can use jQuery to easily change styles dynamically.   Indeed we could, but not pseudo classes for things such as :hover on links.   I did a bit of searching and I couldn’t find a way of doing it using jQuery, so I made one.

The solution

I decided on an object oriented approach as I needed a way to keep track of what style properties the Flash widget has sent and update definitions accordingly.   Using an OO approach allowed me to model components of a stylesheet individually thus allowing client code to construct a new stylesheet by use of these components.   For example if the Flash widget sent a “color” definition for the CSS selector “div#main p”, an then sent another definition, let’s say “font-size” for the same selector, then I would need some way to group these definitions together.   So I made three classes:

StyleSheetElement
Contains a property and value pair for example “color” and “#ff0000″.

StyleSheetTag
Contains StyleSheetElement objects for a given CSS selctor, for example “div#main p”.

StyleSheet
Contains StyleSheetTag objects.   Orders the StyleSheetTag objects and creates CSS output.

The implementation

On to an example:
http://www.4pmp.com/examples/javascript-dynamic-pseudo-classes/test.html

    // Create a new StyleSheet instance
    var sheet = new StyleSheet();

    // Create a CSS element to set colour to green
    var elementBasic = new StyleSheetElement("color", "#00ff00");

    // Attach the CSS element to the CSS description for "a"
    var tagA = sheet.addElementToTag("a", elementBasic);

        // Set the order of the tag for "a"
        tagA.order = 2;

    // Create a CSS element to set colour to red
    var elementHover = new StyleSheetElement("color", "#ff0000");

    // Attach the CSS element to the CSS description for "a:hover"
    var tagHover = sheet.addElementToTag("a:hover", elementHover);

        // Set the order of the tag for "a:hover", will appear beore "a"
        tagHover.order = 1;

    // Create a stylesheet for the new elements and add it to the page (replaces it if one already exists)
    addInlineStyleSheet(sheet);

The first step is to create a SyleSheet object that will contain the style definitions and create the CSS.

The second step is to create a StyleSheetElement for the property you want to set and the value you want to set it to.

Next, you need to add that element to the StyleSheet object along with a CSS selector.   If the StyleSheet does not already contain a tag for the given CSS descriptor then it will first of all create one, then it will see if the tag already contains an element for the same property as the element being added.   If it does then the new element replaces the old one, otherwise the new element is just added to the tag.

You may notice that StyleSheet::addElementToTag() returns the tag that the element was added to.   This is useful if you want to set the order of the tags.   Sometimes you will have tags that need to appear higher up in the resulting CSS, set the StyleSheetTag.order property to achieve this, the smaller the number the nearer the top it will appear.

The final stage is to generate the CSS and add/replace it in the page.   To do this, just call addInlineStyleSheet() and pass it the StyleSheet object you’ve just made.

What about Internet Explorer?

Of course, IE managed to throw a spanner into the works by not supporting changing inline stylesheets.   Well, it does support them in that it’s possible to change the actual HTML, but it has no effect on the rendering of the page.   Great.   So I found a workaround, if the browser is a flavour of IE, then the addInlineStyleSheet() function compiles the StyleSheet object not to CSS but to a list of tags and CSS rules which are then applied in turn by calling document.styleSheets.inlinestyle.addRule().

Download

StyleSheet.001.js

Shout me a coffee

If this article has been useful to you and you want to say “thanks”, then why not shout me a coffee by donating through PayPal?


Thanks!