In both the browsers there is a way to add new layers to the page on the fly (after the page is fully loaded). Again this is a situation where the solution is completely different between the browsers. And in both cases there is a crippling obstacle that makes it impossible to use this technique to it's full potential.
Creating a New Layer:
In Netscape, to add a new layer to the page you simply create a new Layer object:
document.layers[id] = new Layer(width)
After the layer is created you can then assign the properties and add the content to the layer using JavaScript:
document.layers["mylayer"] = new Layer(400)
document.layers["mylayer"].left = 40
document.layers["mylayer"].top = 100
document.layers["mylayer"].height = 300
document.layers["mylayer"].bgColor = "blue"
document.layers["mylayer"].visibility = "show"
document.layers["mylayer"].document.open()
document.layers["mylayer"].document.write("This is my content")
document.layers["mylayer"].document.close()
etc.
Once all this is done, you can use the layer as normal.
Removing a Layer:
Although it is not specifically stated in the documentation, you can also delete a layer as easily as it is created. To accomplish this you hide the layer, and then delete the reference to it:
document.layers["mylayer"].visibility = "hide" delete document.layers["mylayer"]
This will work as expected, and you will no longer be able to reference the layer. However it is not possible to replicate this in IE it is not recommended (read the IE section).
The Problem: Nested Layers
A huge oversight on the part of Netscape is that it doesn't appear that you can dynamically create a nested layer. The logical way to do it would be:
document.layers["parenLayer"].document.layers["childLayer"] = new Layer(400)
But whoops! It doesn't work. It just creates a new non-nested layer that is referenced as if it were nested. This seriously hinders the usefullness of this technique.
Internet Explorer's ability to work with HTML as if it were a string allows you to add more layers as you please. I recommend this be done using IE's insertAdjacentHTML(). If you use the innerHTML property it will cause some unexpected results.
To add another layer (or any other HTML for that matter) to the body of the document, you call the method in this manner:
document.body.insertAdjacentHTML(string)
Where string is a string of text or HTML that needs to be appended to the end of the page. So to create a layer you can pass a DIV tag with the style assign using the old inline technique if you prefer (remember IE doesn't have problems with inline styles):
document.body.insertAdjacentHTML('
<DIV ID="layerName" STYLE="position:aboslute; left:40; top:100;">
This is my content
</DIV>')
This is one situation were IE's solution is superiour - to create a nested layer you can apply the insertAdjacentHTML() method to the parent layer just as you do the body of the document:
document.all[id].insertAdjacentHTML(string)
The Problem: Removing The Layer
Unfortunately Microsoft did not include any specific way to delete a layer. The only way to do it is by changing the innerHTML property.
Here's a function I made to see if it could be done:
function removeLayer(id) {
var str = document.body.innerHTML
var start = str.indexOf('<DIV id='+id+' ')
if (start > -1) {
var end = 0
for (var i=start; i<str.length; i++) {
if (str.substring(i,i+6) == '</DIV>') {
var end = i+6
break
}
}
document.body.innerHTML = str.substring(0,start)+str.substring(end)
}
}
This function resets the innerHTML so that it rewrites the page excluding the layer passed to it.
And yes this does work... BUT, there is a problem with doing it this way that I did not expect. I didn't even notice the problem until I incorporated my DynLayer into my experiment. After you remove a layer, none of the other DynLayers that you have will work properly. For example if you remove one of the layers, and then try to move a different layer using the DynLayer, the layer itself won't move. It took me a while to come to a conclusion about why this was occuring.
The thing that had me pulling my teeth out is that there's nothing wrong with the DynLayer. It works just as it should, if you retrieve any of the properties (eg the x or y values) they do change if you change the location of the DynLayer. But the layer that is actually shown on the screen doesn't move at all. So then I tried to move the layer explicitly:
document.all["mylayer"].style.pixelLeft += 10
And to my surprize that works fine. So why doesn't the DynLayer work? Well I can only assume that by reseting the innerHTML, you in turn create new instances of the layers that are on the page. Since the DynLayers would have been assigned to the previous instances of the layers, their layer reference has been broken. They reference a different layer that is not shown on the screen. I believe this to be a flaw in the Dynamic HTML Model in Internet Explorer. The developers of IE didn't seem to anticipate that a layer might be referenced as a variable rather than explicitly. If you were to always reference the layers explicitly there wouldn't be any problems because you'd always be referencing the "top-most" instance of the layer. The only way around this would be to reassign all your DynLayers every time you remove a layer - and obviously that's not feasible.
So forget about removing layers in a cross-browser environment.
Getting back to creating layers... instead of explicitly writing code for each layer that you want to create, you can use this cross-browser function:
function createLayer(id,left,top,width,height,content,bgColor,visibility,zIndex) {
if (ns4) {
document.layers[id] = new Layer(width)
var lyr = document.layers[id]
lyr.left = left
lyr.top = top
if (height!=null) lyr.clip.height = height
if (bgColor!=null) lyr.bgColor = bgColor
if (zIndex!=null) lyr.zIndex = zIndex
lyr.visibility = (visibility=='hidden')? 'hide' : 'show'
if (content) {
lyr.document.open()
lyr.document.write(content)
lyr.document.close()
}
}
else if (ie4) {
var str = '\n<DIV id='+id+' style="position:absolute; left:'+left+'; top:'+top+'; width:'+width
if (height!=null) {
str += '; height:'+height
str += '; clip:rect(0,'+width+','+height+',0)'
}
if (bgColor!=null) str += '; background-color:'+bgColor
if (zIndex!=null) str += '; z-index:'+zIndex
if (visibility) str += '; visibility:'+visibility
str += ';">'+((content)?content:'')+'</DIV>'
document.body.insertAdjacentHTML("BeforeEnd",str)
}
}
The usage should be obvious. You must pass the name of the layer (id), left, top, and width properties, the rest are optional. After you create the layer you could assign DynLayers to them and work with them that way. I've created 2 demos that should illustrate how you can use this function:
creating1.html - a simple example that creates one layer, and makes it a DynLayer.
creating2.html - a more complex example, utilizing the drag object to create multiple layers.
| Home |