Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS doesn't apply to dynamically created elements in IE 7?

Still looking for an answer.

Changing or reassigning to the filter's innerHTML successfully redraws the element, but breaks my script, so that's out.

Adding additional child nodes, including text nodes, does not force a redraw. Removing the added node does not force a redraw.

Using the ie7.js family of scripts does not work.


In the project I am working on, I dynamically generate (with javascript) filters that look like this:

<div class="filter">
    <a ... class="filter_delete_link">Delete</a>
    <div class="filter_field">
        ...
    </div>
    <div class="filter_compare">
        ...
    </div>
    <div class="filter_constraint">
        ...
    </div>
    <div class="filter_logic">
        ...
    </div>
</div>

And I have CSS that applies to each filter (for example):

.filter a.filter_delete_link{
    display:block;
    height:16px;
    background: url('../images/remove_16.gif') no-repeat;
    padding-left:20px;
}

However, it seems in IE 7 (and probably 6 for that matter), these styles don't get applied to the new filters.

Everything works perfectly in Firefox/Chrome/IE8.

Using the IE8 developer tools, set to IE7 mode, the browser can see the new elements, and can see the CSS, but just isn't applying the CSS.

Is there a way to force IE to reload styles, or perhaps is there a better way to fix this?


The JavaScript: (simplified)

var builder = {
    ...
    createNewFilter: function() {
        var newFilter = document.createElement('div');

        var deleteLink = document.createElement('a');
        deleteLink.href = '#';
        deleteLink.setAttribute('class','filter_delete_link');
        deleteLink.title = 'Delete Condition';
        deleteLink.innerHTML = "Delete";
        newFilter.appendChild(deleteLink);

        var field = document.createElement('div');
        field.setAttribute('class','filter_field');
        var fieldSelect = this.getFieldSelectBox();
        field.appendChild(fieldSelect);
        newFilter.appendChild(field);

        // more of the same...

        deleteLink.onclick = function() {
            builder.removeFilter(newFilter);
        };
        fieldSelect.onchange = function () {
            builder.updateFilter(newFilter);
        }

        return newFilter;
    },
    addNewFilter: function() {
        var nNewFilter = this.createNewFilter(this.numFilters++);
        this.root.insertBefore(nNewFilter,this.nAddLink);

        //other unrelated stuff...

        //provided by Josh Stodola
        //redraw(this.root);

        return nNewFilter;
    }
}
like image 534
Austin Hyde Avatar asked May 27 '10 14:05

Austin Hyde


People also ask

Can we change CSS dynamically?

color = "red"; you can apply the style change dynamically. Below is a function that turns an element's colour to red when you pass it the element's id . You could also use setAttribute(key, value) to set a style on an element. For example, you could set the colour of an element to red by calling element.

How do you apply dynamic class to an element?

In this article, we will see how to dynamically create a CSS class and apply to the element dynamically using JavaScript. To do that, first we create a class and assign it to HTML elements on which we want to apply CSS property. We can use className and classList property in JavaScript.

How do you create new element dynamically?

New elements can be dynamically created in JavaScript with the help of createElement() method. The attributes of the created element can be set using the setAttribute() method.

How do I create a dynamic element in HTML?

With document. createElement() method you can create a specified HTML element dynamically in JavaScript. After creation you can add attributes. If you want the element to show up in your document, you have to insert in into the DOM-tree of the document.


2 Answers

The problem, I've discovered is that IE 6/7 doesn't register the class name changes with elm.setAttribute('class','x') until the UI is redrawn.

The solution is to use the form elm.className = 'x'

**This problem was also noticeable from moving from IE9 quirks to standards mode. The solution was the same.

like image 182
Austin Hyde Avatar answered Oct 13 '22 01:10

Austin Hyde


Sounds to me like you need to force a redraw of the UI for this element. There are several ways to do this, but the following is the most effective method...

// elm is a reference to your element
var disp = elm.style.display;
elm.style.display = "none";
var redrawFix = elm.offsetHeight;
elm.style.display = disp;

Here is another method I found on Ajaxian...

function redraw(elm) {
  var n = document.createTextNode(' ');
  elm.appendChild(n);
  setTimeout(function(){ n.parentNode.removeChild(n) }, 0);
  return elm;
}
like image 39
Josh Stodola Avatar answered Oct 13 '22 00:10

Josh Stodola