Javascript Shorthand for getElementById - javascript

Is there any shorthand for the JavaScript document.getElementById? Or is there any way I can define one? It gets repetitive retyping that over and over.

var $ = function( id ) { return document.getElementById( id ); };
$( 'someID' )
Here I used $, but you can use any valid variable name.
var byId = function( id ) { return document.getElementById( id ); };
byId( 'someID' )

To save an extra character you could pollute the String prototype like this:
pollutePrototype(String, '绎', {
configurable: false, // others must fail
get: function() {
return document.getElementById(this);
},
set: function(element) {
element.id = this;
}
});
function pollutePrototype(buildIn, name, descr) {
var oldDescr = Object.getOwnPropertyDescriptor(buildIn.prototype, name);
if (oldDescr && !oldDescr.configurable) {
console.error('Unable to replace ' + buildIn.name + '.prototype.' + name + '!');
} else {
if (oldDescr) {
console.warn('Replacing ' + buildIn.name + '.prototype.' + name + ' might cause unexpected behaviour.');
}
Object.defineProperty(buildIn.prototype, name, descr);
}
}
It works in some browsers and you can access elements this way:
document.body.appendChild(
'footer'.绎 = document.createElement('div')
);
'footer'.绎.textContent = 'btw nice browser :)';
I have chosen the name of the property almost randomly. If you actually wanted to use this shorthand I would suggest coming up with something easier to type.

You can easily create shorthand easily yourself:
function getE(id){
return document.getElementById(id);
}

id's are saved to the window.
HTML
<div id='logo'>logo</div>
JS
logo.innerHTML;
is the same as writing:
document.getElementById( 'logo' ).innerHtml;
I don't suggest using the former method as it is not common practice.

A quick alternative to contribute:
HTMLDocument.prototype.e = document.getElementById
Then just do:
document.e('id');
There's a catch, it doesn't work in browsers that don't let you extend prototypes (e.g. IE6).

(Shorthand for not only getting element by ID, but also getting element by class :P)
I use something like
function _(s){
if(s.charAt(0)=='#')return [document.getElementById(s.slice(1))];
else if(s.charAt(0)=='.'){
var b=[],a=document.getElementsByTagName("*");
for(i=0;i<a.length;i++)if(a[i].className.split(' ').indexOf(s.slice(1))>=0)b.push(a[i]);
return b;
}
}
Usage : _(".test") returns all elements with class name test, and _("#blah") returns an element with id blah.

<script>
var _ = function(eId)
{
return getElementById(eId);
}
</script>
<script>
var myDiv = _('id');
</script>

There are several good answers here and several are dancing around jQuery-like syntax, but not one mentions actually using jQuery. If you're not against trying it, check out jQuery. It let's you select elements super easy like this..
By ID:
$('#elementId')
By CSS class:
$('.className')
By element type:
$('a') // all anchors on page
$('inputs') // all inputs on page
$('p a') // all anchors within paragaphs on page

There's none built-in.
If you don't mind polluting the global namespace, why not:
function $e(id) {
return document.getElementById(id);
}
EDIT - I changed the function name to be something unusual, but short and not otherwise clashing with jQuery or anything else that uses a bare $ sign.

I frequently use:
var byId='getElementById'
var byClass='getElementsByClass'
var byTag='getElementsByTag'
var mydiv=document[byId]('div')
/* as document["getElementById"] === document.getElementById */
I think it's better than a external function (e.g. $() or byId()) because you can do things like this:
var link=document[byId]('list')[byClass]('li')[0][byTag]('a')[0]
Btw, don't use jQuery for this, jQuery is much, much slower than document.getElementById(), an external function like $() or byId(), or my method: http://jsperf.com/document-getelementbyid-vs-jquery/5

Yes, it gets repetitive to use the same function over and over each time with a different argument:
var myImage = document.getElementById("myImage");
var myDiv = document.getElementById("myDiv");
So a nice thing would be a function that takes all those arguments at the same time:
function getElementsByIds(/* id1, id2, id3, ... */) {
var elements = {};
for (var i = 0; i < arguments.length; i++) {
elements[arguments[i]] = document.getElementById(arguments[i]);
}
return elements;
}
Then you would have references to all your elements stored in one object:
var el = getElementsByIds("myImage", "myDiv");
el.myImage.src = "test.gif";
But you would still have to list all those ids.
You could simplify it even more if you want all elements with ids:
function getElementsWithIds() {
var elements = {};
var elementList = document.querySelectorAll("[id]");
for (var i = 0; i < elementList.length; i++) {
elements[elementList[i].id] = elementList[i];
}
return elements;
}
But it would be pretty expensive to call this function if you have many elements.
So, theoretically, if you would use the with keyword you could write code like this:
with (getElementsByIds('myButton', 'myImage', 'myTextbox')) {
myButton.onclick = function() {
myImage.src = myTextbox.value;
};
}
But I don't want to promote the use of with. Probably there's a better way to do it.

Well, you could create a shorthand function, that's what I do.
function $(element) {
return document.getElementById(element);
}
and then when you wanted to get it, you just do
$('yourid')
Also, another useful trick that I found, is that if you want to get the value or innerHTML of an item ID, you can make functions like this:
function $val(el) {
return $(el).value;
}
function $inner(el) {
return $(el).innerHTML;
}
Hope you like it!
I actually made a kind of mini javascript library based on this whole idea.
Here it is.

If this is on your own site, consider using a library like jQuery to give you this and many other useful shorthands that also abstract away browser differences. Personally, if I wrote enough code to be bothered by the longhand, I would include jQuery.
In jQuery, the syntax would be $("#someid"). If you then want the actual DOM element and not the jQuery wrapper, it's $("#someid")[0], but you could most likely do whatever you're after with the jQuery wrapper.
Or, if you're using this in a browser developer console, research their built-in utilities. As someone else mentioned, the Chrome JavaScript console includes a $("someid") method, and you can also click an element in the developer tools "Elements" view and then reference it with $0 from the console. The previously selected element becomes $1 and so on.

If the only issue here is typing, maybe you should just get yourself a JavaScript editor with intellisense.
If the purpose is to get shorter code, then you could consider a JavaScript library like jQuery, or you can just write your own shorthand functions, like:
function byId(string) {return document.getElementById(string);}
I used to do the above for better performance. What I learnt last year is that with compression techniques the server does it automatically for you, so my shortening technique was actually making my code heavier. Now I am just happy with typing the whole document.getElementById.

If you are asking for a shorthand function...
<!DOCTYPE html>
<html>
<body>
The content of the body element is displayed in your browser.
<div id="d1">DIV</div>
<script>
var d=document;
d.g=document.getElementById;
d.g("d1").innerHTML = "catch";
</script>
</body>
</html>
or
<!DOCTYPE html>
<html>
<body>
The content of the body element is displayed in your browser.
<div id="d1">DIV</div>
<script>
var w=window;
w["d1"].innerHTML = "catch2";
</script>
</body>

Arrow functions make is shorter.
var $id = (id) => document.getElementById(id);

wrap the document.querySelectorAll ... a jquery like select
function $(selector){
var s = document.querySelectorAll(selector);
return s.length > 1 ? s : s[0];
}
// usage: $('$myId')

Well, if the id of the element does not compete with any properties of the global object, you don't have to use any function.
myDiv.appendChild(document.createTextNode("Once I was myDiv. "));
myDiv.id = "yourDiv";
yourDiv.appendChild(document.createTextNode("But now I'm yourDiv."));
edit: But you don't want to make use of this 'feature'.

Another wrapper:
const IDS = new Proxy({}, {
get: function(target, id) {
return document.getElementById(id); } });
IDS.camelCaseId.style.color = 'red';
IDS['dash-id'].style.color = 'blue';
<div id="camelCaseId">div 1</div>
<div id="dash-id">div 2</div>
This, in case you don't want to use the unthinkable, see above.

You can use a wrapper function like :
const byId = (id) => document.getElementById(id);
Or
Assign document.getElementById to a variable by binding it with document object.
const byId = document.getElementById.bind(document);
Note: In second approach, If you don't bind document.getElementById with document you'll get error :
Uncaught TypeError: Illegal invocation
What Function.bind does is it creates a new function with its this keyword set to value that you provide as argument to Function.bind.
Read docs for Function.bind

const $id = id => document.getElementById(id);
...
$id('header')

I just use: function id(id) {return document.getElementById(id);}", called by id(target id).action;
It works for me in Chrome, Edge & Firefox, though not in Safari or Opera.

I wrote this yesterday and found it quite useful.
function gid(id, attribute) {
var x = 'document.getElementById("'+id+'")';
if(attribute) x += '.'+attribute;
eval('x =' + x);
return x;
}
This is how you use it.
// Get element by ID
var node = gid('someID'); //returns <p id='someID' class='style'>Hello World</p>
// returns 'Hello World'
// var getText = document.GetElementById('someID').innerText;
var getText = gid('someID', 'innerText');
// Get parent node
var parentNode = gid('someID', 'parentNode');

Related

Two blocks in getElementById [duplicate]

doStuff(document.getElementById("myCircle1" "myCircle2" "myCircle3" "myCircle4"));
This doesn't work, so do I need a comma or semi-colon to make this work?
document.getElementById() only supports one name at a time and only returns a single node not an array of nodes. You have several different options:
You could implement your own function that takes multiple ids and returns multiple elements.
You could use document.querySelectorAll() that allows you to specify multiple ids in a CSS selector string .
You could put a common class names on all those nodes and use document.getElementsByClassName() with a single class name.
Examples of each option:
doStuff(document.querySelectorAll("#myCircle1, #myCircle2, #myCircle3, #myCircle4"));
or:
// put a common class on each object
doStuff(document.getElementsByClassName("circles"));
or:
function getElementsById(ids) {
var idList = ids.split(" ");
var results = [], item;
for (var i = 0; i < idList.length; i++) {
item = document.getElementById(idList[i]);
if (item) {
results.push(item);
}
}
return(results);
}
doStuff(getElementsById("myCircle1 myCircle2 myCircle3 myCircle4"));
This will not work, getElementById will query only one element by time.
You can use document.querySelectorAll("#myCircle1, #myCircle2") for querying more then one element.
ES6 or newer
With the new version of the JavaScript, you can also convert the results into an array to easily transverse it.
Example:
const elementsList = document.querySelectorAll("#myCircle1, #myCircle2");
const elementsArray = [...elementsList];
// Now you can use cool array prototypes
elementsArray.forEach(element => {
console.log(element);
});
How to query a list of IDs in ES6
Another easy way if you have an array of IDs is to use the language to build your query, example:
const ids = ['myCircle1', 'myCircle2', 'myCircle3'];
const elements = document.querySelectorAll(ids.map(id => `#${id}`).join(', '));
No, it won't work.
document.getElementById() method accepts only one argument.
However, you may always set classes to the elements and use getElementsByClassName() instead. Another option for modern browsers is to use querySelectorAll() method:
document.querySelectorAll("#myCircle1, #myCircle2, #myCircle3, #myCircle4");
I suggest using ES5 array methods:
["myCircle1","myCircle2","myCircle3","myCircle4"] // Array of IDs
.map(document.getElementById, document) // Array of elements
.forEach(doStuff);
Then doStuff will be called once for each element, and will receive 3 arguments: the element, the index of the element inside the array of elements, and the array of elements.
getElementByID is exactly that - get an element by id.
Maybe you want to give those elements a circle class and getElementsByClassName
document.getElementById() only takes one argument. You can give them a class name and use getElementsByClassName() .
Dunno if something like this works in js, in PHP and Python which i use quite often it is possible.
Maybe just use for loop like:
function doStuff(){
for(i=1; i<=4; i++){
var i = document.getElementById("myCiricle"+i);
}
}
Vulgo has the right idea on this thread. I believe his solution is the easiest of the bunch, although his answer could have been a little more in-depth. Here is something that worked for me. I have provided an example.
<h1 id="hello1">Hello World</h1>
<h2 id="hello2">Random</h2>
<button id="click">Click To Hide</button>
<script>
document.getElementById('click').addEventListener('click', function(){
doStuff();
});
function doStuff() {
for(var i=1; i<=2; i++){
var el = document.getElementById("hello" + i);
el.style.display = 'none';
}
}
</script>
Obviously just change the integers in the for loop to account for however many elements you are targeting, which in this example was 2.
The best way to do it, is to define a function, and pass it a parameter of the ID's name that you want to grab from the DOM, then every time you want to grab an ID and store it inside an array, then you can call the function
<p id="testing">Demo test!</p>
function grabbingId(element){
var storeId = document.getElementById(element);
return storeId;
}
grabbingId("testing").syle.color = "red";
You can use something like this whit array and for loop.
<p id='fisrt'>??????</p>
<p id='second'>??????</p>
<p id='third'>??????</p>
<p id='forth'>??????</p>
<p id='fifth'>??????</p>
<button id="change" onclick="changeColor()">color red</button>
<script>
var ids = ['fisrt','second','third','forth','fifth'];
function changeColor() {
for (var i = 0; i < ids.length; i++) {
document.getElementById(ids[i]).style.color='red';
}
}
</script>
For me worked flawles something like this
doStuff(
document.getElementById("myCircle1") ,
document.getElementById("myCircle2") ,
document.getElementById("myCircle3") ,
document.getElementById("myCircle4")
);
Use jQuery or similar to get access to the collection of elements in only one sentence. Of course, you need to put something like this in your html's "head" section:
<script type='text/javascript' src='url/to/my/jquery.1.xx.yy.js' ...>
So here is the magic:
.- First of all let's supose that you have some divs with IDs as you wrote, i.e.,
...some html...
<div id='MyCircle1'>some_inner_html_tags</div>
...more html...
<div id='MyCircle2'>more_html_tags_here</div>
...blabla...
<div id='MyCircleN'>more_and_more_tags_again</div>
...zzz...
.- With this 'spell' jQuery will return a collection of objects representing all div elements with IDs containing the entire string "myCircle" anywhere:
$("div[id*='myCircle']")
This is all! Note that you get rid of details like the numeric suffix, that you can manipulate all the divs in a single sentence, animate them... Voilá!
$("div[id*='myCircle']").addClass("myCircleDivClass").hide().fadeIn(1000);
Prove this in your browser's script console (press F12) right now!
As stated by jfriend00,
document.getElementById() only supports one name at a time and only returns a single node not an array of nodes.
However, here's some example code I created which you can give one or a comma separated list of id's. It will give you one or many elements in an array. If there are any errors, it will return an array with an Error as the only entry.
function safelyGetElementsByIds(ids){
if(typeof ids !== 'string') return new Error('ids must be a comma seperated string of ids or a single id string');
ids = ids.split(",");
let elements = [];
for(let i=0, len = ids.length; i<len; i++){
const currId = ids[i];
const currElement = (document.getElementById(currId) || new Error(currId + ' is not an HTML Element'));
if(currElement instanceof Error) return [currElement];
elements.push(currElement);
};
return elements;
}
safelyGetElementsByIds('realId1'); //returns [<HTML Element>]
safelyGetElementsByIds('fakeId1'); //returns [Error : fakeId1 is not an HTML Element]
safelyGetElementsByIds('realId1', 'realId2', 'realId3'); //returns [<HTML Element>,<HTML Element>,<HTML Element>]
safelyGetElementsByIds('realId1', 'realId2', 'fakeId3'); //returns [Error : fakeId3 is not an HTML Element]
If, like me, you want to create an or-like construction, where either of the elements is available on the page, you could use querySelector. querySelector tries locating the first id in the list, and if it can't be found continues to the next until it finds an element.
The difference with querySelectorAll is that it only finds a single element, so looping is not necessary.
document.querySelector('#myCircle1, #myCircle2, #myCircle3, #myCircle4');
here is the solution
if (
document.getElementById('73536573').value != '' &&
document.getElementById('1081743273').value != '' &&
document.getElementById('357118391').value != '' &&
document.getElementById('1238321094').value != '' &&
document.getElementById('1118122010').value != ''
) {
code
}
You can do it with document.getElementByID Here is how.
function dostuff (var here) {
if(add statment here) {
document.getElementById('First ID'));
document.getElementById('Second ID'));
}
}
There you go! xD

Create a function to get selectors like jquery does with pure javascript

I am tired of including jquery in simple projects but I am so used to using it and I am trying to break free form my dependency on it. I am trying to create a function that will give the same feel of getting selectors like classes and tags. Example: $('selector').innerHTML = ".something";. I have just been looping through them one by one like so:
var classElements = document.querySelectorAll('.something');
for (var i = classElements.length - 1; i >= 0; i--) {
classElements[i].innerHTML = "This Is A Div";
}
But I wanted to create a function where I could just loop through a selector without having to write out a for loop for everything that I want to find. So I could just write it our like above $('.something').innerHTML = "something";
So far this is what I have but it will only get the first of each selector and won't get all of them. Needless to say I am very stuck and the more I read on the subject the more confused I get. I was wondering if someone could point me in the right direction where my thinking is flawed or explain how jquery goes about doing this. Here is my code:
window.getElements = function(selector) {
var selectors = document.querySelectorAll(selector);
for (var i = selectors.length - 1; i >= 0; i--) {
var elements = selectors[i];
}
return elements;
};
getElements(".something").innerHTML = "something";
Here is a fiddle Fiddle
Here is how you would do it. I have done what you have asked which is allow you to use all the native functionality rather than coin wrappers around it. jQuery returns its own api which acts on the selectors. What I have done is create a selector which allows you to act on each element it finds
window.getElements = function(selector,cb) {
var selectors = document.querySelectorAll(selector);
[].forEach.call(selectors, cb);
};
getElements(".something", function(el){el.innerHTML = "ha"});
getElements("#one", function(el){el.style.background = "red" });
It takes the dom list that is found, converts it into an array and then calls your passed function where you pass your native code
Here is a fiddle
https://jsfiddle.net/y52f4wh8/5/
Jquery works differently:
window.jquery = function(selector,cb) {
var selectors = document.querySelectorAll(selector);
function command(cb) {
[].forEach.call(selectors, cb);
};
// Here we return our own api that uses the command function to act on
// our selected list.
return {
html: function(str){
command(function(el){
el.innerHTML=str;
});
},
bg: function(color){
command(function(el){
el.style.background = color;
});
}
}
};
// The jquery way!
jquery(".something").html("ha");
getElements(".something").innerHTML = "something";
this does not work because that your function gets and returns all of the elements, which is a NodeList, but it does not automatically apply methods to every element in the collection as jQuery does. In order to do that, you would have to convert the elements to an array and actually call the function on each element using a loop or some other function.
EDIT: To be clear, you cannot just call NodeList.innerHTML = '' on a NodeList because innerHTML is applied to one element. jQuery internally takes care of BOTH of the collecting of elements, and the applying of methods for you.
EDIT #2: After examining your function more carefully, I have realized there are other issues, but what I wrote above is still the basis from which you want to spring.
You could use something like this for getting elements?:
function getElements(elements) {
return [...querySelectorAll(elements)]
}
But applying functions on nodes is going to be more selective on a case-by-case basis since many of them are applied differently.
The selector part of JQuery is called Sizzle. It has all the functionality that you need but does not come with the other parts of JQuery.
If you would like to find out more about the javascript behind it, I recommend to take a look at the sourcefiles of Sizzle.
jQuery is essentially a wrapper object for NodeList which adds more functionality to DOM operations. If you want to create your own wrapper object which defines functions for bulk versions of all the Element API, you are free to do so, but then you might as well use jQuery or some derivative.
If you want an extremely lightweight proxy object for doing bulk operations on DOM elements, there is the Proxy object in ES6 which can make this very easy to do, but has no IE support.
const $ = function(selector) {
const nodeList = document.querySelectorAll(selector);
return new Proxy(nodeList, {
set: function(target, property, value) {
for (let i = 0; i < target.length; i++) {
target[i][property] = value;
}
},
get: function(target, property) {
return target[0] && target[0][property];
}
});
};
console.log($('p').innerHTML);
$('p').innerHTML = 'Bulk assignement!';
<p>A B C</p>
<p>1 2 3</p>
<p>Do Re Mi</p>
An approach which would be best avoided is to define a setter for innerHTML on NodeList.
Object.defineProperty(NodeList.prototype, 'innerHTML', {
set(text) {
[...this].forEach(elt => elt.innerHTML = text);
}
});
const $ = selector => document.querySelectorAll(selector);
$('.foo').innerHTML = "it works";
<div class="foo"></div>
<div class="foo"></div>

Can I set two different values to an element using getElementById?

Can't I use getElementById twice in javascript file? I want to use it twice because, I want to set a default value to the element with that particular id and then on calling a function i need to change the default value. Can I do this?
Have a look at my code:
function DefaultValue(){
var default = 10.23
var update = document.getElementById('idSpnRWA');
update.innerHTML = default;
}
function setValue(){
var set = 23.56;
var finalUpdate = document.getElementById('idSpnRWA');
finalUpdate.innerHTML = set;
}
I have given a very basic code to make you understand if this way is possible?
In short: yes, you can call getElementById as many times as you want.
Please note however, that default is a reserved word in JavaScript.
Also, you're forgetting to add ; after each line.
Try this (note I renamed the default variable, and added ; where needed.
HTML
<div id="idSpnRWA"></div>
JavaScript
function DefaultValue() {
var dflt = 10.23;
var update = document.getElementById('idSpnRWA');
update.innerHTML = dflt;
}
function setValue() {
var set = 23.56;
var finalUpdate = document.getElementById('idSpnRWA');
finalUpdate.innerHTML = set;
}
DefaultValue();
setValue();
Working Fiddle: http://jsfiddle.net/9e75vnm3/
Of course you can use document.getElementById many times.
But element with a specific id can be only once at your page.
Yes you can use getElementById as many time as you want.
Problem in your code is that you are adding inner html as 10.23% which is not allowed. '%' is consider as a modulo operator. if you want to display in html than you have to concat it as string
function DefaultValue() {
var update = document.getElementById('idSpnRWA');
update.innerHTML = 10.23 + '%';
}
function setValue() {
var finalUpdate = document.getElementById('idSpnRWA');
finalUpdate.innerHTML = 23.56 + '%';
}
DefaultValue();
<div id='idSpnRWA'></div>
You cannot have the same HTML id attribute more than once on a page, but you can get anything as many times as you want, as long as it's not undefined. Of course, this means you can call document.getElementById('idSpnRWA') as many times as you want. You'll want to put percentages in quotes when assigning to .innerHTML, as % is the modulo operator. Better yet, use HTML entities. Element.innerHTML = '10.23&#037';
thank you so much for answering my question. I finally found the solution. it is,
update.value= default;
finalUpdate.value = set;
innerHTML can't be used there. If i use .value, the code is actually working fine.

JavaScript: Implement 'element.hasAttribute' if undefined [for IE7]

I need to make an exisitng web application compatible with IE7.
The code uses element.hasAttribute extensively and IE7 has issues with this method.
Object doesn't support property or method 'hasattribute'
I am trying to check in the code if an input element has the hasAttribute method defined and if not, I am trying to add it to all input elements.
//create an input element variable << works fine
var myInput = document.createElement("input");
//see if it has the 'hasAttribute' method << condition works fine
if (('hasAttribute' in myInput)==false)
{
//get all input elements into objInputElements <<works fine
var objInputElements=document.getElementsByTagName("input");
// MORE CODE NEEDED - To implement a hasAttribute function for all
// elements in the array probably using something
// like: !!element[attributeName] which works in IE7. See link and notes below.
}
This article describes how to define a seperate function to do this. However, I would like to add the hasattribute method to the elements if it is not defined. (this way I don't need to change all the code that is currently written)
IMPORTANT NOTE: There are > 1000 hidden input fields in the form therefore, the 'hasattribute' method needs to be added to the elements in a very efficient way.
Please let me know the how I could achieve this. Thank you!
Since Element.prototype is not supported IE < 8, there is no efficient way to polyfill hasAttribute. The inefficient way (if you wanted to avoid shimming) would be something like this (placed after all inputs had loaded):
<input data-abc="" />
<script>
if (!window.Element || !window.Element.prototype || !window.Element.prototype.hasAttribute) {
(function () {
function hasAttribute (attrName) {
return typeof this[attrName] !== 'undefined'; // You may also be able to check getAttribute() against null, though it is possible this could cause problems for any older browsers (if any) which followed the old DOM3 way of returning the empty string for an empty string (yet did not possess hasAttribute as per our checks above). See https://developer.mozilla.org/en-US/docs/Web/API/Element.getAttribute
}
var inputs = document.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
inputs[i].hasAttribute = hasAttribute;
}
}());
}
var inputs = document.getElementsByTagName('input');
document.write(
'has?' + inputs[0].hasAttribute('abc') // false
);
document.write(
'has?' + inputs[0].hasAttribute('data-abc') // true
);
</script>
I known this is an old post and maybe nobody else use IE7 but if like me you need it (and need to use ajax or something like that) this is my propose.
Maybe we can improve the performance creating a proxy of getElementsByTagName or getElementById to do the trick, and this add support to dynamic elements that are created in runtime.
Maybe something like this:
if (!window.Element || !window.Element.prototype || !window.Element.prototype.hasAttribute) {
(function (document) {
var originalGetElementById = document.getElementById;
var originalGetElementsByTagName = document.getElementsByTagName;
// The HasAttribute function.
function hasAttribute (attrName) {
return typeof this[attrName] !== 'undefined';
}
// Add the HasAttribute to the element if is not present yet.
function attachFunction (element) {
if (element && !element.hasAttribute) {
element.hasAttribute = hasAttribute;
}
return element;
}
// Proxy of the document.getElementById
document.getElementById = function (elementId) {
var element = originalGetElementById(elementId);
return attachFunction(element);
}
// Proxy of the document.getElementsByTagName
document.originalGetElementsByTagName = function (tagName) {
var elements = originalGetElementsByTagName(tagName);
for(var i = 0, len = elements.length; i < len; i++) {
attachFunction(element[i]);
}
return elements;
}
}(document));
}
And this functionality can be in a separated javascript file included with conditional tags in IE:
<!--[if lt IE 8]>
<script src="ie7fixs.js" type="text/javascript" ></script>
<![endif]-->
And then just use the document.getElementsByTagName or document.getElementById.
var inputs = document.getElementsByTagName('input');
document.write(
'has?' + inputs[0].hasAttribute('abc') // false
);
document.write(
'has?' + inputs[0].hasAttribute('data-abc') // true
);
Try it:
//if po is object then for IE:
if (!po.hasAttribute) po.hasAttribute=function(attr) {
return this.getAttribute(attr)!=null
};

how to make a class accept a method without specifying the method in advance?

If i have something like this :
function foo(class){
for(i=0; i<(class.length);i++){
return document.getElementsByClassName(class)[i];
}
}
And now i want to do something like this:
foo("someclass").innerHTML="something";
it will do it only for the first element and i understand why this happens and how to make it work correctly, but how can i make the function get other methods without telling it in the loop exactly what to do,like this
foo("someclass").innerHTML="something";//this to put something inside the element
foo("someclass").style.backgroundColor="#000");// and this to work also
So,if its possible,how can i make the function do this without putting these methods in the foo function loop? Is there a way to put these methods in a variable like this
function foo(class).variableMethod{
for(i=0; i<(class.length);i++){
document.getElementsByClassName(class)[i].variableMethod;
}
}
Is this possible?
You can pass a function to foo(), and have foo() call that function with each matched element:
function foo(className, func)
{
var elements = document.getElementsByClassName(className);
for (var i = 0; i < elements.length; ++i) {
func(elements[i]);
}
}
Now you can do something like:
foo("someclass", function(element) {
element.innerHTML = "something";
element.style.backgroundColor = "#000";
});
Just to add to the other great answers here, one thing you could do is create on override method called innerHtml. You could then have innerHtml check for a collection as well as a single instance and opperate as required.
UPDATE
Here's a quick example of method chaining. Here I basically obtain a collection of elements based on tag name and set their value using a val() method that I created using the Javascript prototype object.
function Foo(tagName)
{
this.collection = document.getElementsByTagName(tagName);
return this;
}
Foo.prototype.val= function(value){
for(var i = 0; i < this.collection.length; i++)
{
this.collection[i].innerHTML = value;
}
}
var x = new Foo("li").val("Hello World");
You can see a working demo of this here: http://jsfiddle.net/E48ym/1/
Frédéric Hamidi's answer will do what you want I think, but you could also use a framework like jQuery - this is the kind of thing it was designed for. So you could do:
$('.className').text('something');
to set the text of all elements with a class of className to something, or
$('.className').css('background-color', '#000');
to change the background color of all elements with a class of className.

Categories