why this javascript is line is Right and the other isn't - javascript

javascript with>
var customer=document.getElementById('custList').value;
and that works...
Why does it work BUT...
var customer=(form1.custList.value);
I get an error that form1 is not defined.
Especially why would this work in IE, and Chrome but not Firefox.
It seems just as clearly stated to me, but I am not a script engine
Just trying to understand

if you want to refer to a form object in your page, you may use the 'document.forms' object, that is an array of form objects in the document. suppose we have a form like this:
<form method="post" action="somthing.php" name="myContactForm" id="contact_form">
<input type="text" name="custList" id="custListId" />
</form>
to access the value in a correct way, you might use any of these methods:
first acccess the form, then the element.
var form = document.forms['myContactForm']; // use the 'name' attribute as the array key
// or if this is the first form appeared in the page. otherwise increase the index number to match the position of your target form.
var form = document.forms[0];
// or access the form directly
var form = document.getElementById('contact_form');
// now get the element, from the form. you can access form elements, by using their name attribute as the key in the elemetns array property of the form object.
var cust = form.elements['custList'].value();
or you can access a form element directly, without any form. you can refer any element in the document by its id, directly. no form is needed here.
var cust = document.getElementById('custListId');
all these statements are valid JavaScript that run on IE, firefox, opera, chrome, etc.
however you can refer to a form object in IE, by just calling its 'name' attribute. so this line works in IE (and as you are saying, chrome. I did not know that chrome handles it):
var cust = myContactForm.custList.value();
IE tries to map unknown window level properties (like myContactForm ) to elements by matching to their 'name' attribute.

I believe IE/Chrome/Opera incorrectly interpret id="form1" as name="form1" ( or vice versa? ) to account for legacy markup.
I would not rely on dom 0 level property accessing such as form1.custList and instead use document.getElementById. If it's too long to type, define a method to do it.. eg
function getId( id ) { return document.getElementById(id) }

Because the second idiom is not standard, while getElementById is, so it has to be supported by every browser to say that is javascript compatible.
Also, the second one should be, if I'm not mistaken, document.form1.custList.value.

Internet Explorer did a lot of things in it's own way. By all means, the first way is the correct way (using getElementById).
For backward compatibility many of these "bugs" still work, but you should not use them.
There are still differences between browsers. Using a JavaScript framework (like jQuery) helps a lot here, it is written to work well cross-browser (for the record, your code will be $('#custList').val(); using jQuery)

Internet Explorer stuffs all of your form elements by name into the window object as properties, which is fragile, incompatible, difficult to use with any finesse -- and what makes your second example work. Other browsers simply take the clean route of not implementing that interface at all, leaving you with the proper DOM functions. Or a toolkit. jQuery really is quite nice. ;)

Related

How to tell the type of a JavaScript and/or jQueryobject

This question pertains as much to the ECMAScript language implementation we know as JavaScript as it does to jQuery and the developer tools availble in most popular browsers.
When you execute a statement like so:
var theElement = $('#theId').closest();
what is the type of theElement?
I assume that in a jQuery situation like above, many jQuery methods including the one above actually return the jQuery object itself, which packages the stuff you actually want to get to. This, so that it may maintain a fluent API and let you join method calls in a single statement like so:
$('#selector').foo().bar().gar().har();
However, in the case of jQuery then, how do you determine what the real underlying type is? For example, if the element returned was a table row with the Id tableRowNumber25, how do you get to that, say, using FireBug.
When I look at either a jQuery returned object or a simple JavaScript object in the watches window of Firebug or any of the Developer Tools in most popular browsers, I see a long laundry list of properties/keys and I don't know which one to look at. In a jQuery object, most of the properties are lamdas.
So, really, my question is -- how do you know the underlying type, how do you know what's actually being returned?
The type of theElement will be [object jQuery].
If you want the HTML element itself, you have to select it:
console.log(theElement[0]) //Return <div id='theId'>
console.log(theElement.get(0)) //Return <div id='theId'>
If you want the node name, there is a property in the HTML node element call nodeName wich return the capitalised node name:
console.log(theElement[0].nodeName)// Return DIV
typeof(jQueryElementList.get(0)) will return a string of the type.
Some browsers might return this as upper or lower case, I think. IE probably uppercases (see Testing the type of a DOM element in JavaScript). Apparently you can check the nodeType attribute (jQueryElementList.get(0).nodeType) to determine whether it is an html object/tag.

Get full DOM stack as a string

I want to get the full DOM stack as a string. As an example, please open Chrome, press F12 and type "document.all". This object represents the full DOM. I want to convert this object as a string. In Chrome you're able to explore the object, expand sections and view their content in the web debugger console. Is there any possibility to convert document.all as a string? Or a similar solution with gives me the full DOM stack? I don't just want the innerHTML/outerHTML, I want the content of literally everything what's defined in the current DOM. Any ideas? Thanks in advance...
EDIT: Okay, I think my question is kind of confusing, sorry for that. To clarify this: I want to get every property of every object which is defined, including stuff like "document.location", "document.location.hash", "window.innerHeight", "document.body.innerHTML", and so on, by using JavaScript.
As far as I know, there's no way to get every property of every object.
In at least some browsers (Chrome, for instance), you can get most of the DOM with outerHTML on documentElement (the root element, e.g., html):
var html = document.documentElement.outerHTML;
You'd have to check whether your other target browsers do. At a minimum, they'll have innerHTML on body:
var bodyHTML = document.body.innerHTML;
But in terms of the other things, I don't believe there's any way to get every property of every object. For instance, you can find the properties on window like this:
var key;
for (key in window) {
// ...'key' is the property name, window[key] is the value...
}
...but that will only give you enumerable properties, not non-enumerable ones. And of course, you'd have to recurse into objects to get their properties (allowing for the fact that you can get to an object in more than one way — for example, window === window.window and there's also top, self, etc. to worry about; and similarly for document.all, document.forms, ...).
So unfortunately, while you can get a lot of the information you're talking about, I don't believe you can get it all.
You can implement this yourself using Object.getOwnPropertyNames, which will even include non-enumerable properties. I made a small example showing how this might be done.

Removing Chrome's "translate" DOM Property

I'm working with some legacy code where the original developers made heavy use of generating HTML DOM nodes with a non-standard attribute named translate
<span translate="[{"shown":"My Account","translated":"My Account","original":"My Account","location":"Text","scope":"Mage_Customer"}]">My Account</span>
and then traversing/searching for those nodes with javascript code like the following.
if (!$(target).match('*[translate]')) {
target = target.up('*[translate]');
}
The problem I'm trying to solve is, it appears that Google Chrome automatically adds a translate attribute to every DOM node in the document, and that this DOM node's value is a boolean true. You can see this by running the following Javascript from Chrome's javascript console
> document.getElementsByTagName('p')[0].translate
true
>
Is there anyway to tell Chrome not to populate these attributes? Their presence is wrying havoc with the legacy code. PrototypeJS's match and up nodes treat these boolean object attributes as matches, while the code I'm dealing with is specifically looking for DOM nodes with an attribute named translate. I'd like to find a solution for my problem that doesn't involved rewriting the old Javascript to use methods like hasAttribute.
I tried (as a wild guess) adding the meta attributes mentioned in this article,
<meta name=”google” value=”notranslate”>
<meta name=”google” content=”notranslate”>
but the nodes in the page still has a boolean true translate attribute.
(if it matters, this is Magento's inline translation system I'm talking about here)
The best I've been able to come up with so far is going through every DOM element in the page defining a getter that checks for the existence of an attribute. (the Object.__defineGetter__ guard clause ensures no errors in browsers that don't support modern Javascript)
if(Object.__defineGetter__)
{
var hasTranslateAttribute = function(){
return $(this).hasAttribute("translate");
};
document.observe("dom:loaded", function() {
$$('*').each(function(theElement){
theElement.__defineGetter__("translate", hasTranslateAttribute);
});
});
}
I tried defining a getting on Object.prototype and Element.prototype, but it seems like the browser's native translate is defined higher up the chain, so you need to redefine things on a per element basis.
Replace the nonstandard attribute translate by an attribute like data-translate, which is virtually guaranteed to be and to remain undefined in HTML specifications and in browsers. The data-* attributes were invented to prevent issues like this, and they can also be used to fix them.

IE Object doesn't support this property or method

This is probably the beginning of many questions to come.
I have finished building my site and I was using Firefox to view and test the site. I am now IE fixing and am stuck at the first JavaScript error which only IE seems to be throwing a hissy about.
I run the IE 8 JavaScript debugger and get this:
Object doesn't support this property or method app.js, line 1 character 1
Source of app.js (first 5 lines):
var menu = {};
menu.current = "";
menu.first = true;
menu.titleBase = "";
menu.init = function(){...
I have tested the site in a Webkit browser and it works fine in that.
What can I do to fix this? The site is pretty jQuery intensive so i have given up any hope for getting it to work in IE6 but I would appreciate it working in all the others.
UPDATE: I have upload the latest version of my site to http://www.frankychanyau.com
In IE8, your code is causing jQuery to fail on this line
$("title").text(title);
in the menu.updateTitle() function. Doing a bit of research (i.e. searching with Google), it seems that you might have to use document.title with IE.
Your issue is (probably) here:
menu.updateTitle = function(hash){
var title = menu.titleBase + ": " + $(hash).data("title");
$("title").text(title); // IE fails on setting title property
};
I can't be bothered to track down why jQuery's text() method fails here, but it does. In any case, it's much simpler to not use it. There is a title property of the document object that is the content of the document's title element. It isn't marked readonly, so to set its value you can simply assign a new one:
document.title = title;
and IE is happy with that.
It is a good idea to directly access DOM properties wherever possible and not use jQuery's equivalent methods. Property access is less troublesome and (very much) faster, usually with less code.
Well, your line 1 certainly looks straight forward enough. Assuming the error line and number is not erroneous, it makes me think there is a hidden character in the first spot of your js file that is throwing IE for a fit. Try opening the file in another text editor that may support display of normally hidden characters. Sometimes copying/pasting the source into a super-basic text-editor, like Notepad, can sometimes strip out non-displayable characters and then save it back into place directly from Notepad.

How to add/update an attribute to an HTML element using JavaScript?

I'm trying to find a way that will add / update attribute using JavaScript. I know I can do it with setAttribute() function but that doesn't work in IE.
You can read here about the behaviour of attributes in many different browsers, including IE.
element.setAttribute() should do the trick, even in IE. Did you try it? If it doesn't work, then maybe
element.attributeName = 'value' might work.
What seems easy is actually tricky if you want to be completely compatible.
var e = document.createElement('div');
Let's say you have an id of 'div1' to add.
e['id'] = 'div1';
e.id = 'div1';
e.attributes['id'] = 'div1';
e.createAttribute('id','div1')
These will all work except the last in IE 5.5 (which is ancient history at this point but still is XP's default with no updates).
But there are contingencies, of course.
Will not work in IE prior to 8:e.attributes['style']
Will not error but won't actually set the class, it must be className:e['class'] .
However, if you're using attributes then this WILL work:e.attributes['class']
In summary, think of attributes as literal and object-oriented.
In literal, you just want it to spit out x='y' and not think about it. This is what attributes, setAttribute, createAttribute is for (except for IE's style exception). But because these are really objects things can get confused.
Since you are going to the trouble of properly creating a DOM element instead of jQuery innerHTML slop, I would treat it like one and stick with the e.className = 'fooClass' and e.id = 'fooID'. This is a design preference, but in this instance trying to treat is as anything other than an object works against you.
It will never backfire on you like the other methods might, just be aware of class being className and style being an object so it's style.width not style="width:50px". Also remember tagName but this is already set by createElement so you shouldn't need to worry about it.
This was longer than I wanted, but CSS manipulation in JS is tricky business.
Obligatory jQuery solution. Finds and sets the title attribute to foo. Note this selects a single element since I'm doing it by id, but you could easily set the same attribute on a collection by changing the selector.
$('#element').attr( 'title', 'foo' );
What do you want to do with the attribute? Is it an html attribute or something of your own?
Most of the time you can simply address it as a property: want to set a title on an element? element.title = "foo" will do it.
For your own custom JS attributes the DOM is naturally extensible (aka expando=true), the simple upshot of which is that you can do element.myCustomFlag = foo and subsequently read it without issue.

Categories

Resources