Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Getting Properties and Property types 1

Status
Not open for further replies.

Borvik

Programmer
Jan 2, 2002
1,392
US
I'm using the following function to retrieve all the properties of an object:
Code:
function getProperties(obj) {
	var i, v;
	var count = 0;
	var props = [];
	if (typeof(obj) === 'object') {
		for (i in obj) {
			try{
				v = obj[i];
				if (v !== undefined && typeof(v) !== 'function' && typeof(v) !== 'object') {
					props[count] = i;
					count++;
				}
			}catch(err){}
		}
	}
	return props;
}

The only difficulty is that later when I try to set some of those properties I get the error: "setting a property that has only a getter."

Now I realize that I probably shouldn't be setting that property then (and don't ask WHICH property - it really doesn't matter, this is going to be dynamic, so lets say its ALL the returned properties).

How can I modify the function above to return only those properties that are "setters" - or how can I easily tell if a property is a "setter"?

Thanks.
 
You could try setting each property, surrounded with a try/catch block. If execution falls into the catch block, then you know there's an error, and chances are it's because you are trying to set a read only property.

Thus, you'd know which properties are able to be set, and which are not.

Hope this helps,
Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
Thanks BillyRay,

I was thinking about that this morning, I was just wondering if there was a "reflection" way to determine that.

I could probably use something like this then (with the try catch of course):?
Code:
obj[i] = obj[i];
 
Ok - it worked and didn't work.

Just for contexts sake, I'm developing an AJAX framework based off of SAJAX (php) and JSON that will allow the PHP functions access to the properties of the HTML DOM.

Code:
function buildDOMVar(){
	var ids = getIdsAndClasses()['ids'];
	var domRes = {};
	for(idx in ids){
		domRes[ids[idx]] = {};
		var domObj = document.getElementById(ids[idx]);
		var props = getProperties(domObj);
		for(propIdx in props)
			domRes[ids[idx]][props[propIdx]] = domObj[props[propIdx]];
	}
	return domRes;
}
function getProperties(obj){
	var i, v;
	var count = 0;
	var props = [];
	if(typeof(obj) === 'object'){
		for(i in obj){
			if(i.toLowerCase() == 'textcontent' || i.toLowerCase() == 'outerhtml')
				continue;
			try{
				v = obj[i];
				if(v !== undefined && typeof(v) !== 'function' && typeof(v) !== 'object'){
					[red]obj[i] = obj[i];[/red]
					props[count] = i;
					count++;
				}
			}catch(err){}
		}
	}
	return props;
}
As you can see here I modified the gathering of an object's properties with the code above. By placing it in the already existing try...catch block, but before the property gets added to the returning array it prevents readonly properties from being returned.

This works fine in FireFox, though when the buildDOMVar function is called in IE (using IE7 btw) - it turns this:
Code:
<body>
<p>
	<span id="lblText" class="class1">Test</span>
	<button id="cmdButton1">Button</button>
	<input type="submit" id="cmdSubmit1" value="Submit" />
	<input type="text" id="txtTextbox1" /><br />
	<textarea id="txt1" rows="25" cols="75"></textarea>
</p>
</body>
into this:
Code:
<BODY><P>TestButton  <BR> </P></BODY>

The HTML document has been successfully checked as XHTML 1.0 Strict.

Might there be any other way to check if a property is readonly and therefore not blow up IE?
 
I almost found something: __lookupSetter__, but apparently that is not supported in IE, as it just doesn't work period.
 
I found that the properties that caused most of the problems (in both IE and Fx) were 'innerHTML', 'outerHTML', 'innerText', and 'outerText'. So I skipped setting those, but found there were many other "normal" properties that also screwed thing up (e.g. "height" in IE6).

Talking with one of the other regulars here, he suggested creating a new in-memory element of the same type as the one you are interested in, and trying to set its properties instead. That way, your on-page elements will never be affected.

I think that's probably the best way to go if you don't want to have to worry about skipping arbitrary properties for different browsers.

Hope this helps,
Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
Thanks BillyRay,

I think that's probably the best way to go there, and it works in both IE and Firefox. So now I have it doing the assignments to the memory element created from "obj.cloneNode(false);"

I may have to come up with a mapping scheme though as IE and Firefox even handle assignments differently. For example a button (declared <button id="name">Text</button>). In IE using innerHTML to set the button text doesn't work you have to use:
Code:
document.getElementById('name').value = "new value";
Whereas in Firefox you have to use innerHTML and not the value property.
 
Both are correct assumptions.

It was originally an excerise in read-only, now as that is working (thanks btw) I'm rambling about how the project is practically making this moot.

Either way - what you proposed did indeed work, and whether I end up using it or not - at least someone in the future can find this solution.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top