2

Imagine that I have a couple of statements as following:

var n1 = oDiv.firstChild;
var n2 = oDiv.lastChild.previousSibling.firstChild; //know this crazy, but for knowledge sake

How can I apply various styles like the following (which usually works only for "element" types and not "node" types):

//does not work
n1.style.borderWidth = "1px";
n1.style.borderColor = "#336699";
n2.style.borderStyle = "solid";

Also, is there any way to typecast "node" to "element" in JavaScript?

update:

The code I am trying to accomplish above is here http://jsfiddle.net/anthachetta/4mXrd/

user203687
  • 6,875
  • 12
  • 53
  • 85
  • what do you mean by typecast node to element in java ? – mas-designs Nov 28 '12 at 16:08
  • By any chance, if I can convert "node" object to "element" object in JavaScript.. – user203687 Nov 28 '12 at 16:09
  • No, you can't, and it has nothing at all to do with JavaScript. You're working with native browser objects, and what they do is essentially cast in stone. – Pointy Nov 28 '12 at 16:09
  • Oh. How about applying styles to "node" objects? – user203687 Nov 28 '12 at 16:10
  • like so `Object.style.background="color image repeat attachment position"` make sure your object is really being loaded – mas-designs Nov 28 '12 at 16:11
  • Why -1 for my question. If we cannot do what I asked, you guys can simply say, we cannot do that due to so and so reason. This is very disappointing/discouraging. – user203687 Nov 28 '12 at 16:18
  • There is probably a solution for you, but you are looking in the wrong direction. I think it would help if you posted a more specific problem geared more towards the visual effect you are trying to create. – Aaron Kurtzhals Nov 28 '12 at 16:19
  • BTW, I tried to make a jsfiddle of it here: http://jsfiddle.net/anthachetta/4mXrd/ – user203687 Nov 28 '12 at 16:19
  • I know, we can do it more easily with jQuery or CSS. It is all for the learning sake and just wanted to check if I can apply style to a "node" object. – user203687 Nov 28 '12 at 16:22
  • See the following question for information about nodes and elements http://stackoverflow.com/questions/9979172/difference-between-node-object-and-element-object – Aaron Kurtzhals Nov 28 '12 at 16:23
  • The problem is that firstChild doesn't do what you expect. It selects new lines and whitespace along with elements. See [this answer](http://stackoverflow.com/a/2299908/551093) for a proposed solution. – Christian Nov 28 '12 at 16:24
  • The answer was skipping text nodes. But, I am trying to apply style to the text node itself. Also, there are no spaces or new lines in my code. You can check my code here: http://jsfiddle.net/anthachetta/4mXrd/ – user203687 Nov 28 '12 at 16:30
  • @user203687 Applying style to text nodes doesn't make sense in HTML. In HTML it's impossible to apply css styles to plain text without surrounding it with ``s. So in the DOM the same rule apply. You need to either create a and surround that text node with it and then apply the style to that tag or find out what tag that text node is a child of and apply your style there. – slebetman Nov 28 '12 at 16:35

2 Answers2

1

The DOM works exactly the same way as HTML does. That makes sense since the DOM was designed to model HTML as objects. So, what do you do if you want to make the following bold:

Hello World

From your code, what you're trying to do is something like this:

style=font-weight:bold Hello World

Obviously that wouldn't work because it's not valid HTML. What you'd normally do is this:

<span style='font-weight:bold;'>Hello World</span>

So you need to do the same in the DOM:

// Assume you have a div "div" and the first child
// is the text node "Hello World"

var hello_world = div.firstChild;

// Now, you want to make Hello World bold.
// So you need to create a span:

var span = document.createElement('span');
span.style['font-weight'] = 'bold';

// Now wrap hello_world in the span:

span.appendChild(div.removeChild(hello_world));

The above is actual working DOM code that does what you want. But beware:

  1. Standards compliant browsers also count whitespace as nodes.
  2. IE doesn't count whitespace as nodes.

For example, if your HTML looks like this:

<div>
    <span>Hi</span>
</div>

the standard says your DOM must look like this:

div +
    |---- text node (whitespace)
    '---- span +
               '---- text node (Hi)

but IE does what most people probably expect:

div +
    '---- span +
               '---- text node (Hi)

This means that you can't blindly trust node.firstChild without checking to see if it's what you expect.

slebetman
  • 109,858
  • 19
  • 140
  • 171
  • Thanks for the reply. That really made sense. Can you level my question to 0 (as it is -1) now. I hope my question is still valid. – user203687 Nov 28 '12 at 16:53
1

There are a few problems.

What is with the lastChild.previousSibling.firstChild mess? All that's doing is confusing you.

That mess of properties is returning you a text node, not an element.

lastChild gives you "a line", previousSibling gets the <i> tag, then firstChild returns "just". You are trying to apply a style to a text node, which you can't do, you need to style an element.

You are trying to apply the style to the nodeValue. That's a string. You can use parentNode to get to the <i> tag from the text node.

oDiv.lastChild.previousSibling.firstChild.parentNode.style.color = "#FF0000";

DEMO: http://jsfiddle.net/NTICompass/4mXrd/2/

gen_Eric
  • 223,194
  • 41
  • 299
  • 337