What kind of JavaScript is this? - javascript

I have an application that has this format scattered around but I dont know what kind it is. It's not jQuery, so what is it?
$('some_edit').style.display = "block";
$('some_views').style.display = "none";
I get this in firebug and I know the element is present:
$("some_edit").style is undefined

It could be many things - examine the source code (or use Firebug) and see what JS libraries are being loaded.

A lot of people have defined the '$' symbol as a substitute for document.getElementById().
Basically:
function $(id) { return document.getElementById(id); }
$("ElementID").innerHTML = "Text"; //Usage
A more proper, "namespace" example:
var DOM = { // creating the namespace "DOM"
$: (function() {
if(document.getElementById)
return function(id){ return document.getElementById(id); }
else if(document.all)
return function(id) { return document.all[id]; }
else
return function(id) { /* I don't even want to get into document.layers */ }
})()
};
// Later in the code:
{
function ExampleFunction() {
// ...
DOM.$("ElementID").style.backgroundColor = "#96d0a0"; // a nice minty green color
// ...
}
}
I have used a self-invocation pattern (function(){ ... }()) in this example.

at first i thought the jquery selector would likely have been $("#some_edit") and then .css(). so I would have said, prototype or mootools or a home brew $.
you can certainly discount both mootools and prototype, because if the selector returns an object, then the style property will be available (ignoring best practices in both frameworks on setting styles).
this leaves, the site uses homebrew $ assignment or jquery, which is not being used correctly.
actually, $("foo").style.blah in jquery will produce this very exception (even if the selector was good) - here is jsfiddle to the rescue
case point jquery (triggers):
http://www.jsfiddle.net/dimitar/vmsZn/
case point prototype (works):
http://www.jsfiddle.net/dimitar/vmsZn/1/
case point mootools (works):
http://www.jsfiddle.net/dimitar/vmsZn/2/

It is setting the display style for the two page elements - the display property specifies the type of box an element should generate.
block = The element will generate a block box (a line break before and after the element)
none = The element will generate no box at all

Put a [0] in front of $('some_views') to return the Native DOM Element.
$('some_views')[0].style.display = "none";
or $('some_views').get(0).style.display = "none";
or $('some_views').css('display', 'none') to iterate through the collection of DOM elements.

It's JQuery -- uses $ as its key variable.
Added:
Could also be mootools. Also uses $
Added:
'some_edit' would be the id of an element.
ps. I agree $ could be anything. Odds are though that it is JQuery or Mootools. "When you hear hoof beats, think horses, not zebras."

Related

creating Vanilla JS equivalent css method of jQuery

I am trying to create a function like the function of jQuery which changes the style of an HTMLElement, probably you have seen it somewhere:
$("button").css("color", "red");
which is pretty handy, so here is what I've tried:
function $(selector, parent=document){
return parent.querySelector(selector);
}
so the above code is the code of the function $ which grabs an HTMLElement from the DOM,this seems to work perfectly.
Now, the next step for me is to define the $ function methods and properties, so the method I want to create is the css method as seen in the previous example:
$.css = function(style, value){
this[style] = value;
}
now after testing the css method it's not working (and of course it will never work, but I'm just trying to deliver my question idea for you).
I know a lot about object-oriented programming in JavaScript, I am comfortable with it, so I have no problem if you posted any answer, I will try my best to understand it.
I've tried a lot to understand what's the magic that the jQuery developers made to create this method.
What do you think the best approach to make it? what about mixins, what if I wanted other functions and not just "$" to inherit this "css" method?
To modify styles, you need to set a CSS property of the style declaration object of an element. For example:
elm.style.color = 'red';
You need to modify your $.css to access the current element(s) in the collection, and access their .style[propertyName] property.
You can put the collection onto a property of the instance, and make sure to put the css method as a prototype of the class:
function collection (selector, parent = document) {
this.elms = parent.querySelectorAll(selector);
}
collection.prototype.css = function(prop, value) {
for (const elm of this.elms) {
elm.style[prop] = value;
}
}
const $ = (...args) => new collection(...args);
$("button").css("color", "red");
<button>a button</button>
<button>a button</button>
Because your $ doesn't use new, you'll either need it to return an instance of a different class (as in the code above), or always use new when calling it, or have $ return its instance created via Object.create, or something like that. There are various methods.
Not sure if this is what you're after, but you could just apply the style inline?
var elem = document.querySelector('#some-element');
//set color to red
elem.style.color = 'red';
//set the background color to a light gray
elem.style.backgroundColor = '#e5e5e5';
//set the height to 225px
elem.style.height = '225px';

How can I make an alias for element.querySelector?

For example, my element is a DOM element div, and within it are other divs.
So I generally use elem.querySelector('.whatever') to find a child within it. But I'd like to rename querySelector to find.
But how can I do this for all DOM elements, is there an easy way? I'd rather not just have "function find(elem, what)", but rather I'd like to do it on the element itself so "elem.find('.whatever')"
You can create a function to achieve the same thing, but will give extra work to the browser
HTMLElement.prototype.find = function(selector){
//or querySelector for one element depends on need
return this.querySelectorAll(selector);
};
elem.find('.whatever');
Warning! Modifying the core prototype is a bad practice.
Another solution from "connexo"
HTMLElement.prototype.find = HTMLElement.prototype.querySelector
You can also create your own version of "jquery" if you are afraid of modifying the core prototype
function $$(element) {
return {
find: function(selector) {
return element.querySelectorAll(selector);
}
}
}
//then just wrap any object
$$(elem).find(selector);
I almost always use the global document.querySelector form, and it's definitely too verbose for my taste.
While not exactly an alias, I really like this simple solution:
function get (selector, context=document) {
return context.querySelector(selector)
}
function getAll (selector, context=document) {
return context.querySelectorAll(selector)
}
// get single element
get("#id")
// get all elements
getAll("nav li")
// all within an element
getAll("li", element)

Remove element created by JavaScript on load

How can I remove elements which are created by JavaScript, I tried using CSS by setting display:none; but that doesn't seem to solve my problem, also I can't remove them since I don't have them in HTML, any other ways? Thank you
UPDATE:
Can't use any JavaScript such as jQuery, MooTools, ExtJS etc, and actual elements I want to remove are divs, with a specified class so I can't use getElementById.
I found this script on Google, but it doesn't seem to work but this is what I need:
HERE
This is fairly simple to do this using jQuery.
$("#myId").remove();
will remove
<div id="myId"></div>
Edit: You can also do it with "old school" javascript.
The function you're looking for is removeChild()
Example:
function removeElement(divNum) {
var d = document.getElementById('myDiv');
var olddiv = document.getElementById(divNum);
d.removeChild(olddiv);
}
You will want something like this to take advantage of browser support where you can:
if(document.getElementsByClassName){
// Safari 3+ and Firefox 3+
var itms = document.getElementsByClassName('your_class');
for(var i = 0; i<itms.length; i++){
var it = itms[i];
if(it.tagName == "DIV"){
it.parentNode.removeChild(it);
i = i - 1; //It actually gets removed from the array, so we need to drop our count
}
}
} else {
// All other browsers
var itms = document.getElementsByTagName('div');
for(var i = 0; i<itms.length; i++){
var it = itms[i];
// Test that className contains your class
if(/your_class/.test(it.className)) it.parentNode.removeChild(it);
}
}
JavaScript handles all memory mangement for you using garbage collection so once all references to an object cease to exist that object will be handled by the browsers specific implementation.
If you have the dom element itself:
if(node && node.parentNode){
// return a ref to the removed child
node.parentNode.removeChild(node);
}
Since you say you can't use Javascript, you're pretty stuck. Have you tried this CSS:
.classname {
display: none !important;
}
It's possible that the created elements have inline styles set on them, in which case normal CSS is overridden. I believe the !important will override inline styles.
Of course, the best solution is not to add the element in the first place... but I'm guessing you're in one of those (unfathomably common) scenarios where you can't change or get rid of the JS?
Not all browsers have a
document.getElementsByClassName
method, but for your purpose you can
fake it well enough- This method does
not work like the native
HTMLElement.getElementsByClassName- it
returns an array, not a live nodelist.
You can specify a parent element and a
tag name to speed it up.
function getElementsByClass(css, pa, tag){
pa= pa || document.body;
tag= tag || '*';
css= RegExp('\\b'+css+'\\b');
var A= [], elements, L, i= 0, tem;
elements= pa.getElementsByTagName(tag);
L= elements.length;
while(i<L){
tem= elements[i++];
if(css.test(tem.className)) A[A.length]= tem;
}
return A;
}
// test
var A= getElementsByClass('removeClass'), who;
while(A.length){
who= A.pop(); // remove from the end first, in case nested items also have the class
if(who.parentNode) who.parentNode.removeChild(who);
who= null;
}
If you have assigned event handlers to
the elements being removed, you should
remove the handlers before the
elements.
You will probably have to be more specific.
The general answer is 'with JavaScript'. As long as you have a way of navigating to the element through the DOM, you can then remove it from the DOM.
It's much easier if you can use a library like jQuery or prototype, but anything you can do with these you can do with JavaScript.
marcgg has assumed that you know the ID of the element: if you don't but can trace it in the DOM structure, you can do something like this (in prototype - don't know jQuery)
var css_selector = 'table#fred tr td span.mydata';
$$(css).invoke('remove');
If you can't use a JS library, you'll have to do the navigation through the DOM yourself, using Element.getElementsByTagName() a lot.
Now you've specified your question a bit: use Element.getElementsByTagName, and loop through them looking at their className property.
Use:
document.removeChild('id_of_element');

Alternative to 'className' in JavaScript for IE Mobile?

I'm working on a mobile web app that needs to work in IE Mobile. I've narrowed down a JavaScript error I'm getting to IE Mobile not supporting the 'className' property (IE4 engine...). I'm trying to find an alternative that works across all browsers with minimal code changes (I already have a few libraries that use 'className').
The easiest approach I could think of would be to modify IE's element prototype to include className (if it doesn't have it), the problem is that I don't know what the alternative to 'className' is in IE Mobile.
I've tried this:
element.className = element.class;
Which obviously doesn't work because class is a keyword in JavaScript and my JS compressor doesn't like it, and it's probably not valid anyway.
Other than using 'setAttribute()' everywhere I need to modify an element's class, is there any property I can use that is the equivalent to className?
While you can't avoid using setAttribute(), you can take a line out of the jQuery playbook and use a helper procedure with an optional parameter. This code is untested, but ought to work:
var className = function (obj, value)
{
if (value !== undefined)
{
return obj.setAttribute ('class', value);
}
return obj.getAttribute ('class');
};
// Use as
alert (className (element));
className (element, "foo");
alert (className (element));
No attribute, no. I'm afraid you're stuck with getAttribute() and setAttribute().
Following up on what John Millikin, you could even make that function part of IE's element prototype:
Element.prototype.getClass = function() {
return obj.getAttribute ('class');
}
Element.prototype.setClass = function(newClass) {
return obj.setAttribute('class', newClass);
}
or if you want a combo method like John provided ...
Element.prototype.className = function(newClass) {
if (!newClass)
return this.getClass();
return this.setClass(newClass);
}

Setting properties on anonymous DOM elements through JavaScript?

Let's say I'm generating markup through server-side code. I'm generating a bunch of HTML tags but I want to add custom client-side behavior.
With JavaScript (if I had a reference to the DOM node) I could have written:
var myDOMNode = ...
myDOMNode.myCustomAttribute = "Hi!";
Now the issue here is that I don't want to qualify every element with an unique id just to initialize data. And it's really strange to me, that there's not an easier and unobtrusive way to attach client-side behavior.
If I'm remembing this correctly, this is valid IE stuff.
<div onload="this.myCustomAttribute='Hi!'"></div>
If I was able to do this, I should be able to access it's "data context" though the identifier 'myCustomAttribute', which is really what I want.
The following will work but not validate:
<div myattribute="myvalue"></div>
But if you are injecting it into the HTML with Javascript, then perhaps that's not concern for you. Otherwise, you can use something like jQuery to process the elements before adding them to the DOM:
$(elements).each(function(){
$(this).attr('myattribute','myvalue');
});
First off you should access custom attributes using the getAttribute and setAttribute methods if you want your code to work on other browsers than IE.
As to your event handler question that really depends on how you add the event handler.
Assigning a function directly to the elements onXXXX property would allow you access the the element via this.
If you use IE's attachEvent you can't use this, you can access the element that generated the event using event.srcElementbut that may be child element of the div. Hence you will need to test for the existance of myCustomAttribute and search up the ancestors until you find it.
I do appricate the input but I've finally figured this out and it's the way I go about initialization that has been the thorn in my side.
What you never wan't do is to pollute your global namespace with a bunch of short lived identifiers. Any time you put id="" on an element you're doing exactly that (same thing for any top level function). By relying on jQuery, HTML5 data and CSS there's a solution to my problem which I think is quite elegant.
What I do is that I reserve a CSS class for a specific behavior and then use HTML5 data to parameterize the behavior. When the document is ready, I query the document (using Query) for the CSS class that represents the behavior and initialize the client-side behavior.
I've been doing a lot of ASP.NET and within this context both the id="" and name="" belongs to ASP.NET and is pretty useless for anything else than internal ASP.NET stuff. What you typically find yourself doing is to get at a server-side property called ClientID you can refer to this from client-side JavaScript, it's a lot of hassle. They made it easier in 4.0 but fundamentally I think it's pretty much broken.
Using this hybrid of CSS, HTML5 data and jQuery solves this problem altogether. Here's an example of an attached behavior that uses regular expressions to validate the input of a textbox.
<input type="text" class="-input-regex" data-regex="^[a-z]+$" />
And here's the script:
$(function () {
function checkRegex(inp) {
if (inp.data("regex").test(inp.val()))
inp.data("good-value", inp.val());
else
inp.val(inp.data("good-value"));
}
$(".-input-regex")
.each(function () {
// starting with jQuery 1.5
// you can get at HTML5 data like this
var inp = $(this);
var pattern = inp.data("regex");
inp.data("regex", new RegExp(pattern));
checkRegex(inp);
})
.keyup(function (e) {
checkRegex($(this));
})
.change(function (e) {
checkRegex($(this));
})
.bind("paste", undefined, function (e) {
checkRegex($(this));
})
;
});
Totally clean, no funky id="" or obtrusive dependency.
In HTML5 there are HTML5 data attributes introduced exactly for the case.
<!DOCTYPE html>
<div data-my-custom-attribute='Hi!'></div>
is now corect, validating html. You can use any name starting with data- in any quantity.
There is jQuery .data method for interaction with them. Use .data( key ) to get, .data(key, value) to set data-key attribute. For example,
$('div').each(function () {
$(this).html($(this).data('myCustomAttribute')).data('processed', 'OK');
});
How about this?
<script>
function LoadElement(myDiv)
{
alert(this.myCustomAttribute);
}
</script>
<div onload="LoadElement(this)"></div>
not tested btw
Since you're trying to do this for multiple elements, you may try name attributes and getElementsByName.
<div name="handleonload">...</div>
window.onload = function () {
var divs = document.getElementsByName('handleonload');
for (var i = 0; i < divs.length; i += 1) {
divs[i].foo = 'bar';
}
};
Alternatively, you can use selectors, using libraries (such as jQuery and Prototype) and their respective iterators. This will also allow for you to search by other attributes (such as class).
Though, be cautious with your terminology:
obj.property = value;
<tag attribute="value">
<div style="width:100px;height:100px;border:solid black 1px" myCustomAttribute='Hi!' onclick="alert(myCustomAttribute);"></div>
The onload event is used for server side events. Its not part of the standard html element events.
Take a look at the following functions (especially the walk_the_dom one):
// walk_the_DOM visits every node of the tree in HTML source order, starting
// from some given node. It invokes a function,
// passing it each node in turn. walk_the_DOM calls
// itself to process each of the child nodes.
var walk_the_DOM = function walk(node, func) {
func(node);
node = node.firstChild;
while (node) {
walk(node, func);
node = node.nextSibling;
}
};
// getElementsByAttribute takes an attribute name string and an optional
// matching value. It calls walk_the_DOM, passing it a
// function that looks for an attribute name in the
// node. The matching nodes are accumulated in a
// results array.
var getElementsByAttribute = function (att, value) {
var results = [];
walk_the_DOM(document.body, function (node) {
var actual = node.nodeType === 1 && node.getAttribute(att);
if (typeof actual === 'string' &&
(actual === value || typeof value !== 'string')) {
results.push(node);
}
});
return results;
};
With the above two functions at hand, now we can do something like this:
some link
<script>
var els = getElementsByAttribute('dreas');
if (els.length > 0) {
els[0].innerHTML = 'changed text';
}
</script>
Notice how now I am making finding that particular element (which has an attribute called dreas) without using an id or a class name...or even a tag name
Looks like jQuery is the best bet for this one based on my searching. You can bind an object to a DOM node by:
var domNode = ...
var myObject = { ... }
$(domNode).data('mydata', mymyObj);
then you can call the data back up the same way, using your key.
var myObect = $(domNode).data('mydata');
I assume you could also store a reference to this within this object, but that may be more info then you really want. Hope I could help.

Categories

Resources