I’ve heard it said (or something similar by Manual Lemos and one of his guests in a podcast on
JSClasses.org)
There are JavaScript™ programmers and there are
jQuery programmers, and one person is usually not both.
I say there are three different types of people developing websites: software-engineers, programmers, and code-monkeys.
The code-monkeys really have no personal interest in writing code, other than it’s their job.
They may be graphic artists, or maybe the advertising/social-networking professional for a business,
or maybe just a teen building his/her own website for a band he/she plays in;
whatever their motivation, they need dynamic and/or interactive HTML pages,
and jQuery is a fantastic tool to help them create their vision without having to know (and almost daily keep up with)
the many details regarding how to leverage the power of different browsers across different platforms,
or worry about creating logic patterns that work without crashing or exposing vulnerabilities.
In other words, programming is not for everyone, but some web-developers still need to utilize scripting power.
Real programmers may go either way, and possibly even both: learning how to write code in pure JavaScript™ and/or learning how to leverage the power of one or more libraries like jQuery. They write more complex code, going beyond what the already-available libraries alone can accomplish. A true software engineer is a well-developed programmer who fully understands how to organize and structure a large set of code, and mold it into an application. A software engineer (should/hopefully) creates a code-base and supporting file-structure that maximizes efficiency by minimizing file-size and using streamlined code. Often it is found that common library files like jQuery do not have enough power in their functions, yet at the same time offer far more (and often redundant) functionality than is needed for the application being developed. For the applications I’ve been developing, this is the case. While I admire the “Sizzle” sub-component of jQuery (the part that allows you to query the DOM with CSS-like selectors), I generally find the greater jQuery package bloated and underpowered. So I developed the UniDOM project.
There are two basic parts to the UniDOM code-base.
The first handles DOM “events,”
and the second is a collection of methods for querying and working with the
DOM.
And as promised in the headlines, UniDOM‘s addEventHandler()
method
allows a programmer to write one script code-set for all browsers,
¡including low-level event capturing!
Yes, that is correct: you may now create custom drag-and-drop code, for example, and not worry about having to
write code for modern browsers as well as separate code for legacy versions of Microsoft’s Internet Exploder.
As a brief reminder, events are “captured” in the standard
DOM by passing true
as the final (3rd) argument to the standard addEventListener()
method,
whereas you must use the setCapture()
method with Internet Exploder, and the two work very differently;
so different that it is virtually, if not literally, impossible to write a “wrapper” method that can manage these
two different approaches to “event capturing” on a low level.
Sure you might be able to write a simple drag-and-drop interface that will work cross-browser with
HTML elements in a very specific and limited way. I looked at that possibility and decided
I didn’t even want to try.
UniDOM avoids that mess and simply “simulates” the capturing phase, and then if captured,
by necessity the “bubbling” phase.
So you write your code as if it were for the standard
DOM, and UniDOM does the rest!
UniDOM’s addEventHandler()
method also offers high-end programming
features such as different coding styles (functional, plus two Object-Oriented styles),
and the ability to pass to your event handler functions
an unlimited number of user arguments that are true function arguments
,
not just artificially-added “Event
object” properties.
UniDOM’s “power methods” take DOM queries to the next level, can do far more,
and are more flexible than most other popular JavaScript™ libraries out there today.
Yet UniDOM’s ultra-lightweight commented code-base is around 1∕4 of jQuery’s,
and still even less than the minimized version of jQuery.
Currently (autumn 2014) UniDOM minified and optimized
is 30KB versus jQuery minified at 94KB — less than 1∕3 the size!
Taken together, all these features make UniDOM a formidable addition to any
JavaScript™ toolkit library.
It’s true that jQuery has more features and is geared to more devices, operating systems, and browsers
than UniDOM, but then not all projects are designed for a smartphone,
or require auto-loading HTML subsections via “Ajax,” or animated pages, etc.
UniDOM takes a more modular approach to script libraries, leaving “Ajax” and animation to other code files,
giving programmers and software engineers a scripting library that is more flexible yet specialized to need,
to create new projects without being stuck inside the box.
UniDOM is not a replacement for jQuery, but it is also true that jQuery is not a replacement for UniDOM!
Although the jQuery slogan is write less, do more,
as we will see,
UniDOM can simplify scripting in ways that make the equivalent jQuery code seem like a short-story.
The secret behind UniDOM’s “power-methods” for working with the DOM lies not only in their acceptance of regular expressions, whereas for example jQuery only accepts strings:
// jQuery command:
$('.myRedFlowers, .myGreenFlowers, .myPurpleFlowers, .myOrangeFlowers, .myBlueFlowers, .myYellowFlowers, .myCyanFlowers').removeClass('.myRedFlowers, .myGreenFlowers, .myPurpleFlowers, .myOrangeFlowers, .myBlueFlowers, .myYellowFlowers, .myCyanFlowers');
// equivalent UniDOM command:
UniDOM.getElementsByClass(document.body, /\bmy(Red|Green|Purple|Orange|Blue|Yellow|Cyan)Flowers\b/ )._.removeClass( /\bmy.+Flowers\b/ );
// or maybe simply this UniDOM command:
UniDOM.getElementsByClass(document.body, /\bmy.+Flowers\b/ )._.removeClass( /\bmy.+Flowers\b/ );
UniDOM can also accept extremely complex “logic arrays,”
whereas jQuery only allows simple “and
/or
” logic in query strings
(the jQuery example above demonstrates logical “or
”,
and $('.myPurpleFlowers.onBushes');
is an example of logical “and
”).
“Logic arrays” are explained below in the section describing the UniDOM.has()
method.
Since UniDOM can also gather document elements using user-defined callbacks,
a programmer can write code that gathers callback functions from various different modules and plug-ins,
arrange them in complex “logic arrays” and perform a dynamically-created query.
jQuery users are standing there with a blank look on their face… … …
Oh, but wait, can’t a jQuery “selector string” do complex queries very simply that would be more complex for UniDOM?
$('#myGuitars .sixString:selected'); //jQuery
// vs. UniDOM without a CSS-selector engine:
UniDOM.getElementsbyClass(document.getElementById('myGuitars'), 'sixString')._.getSelected();
No problem! Again, as we shall see, UniDOM can use various different selector engines, including the one that jQuery uses.
UniDOM is a lightweight hybrid of different approaches to cross-browser DOM compatibility and “power methods,” intended for use with applications to be inserted into larger projects, with a special focus on programmers’ tools with more flexibility and power, rather than myriads of shortcut methods for the less technically minded, many of which go unused; and with a focus on script readability and method names in the original spirit of JavaScript™ that allow the uninitiated to follow along at least somewhat (especially if they know JavaScript™ or another programming language) without having to guess or use a reference as to what each method is essentially trying to do, which allows you to write cross-application code that is more accessible to more people; and also with a focus on tools that allow developers to embrace the balance of:
- minimal HTML Elements with minimal markup to the Elements:
- no “wrapper” Elements that don’t directly reflect the document content itself, simply for CSS or JavaScript™ handles
- minimize the use of classNames for example
(meaning less Elements with any classNames, and less classNames per Element)
- simplified JavaScript™ that relies as little as possible on given HTML Elements and document layout (¡more important!)
UniDOM’s coding styles:
UniDOM offers 4 programming/coding styles, all possibly available at the same time.
Note the first two functional styles commonly require “passing in” the
DOM Element to work with,
while the last two Object-oriented styles are methods of a
UniDOM.ElementWrapper
, a
UniDOM.ElementWrapperArray
,
or a native DOM Element,
so you don’t “pass in” an Element, and therefore the Object-oriented methods
take one less argument (sans the first one) than the equivalent functional.
name-spaced functional programming style
The first value passed in is always the element(s) used in the function. Most functions take only one element passed in at a time. “
==== example (removes 'myClass' className from the first descendent of element found that has said className):addEventHandler
” is the exception. Elements returned are “raw” (unwrapped) DOM Elements or “UniDOM.ElementWrapperArray
”s of them.UniDOM.removeClass(UniDOM.getElementsByClass(element, 'myClass')[0], 'myClass');
==== example (removes 'myClass' className from all descendents of element found that have said className):UniDOM.getElementsByClass(element, 'myClass')._.removeClass('myClass');
==== example - same as above but exposing only the SoftMoon nameSpace to the window (see more comments at this file’s end):SoftMoon.WebWare.UniDOM.getElementsByClass(element, 'myClass')._.removeClass('myClass');
global-functional programming style
Similar to the name-spaced functional programming style (see above), without needing the “UniDOM” nameSpace to call the power-methods. You must first call
==== example (removes 'myClass' className from the first childNode of element found that has said className):UniDOM.globalize()
which will dump all of UniDOM’s function-names into the globalwindow
namespace.removeClass(getElementsByClass(element, 'myClass')[0], 'myClass');
¡¡¡Any “tool” or “framework,” etc. should never globalize these functions!!!
¡¡¡Only the web-page developer can safely make this choice!!!
wrapper-based object-oriented programming style
with optional support of “Sizzle,” “Slick,” or the new inherentelement.querySelectorAll()
DOM method available in modern HTML5 browsers, etc. (see: http://sizzlejs.com/ & http://mootools.net/docs/core/Slick/Slick)Do not pass in elements to the individual methods, only to the initial
==== example (removes 'myClass' className from the first childNode of element found that has said className):UniDOM()
constructor function. This allows “chaining” on both individual elements and groups of them. Elements returned are “wrapped” with aUniDOM.ElementWrapper
, (find the actual Element using:myReturnedElementWrapper.element
) and groups of Elements are returned in aUniDOM.ElementWrapperArray
, (a real JavaScript™Array
with added methods tacked on) both of which have all the standard “power methods” to allow chaining. Note that you may distinguish anElementWrapper
using:(myVariable instanceof UniDOM.ElementWrapper)
(¡except whenmyVariable
is the window an Error is thrown!) but you cannot distinguish anElementWrapperArray
from any other array without checking the available “tacked on” methods (and these can be forged, if you care).UniDOM(element).getElementsByClass('myClass')[0].removeClass('myClass');
==== example (removes 'myClass' className from all descendents of element found that have said className):UniDOM(element).getElementsByClass('myClass')._.removeClass('myClass'); UniDOM(element, true).getElementsByClass('myClass').removeClass('myClass');
Note in the example above, by passing in
With “Sizzle,” or “Slick” installed on your web page, or with an HTML5 browser, UniDOM’s code simplifies to:true
as the second argument to UniDOM, we do not use the._.
interface object as methods are “appliedDirect” to the array returned bygetElementsByClass
. This may seem to take more characters (unless your script-chain is long), but you can also set the static valueUniDOM.ElementWrapperArray.wrappedElements=true
to achieve the same effect for every subsequent query. However, “applying direct” does create an extra burden on the processor as the “appliedDirect power methods” are manually added to the real JavaScript™Array
which is returned, so if your query is in a highly-repetative loop, it may noticeably slow things down on older computers.UniDOM(element, '.myClass')._.removeClass('myClass');
inherent prototype based object-oriented programming style
This optional “prototype” coding style must be specifically invoked by calling
==== example:UniDOM.prototypify()
which will modifyElement.prototype
by adding UniDOM’s power methods. We never “pass in” the element, as methods are applied via prototype directly to all Elements in the DOM. Returned values are “raw” DOM Elements or a “UniDOM.ElementWrapperArray
” of them.element.getElementsByClass('myClass')[0].removeClass('myClass');
Note that while UniDOM’s method will accept the same arguments (plus more) as the DOM standard
getElementsByClassName()
, the latter returns a “live NodeList” that changes as the DOM is updated, and we need to retain that functionality for cross-library compatibility. And remember:¡Any “tool” or “framework,” etc. should never prototypify the DOM!
Only the web-page developer can safely make this choice.
Event handling with UniDOM
addEventHandler(element, eventType, handler[, useCapture [, userArg1 [, userArg2 … … …]]])
element
*only when called as a functional- The DOM Element(s) to attach the event-handler to.
You may pass in a single Element, or a UniDOM
ElementWrapper
instance, or an array of Elements and/or ElementWrappers. Do not pass in a value forelement
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 2 arguments (plus any optional- & user-arguments), as the element is then figured by this method’s Object. eventType
- Event-types may be passed in with or without the prefixed “on” and are case-insensitive. You may pass in a single event-type (as a String), or an array of event-types. All event-types passed in will be “bound” to all elements passed in, and all event-handlers you pass in will be called upon by every one of these event-types. Custom user-defined event types may be used. With legacy versions of Micorsoft’s® Internet Exploder, since custom events can not be used as “listeners,” UniDOM keeps track of these and “manually fires” them using generateEvent.
handler
- You may add a single event handler, or an array of event handlers (using one single call to addEventHandler())
to be called in order by the wrapper function.
That is, all handlers will be called by each
eventType
you add. When you add [an] event handler[s], it/they is/are “wrapped” with an internal closure-function, and this wrapper is then the actual attached event handler. Each handler added usingaddEventHandler()
may be:- a function (same as usual for standard DOM or MSIE)
- an Object with a generic “
handleEvent
” method (Mozilla® Firefox® style) - an Object with a method to match the event type,
i.e.
myObject.onclick
,myObject.onmouseover
,myObject.onfocus
, etc. The method name must be the event-type in all lowercase, prefixed with “on”, regardless of how you registered it.
===== myHandler=function(event) {console.log("myHandler unhandled "+event.type+" → "+event.target.name)}; myHandler.onclick=function(event) {… … …}; myHandler.onmouseover=function(event) {… … …}; myHandler.onmouseout=function(event) {… … …}; UniDOM.addEventHandler(element, ['click', 'mouseOver', 'mouseMove', 'mouseOut'], myHandler); ===== myObject={/*… … properties and methods, foos and bazes … …*/} myObject.handleEvent(event) {console.log("myObject unhandled "+event.type+" → "+event.target.name)}; myObject.onclick=function(event) {… … …}; myObject.onmouseover=function(event) {… … …}; myObject.onmouseout=function(event) {… … …}; UniDOM.addEventHandler(element, ['click', 'mouseOver', 'mouseMove', 'mouseOut'], myObject); =====
You may also pass in an Array of handlers and all will be called in order, so given the examples above, we can do:===== anotherHandler=function(event) {/*… …handle all events… …*/}; UniDOM.addEventHandler(element, ['click', 'mouseOver', 'mouseMove', 'mouseOut'], [myHandler, myObject, anotherHandler]); =====
When using multiple event-handlers (in an Array), any one of them may change the property “doContinue” of the “event” object to “false” (event.doContinue=false;
) to cancel calling the rest in the Array. This will not cancel bubbling or capturing, and this will not cancel other event-handlers added using a separate call to “addEventHandler”.
¡¡¡Don’t forget an Array of event-handlers is {{live}}, so you can change itafter you add it; therefore, additions to an Array of event-handlers are affected by and can effect “ event.doContinue
”!!!
In the example below (given the examples above), no “unhandled” events will be logged:===== anotherHandler=function(event) { if (event.type=='mousemove') event.doContinue=false; //block the rest of the handlers in the handler-array /*… …handle all mouseMove events… …*/ }; UniDOM.addEventHandler(element, ['click', 'mouseOver', 'mouseMove', 'mouseOut'], [anotherHandler, myHandler, myObject]); =====
The value of the JavaScript™ keyword “this
” within the added handler function or Object method will be as follows:function → this=
→the Element to which the event handler was “added” myObject.handleEvent
→ this=
→myObject
myObject['on'+event.type]
→ this=
→myObject
event ={ id:
unique id generated for each event target:
MSIE’s event.srcElement
→ the Element, Document, or Window that generated the event, i.e. a possiblechildNode
of the “currentTarget
” element during capture or bubble phases.currentTarget:
element
→ the current element which is handling the event, to which an event handler is attached (value of “this
” when an event-handler is attached to or is a property of an Element).relatedTarget:
MSIE’s (event.fromElement || event.toElement)
the Element from which the mouse is going/coming.eventPhase:
1
← when using MSIE, only when you employ the simulated capture phase.eventPhase:
MSIE’s (event.srcElement===element) ? 2 : 3
where element is the one you attach the event to. (2 is the “ontarget
” phase; 3 is the bubbling phase; same as standards)charCode:
MSIE’s event.keycode
offsetX:
↓→mouse offset from the “target” element: offsetY:
↑→calculated for standards-complient browsers when applicable to the event type currentX:
↓→mouse offset from the “currentTarget” element: currentY:
↑→calculated for standards-complient browsers when applicable to the event type stopPropagation:
with MSIE: function() {this.cancelBubble=true;}
This will also stop propagation during the simulated capturing phase.preventDefault:
with MSIE: function() {this.returnValue=false;}
MSIE:
true
when using legacy DOM event-handling with old versions (IE9 & earlier) of Microsoft’s Internet Exploder; undefined otherwise. Do note that IE9 can use standard DOM event-handling (as well as its legacy DOM package), and when using the standards, this property’s value will be undefined.} useCapture
- Boolean: default=
false
For Microsoft’s Internet Exploder, the “capturing phase” of an event is simulated, provided that both the “capturing” event handlers and any event handlers on descendent elements are registered with UniDOM. See also theUniDOM.enable_oldMSIE_capture()
function to guarantee this provision when also using third-party software that doesn’t use UniDOM. You should useevent.stopPropagation()
as with the standard DOM, within any phase of the event. userArg
… … …- You may pass in any number of optional user arguments, and each will be passed as a unique argument to every
one of your event handlers in your
handler
-array. For example, you might have an HTML photo gallery, with photos displayed in order of popularity. The page is loaded with the gallery, and on the side-bar you want to use JavaScript™ to add an alphabetized list of people who took each photo. So your script would gather the images and their respective data, build the sidebar menu, and attach anonClick
oronMouseOver
event-handler to each menu item://given an Object containing the <img/> tags // and an alphabetized array of objects holding the photographer’s name & rank: for (var i=0; i<data.length; i++) { li=build_li_(data[i].name); // use your function defined elsewhere UniDOM.addEventHandler(li, ['onMouseOver', 'onClick'], popPic, false, images[data[i].imageName], data[i].imageName, data[i].photographer, data[i].rank, document.body); } // and now our popPic function is very generic, versatile, and easy to read: function popPic(event, imageTag, imageName, photographer, rank, container) { var popup, old; popup=document.createElement('div'); popup.appendChild(imageTag.cloneNode(false)); popup.appendChild(document.createTextNode(imageName + ' by ' + photographer + ': ' + rank + '%')); popup.id='rank_popup'; if (old=document.getElementById('rank_popup')) old.parentNode.replaceChild(old, popup); else container.appendChild(popup); if (event.type==='click') imageTag.scrollIntoView(); }
Return value:
UniDOM’s addEventHandler
returns either:
•an Object holding references to “UniDOM.EventHandler
” instance-Objects;
or if you “pass in” an array of elements, •a corresponding array of the above-said “holding-Objects.”
Each of the “holding-Object’s” properties correspond to each event type registered.
Each “holding-Object” property name is the exact same as you pass in for the event type.
The UniDOM.EventHandler
instance-Objects hold vital info about your attached
event handlers, and have live active members.
Here’s a possible example of an Object returned:
rtnval = UniDOM.addEventHandler(element,
['onMouseOver', 'onMouseOut', 'click'],
myMouseHandler);
/* an example of rtnval = {
onMouseOver: // a UniDOM.EventHandler instance
onMouseOut: // a UniDOM.EventHandler instance
click: // a UniDOM.EventHandler instance
}
*/
Static Properties:
You may globally alter some features of the addEventHandler()
function.
property | initial value | description |
---|---|---|
errorOnDoubleBind: | false |
This Boolean flag controls whether to throw an Error when trying to double-bind the same
handler function(s) with the same eventTypes on the same
element using the same useCapture flag.
UniDOM will never double-bind, and if this flag is false, attempts to do so will be silently ignored! |
retroMSIE9: | null |
This Boolean flag controls whether MSIE9 should use its legacy attachEvent()
method (with UniDOM’s simulated capture) or the standard
DOM addEventListener() method.
It also controls whether UniDOM.generateEvent() & UniDOM.triggerEvent()
use fireEvent() (Boolean true )
or the standard dispatchEvent() (Boolean false ),
or with UniDOM.generateEvent() both if this flag is null .
When I once tried to use two separate JavaScript™
software packages that used opposing methods from each-other,
I started getting stack-overflows when one function called another in succession
(functions that were not even event related!), and what seemed like memory corruption causing
browser instability. |
UniDOM.EventHandler
Object instances
id: | unique id ←¡do not change this value! |
element: | ¡do not change this value, it is not live! |
eventType: | ¡do not change this value, it is not live! This value is all lowercase without the leading “on” |
handler: | {{LIVE}} an array of the handlers that are executed in order by the wrapper (see below) for each event |
handler.suspend: | {{LIVE}} Boolean value to temporarily suspend calling the handlers (but the wrapper is still active) |
wrapper: | ¡do not change this value, it is generally not live!
This is the wrapper function that is actually added as an event handler to the element.
This wrapper then calls each of the functions in the handler array (see above).
You may invoke this wrapper directly ( myEH.wrapper(event); ) to simulate an event.
Old MSIE uses this property to simulate event capturing, so in that case,
during the simulated capture & bubble phases, this property is {{LIVE}} |
userArgs: | {{LIVE}} an array of user arguments; each passed as an argument to each handler function by the wrapper. |
remove(): | This method removes (unbinds) the event handler wrapper from the element
and sets this Object’s id to false .
(see also UniDOM.removeEventHandler )
It is best practice to keep track of your EventHandler returned by UniDOM’s
addEventHandler and then use it to remove (unbind)
the handler from the element:
// myBinding will be a plain Object that holds EventHandler instances:
myBinding=UniDOM.addEventHandler(document.body, "mouseUP", dragDROP, true);
function dragDROP(event) {
// the .mouseUP property is a UniDOM.EventHandler instance:
myBinding.mouseUP.remove();
/* now do whatever to drop the dragged thing */ } |
You may alter the arrays of the “handler
” and “userArgs
” properties of a
UniDOM.EventHandler
Object, but replacing them is ineffective.
For instance you may push, pop, shift, unshift or otherwise alter the handler
and userArgs
arrays,
and the wrapper function will call the functions in the modified handler-array, passing the arguments in the
modified userArgs-array, though note that even if you remove all the handlers from
the handler-array, the “wrapper
” will still be attached to the element and active.
You may use:
(myUnknownVariable instanceof UniDOM.EventHandler)
in your scripts,
but UniDOM prevents you from creating an instance by scripting myEH=new UniDOM.EventHandler(… … …);
or myEH=UniDOM.EventHandler(… … …);
You can only create an instance by using UniDOM’s addEventHandler
.
The created instance is returned as a sub-property of the returned Object.
See: addEventHandler
’s return value.
removeEventHandler(EventHandler_instance) //preferred
removeEventHandler(element, eventType, handler, useCapture)
It is easiest to keep track of the UniDOM.EventHandler
instance returned when you add an event handler.
In that case, you can simply use myEH.remove();
(see UniDOM.EventHandler
).
If you want or need to, you may instead pass the whole EventHandler
instance to this function.
If you don’t have access in the scope of a function to the EventHandler
instance
returned when the handler was added by UniDOM, you can use the long-form of this function instead
(similar to the DOM standard way).
See getEventHandler
(below) for info on the arguments
passed in to this function when using its long-form.
getEventHandler(element, eventType, handler, useCapture)
If you don’t have access in the scope of a function to the
UniDOM.EventHandler
instance
returned when the handler was added by UniDOM, you can use this function to get it.
element
*only when called as a functional- The DOM Element the event-handler is attached to.
You may pass in a single Element, or a UniDOM
ElementWrapper
instance. Do not pass in a value forelement
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 3 arguments, as the element is then figured by this method’s Object. eventType
- You may pass in only one Event-type. Event-types may be passed in with or without the prefixed “on” and are case-insensitive.
handler
- You must pass in the same handler function that you added, or an array that contains
the same handler functions in the same order.
Since a
UniDOM.EventHandler
array is {{LIVE}} (you can change it at any time) if you do change it after you “addEventHandler
” you must pass in the modified current handler selection. useCapture
- must match the Boolean value you passed in when you added the event handler.
Return value:
The properly corresponding UniDOM.EventHandler
instance.
removeAllEventHandlers(element,
[goDeep])
element
*only when called as a functional- The DOM Element the event-handlers are attached to.
You may pass in a single Element, or a UniDOM
ElementWrapper
instance. Do not pass in a value forelement
when usingElementWrapper
— or prototype— based Object-oriented programming styles; the element is then figured by this method’s Object. goDeep
- Optional: default is
false
. Whether to remove handlers from DOM childnodes and recursively their children. SeegetElements
for more details on the use of this parameter.
generateEvent(element, eventType, eSpecs)
For high-level event-creation. This will create a new Event-Object and then dispatch/fire an event using it, and is cross-browser friendly. For legacy versions of MSIE that do not recognize custom user-defined (synthetic) event-types, this method will simulate properly “firing” the custom event if it was registered using UniDOM’s addEventHandler.
element
*only when called as a functional- The DOM Element to generate the event on.
You may pass in a single Element, or a UniDOM
ElementWrapper
instance. Do not pass in a value forelement
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 2 arguments, as the element is then figured by this method’s Object. eventType
- You may pass in one Event-type or an Array of Event-types. Event-types may be passed in with or without the prefixed “on” and are case-insensitive.
eSpecs
- An object with property names to define the specifications for the Event you want to generate.
Please refer to a good book on JavaScript™ for further info.
Note you must supply a value for
eSpecs.view
if you want to set any other explicit specifications (excepteSpecs.bubbles
andeSpecs.cancelable
). Some example specs are below for all browsers except old MSIE:eSpecs.bubbles, eSpecs.cancelable
all Events eSpecs.view, eSpecs.detail
UIEvents (includes key events and mouse events) eSpecs.screenX, eSpecs.screenY, eSpecs.clientX, eSpecs.clientY, eSpecs.ctrlKey, eSpecs.altKey, eSpecs.shiftKey, eSpecs.metaKey, eSpecs.button, eSpecs.relatedTarget
MouseEvents eSpecs.buttons, eSpecs.movementX, eSpecs.movementY, eSpecs.offsetX, eSpecs.offsetY, eSpecs.region, eSpecs.which
MouseEvents in newer browsers if (eSpecs.userArgs) for (p in eSpecs.userArgs) {event[p]=eSpecs.userArgs[p];}
Related Static Properties:
property | initial value | description |
---|---|---|
retroMSIE9: | null |
This Boolean flag controls whether MSIE9 should use its legacy attachEvent()
method (with UniDOM’s simulated capture) or the standard
DOM addEventListener() method.
It also controls whether UniDOM.generateEvent() & UniDOM.triggerEvent()
use fireEvent() (Boolean true )
or the standard dispatchEvent() (Boolean false ),
or with UniDOM.generateEvent() both if this flag is null .
When I once tried to use two separate JavaScript™
software packages that used opposing methods from each-other,
I started getting stack-overflows when one function called another in succession
(functions that were not even event related!), and what seemed like memory corruption causing
browser instability. |
triggerEvent(element, event)
For low-level event-creation. You must create your own new Event-Object (you can not reuse one once the event has occurred). You must determine the proper method (old MSIE or standard) for creating your new Event-Object, but this function is then cross-browser friendly. This method is currently not available in the “Element-prototype” programming style.
element
*only when called as a functional- The DOM Element to dispatch the event on.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument, as the element is then figured by this method’s Object. - event
- An Event-object created with your low-level code using
document.createEvent
ordocument.createEventObject
.
Related Static Properties:
property | initial value | description |
---|---|---|
retroMSIE9: | null |
This Boolean flag controls whether MSIE9 should use its legacy attachEvent()
method (with UniDOM’s simulated capture) or the standard
DOM addEventListener() method.
It also controls whether UniDOM.generateEvent() & UniDOM.triggerEvent()
use fireEvent() (Boolean true )
or the standard dispatchEvent() (Boolean false ),
or with UniDOM.generateEvent() both if this flag is null .
When I once tried to use two separate JavaScript™
software packages that used opposing methods from each-other,
I started getting stack-overflows when one function called another in succession
(functions that were not even event related!), and what seemed like memory corruption causing
browser instability. |
enable_oldMSIE_capture()
If you want to use UniDOM’s simulated capture function with old versions Microsoft’s Internet Exploder, and you need to be able to use third-party JavaScript™ scripts at the same time, call this function before loading any third-party scripts. This will modify the DOM’s ElementNode prototype “attachEvent” method to run through UniDOM’s script for compatibility; otherwise, third-party event-handlers can not be blocked during the simulated capture, or bubbling may occur twice.
setMouseEventOffsets(event)
For Firefox® and other older browsers that do not support the non-standard
event.offsetX
, event.offsetY
,
event.currentX
, and event.currentY
properties introduced by MSIE.
This function is called automatically by UniDOM’s event-handler “wrappers” as needed,
so there is no need to call this function
independently if you use UniDOM.addEventHandler
.
Note that this is only available in the functional programming styles,
not as a method of an Element or ElementWrapper
.
- event
- A standard event-Object (which holds the mouse position on the window).
Return value:
The event
-Object modified to reflect the mouse-offset-distances from the event.target
and event.currentTarget
.
getMouseOffset(element, event)
element
*only when called as a functional- The DOM Element
from which to figure the mouse position {x,y} distance.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument, as the element is then figured by this method’s Object. - event
- A standard event-Object (which holds the mouse position on the window).
Return value:
An Object:
{x: /*horizontal distance*/ ,
y: /*vertical distance*/ }
Client Info
getScreenX(_window_)
getScreenY(_window_)
These functions are only available in the functional programming styles.
_window_
- Optional window-object reference; default is the current window the script is running in.
Return value:
The position of the browser on the screen. Legacy-browser friendly.
getInnerWidth(_window_)
getInnerHeight(_window_)
These functions are only available in the functional programming styles.
_window_
- Optional window-object reference; default is the current window the script is running in.
Return value:
Dimensions of the browser window. Legacy-browser friendly.
getScrollX(_window_)
getScrollY(_window_)
These functions are only available in the functional programming styles.
_window_
- Optional window-object reference; default is the current window the script is running in.
Return value:
Number of pixels the document is scrolled from the left and top. Legacy-browser friendly.
getDocumentWidth(_window_)
getDocumentHeight(_window_)
These functions are only available in the functional programming styles.
_window_
- Optional window-object reference; default is the current window the script is running in.
Return value:
Dimensions of the document. Legacy-browser friendly.
UniDOM.MS_Exploder
Numerical integer value indicating the base-version of Microsoft’s Internet Exploder,
or null
if UniDOM detected another browser.
DOM query & manipulation tools
window.getComputedStyle(element)
For old versions of Microsoft’s Internet Exploder that don’t have a native version of this global function, UniDOM gives you a cross-browser shell-wrapper-function as defined below:
function getComputedStyle(element) {return element.currentStyle}
getElementOffset(element, [scroll])
getElementOffset(element, [ancestor])
element
*only when called as a functional- The DOM Element from which to figure the
offset distance {x,y} from either the •beginning of the document,
or the •viewport (see
scroll
below), or the •ancestor
. You may pass in a single Element, or a UniDOM ElementWrapper. Do not pass in a value forelement
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style accepts only 1 optional argument, as the element is then figured by this method’s Object. scroll
- Optional Boolean: if
true
, the offset is figured from the top-left corner of the viewport. The default value isfalse
. ancestor
- If a DOM Element
which is an ancestor to
element
is passed, the offset is figured from theancestor
instead of the document or viewport.
Return value:
An Object:
{x: /*horizontal distance*/ ,
y: /*vertical distance*/ }
isElementNode(unknown)
unknown
*only when called as a functional- The value to test. You may pass in a single unknown value.
Do not pass in a value for
unknown
when using theElementWrapper
—based Object-oriented programming style; the value is then figured by this method’s Object. Note that UniDOM’s Element-gathering functions can also gather DOM Nodes other than Elements, and these may then be wrapped with aUniDOM.ElementWrapper
. Note also that while this is primarily used as a functional (asUniDOM.isElementNode()
or the equivalent as a global function) and also a —method— of anElementWrapper
, logically there is no equivalent method in UniDOM’s Element-prototype—based programming style.
Return value:
Boolean
getAncestor(element, cb
[, goDeep [, objFltr [, applyDirect [, powerSelect]]]])
Crawls (transverses) the document backwards to find the matching ancestor element of
element
, and possibly recursively its ancestors, depending on goDeep
.
element
*only when called as a functional- The DOM Element from which to begin crawling the document.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument (plus any of the optional arguments), as the element is then figured by this method’s Object. cb
- Callback function: should decide whether each element passed to it is the ancestor of choice and return a Boolean value indicating such choice.
goDeep
- Whether to (continue to) recursively check the
parentNode
(s) of the matching element(s). May be: •Boolean (default isfalse
forgetAncestor
methods,true
forgetElements
methods) or a •function that evaluates each individual element passed to it and returns a Boolean value. WhengoDeep
is a function, a second argument is also passed to it referring back to the “context”element
which was passed into thisgetAncestor
function. UniDOM’sgetAncestor()
andgetElements()
each work a little different depending on the value ofgoDeep
. WithgetAncestor()
methods,goDeep
is ignored until the first match is found. IfgoDeep==false
or alternativelygoDeep()==false
after a match is found, then the query ends and the matching ancestor(s) will be returned. ojbFltr
- An Object-property-name-filter function to enhance the returned Array value with named properties
referring to members of the Array. See:
objectify
. applyDirect
- Boolean: ¿Apply “power methods” directly to returned arrays?
See the
UniDOM.ElementWrapperArray
constructor. powerSelect
- Boolean: ¿Apply nonstandard methods (
getSelected()
&setSelected()
) to<select>
elements? See:powerSelect
.
Return value:
If no match is found, false
is returned.
If goDeep
evaluates to false
on the first match found, that single element will be returned.
If goDeep
evaluates to true
on the first match found, an
ElementWrapperArray
(a simple Array with added “UniDOM power methods”)
is returned (the result may only be one member, or multiple members of elements).
¡Note that the returned array is in reverse order from the document contents!
getElements(element, cb
[, goDeep [, objFltr [, applyDirect [, powerSelect]]]])
Crawls (transverses) the document to gather the matching childNodes
of element
,
and possibly recursively their children depending on goDeep
.
element
*only when called as a functional- The DOM Element from which to begin crawling the document.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument (plus any of the optional arguments), as the element is then figured by this method’s Object. cb
- Callback function: should decide whether each element passed to it is the descendent of choice and return a Boolean value indicating such choice.
goDeep
- Whether to recursively check
childNode
s of the element. May be: •Boolean (default istrue
forgetElements
methods,false
forgetAncestor
methods) or a •function that evaluates each individual element passed to it and returns a Boolean value. WhengoDeep
is a function, a second argument is also passed to it referring back to the “context”element
which was passed into thisgetElements
function. UniDOM’sgetAncestor()
andgetElements()
each work a little different depending on the value ofgoDeep
. WithgetElements()
methods, ifgoDeep=false
then the children of each element willnot be considered. ForgetElements
,getJuniors
, andgetElders
methods, whengoDeep
is a function, it may also set thedoContinue
property of itself tofalse
using the codearguments.callee.doContinue=false
(or even the callbackcb
function may setgoDeep.doContinue=false
), and the query will terminate immediately. Note that UniDOM always resets thedoContinue
property totrue
when it starts a query, so you don’t need to worry about resetting it. ojbFltr
- An Object-property-name-filter function to enhance the returned Array value with named properties
referring to members of the Array. See:
objectify
. applyDirect
- Boolean: ¿Apply “power methods” directly to returned arrays?
See the
UniDOM.ElementWrapperArray
constructor. powerSelect
- Boolean: ¿Apply nonstandard methods (
getSelected()
&setSelected()
) to<select>
elements? See:powerSelect
.
Return value:
If matching elements are found, returns an ElementWrapperArray
(a simple Array with added “UniDOM power methods”) of HTML elements (though there may only be one array member).
Returns an empty array if no matches found.
getJuniors(element, cb
[, goDeep [, objFltr [, applyDirect [, powerSelect]]]])
Crawls (transverses) the document of all
DOM Elements following element
(its childNodes and following siblings),
and possibly recursively their children and ancestors’ following siblings depending on goDeep
,
to gather matching DOM Elements.
See getElements
for details on arguments passed to this function,
and the return value from this function.
This useful example below uses the getJuniors
method; but it also exemplifies for
getAncestor
, getElements
, and getElders
how to use
the callback cb
function and how to pass a function for goDeep
.
It also exemplifies using goDeep.doContinue
, but that feature is not available for
getAncestor
since it is illogical: you simply pass false
from goDeep()
to achieve the same result of immediately terminating the query.
var goDeep=function(e) {return !(e.className.match( /\bdisabled\b/ ));},
cb=function(e) {
if (( (e.nodeName==='INPUT' && e.type==='text')
|| e.nodeName==='TEXTAREA' )
&& !e.disabled) {
goDeep.doContinue=false;
return true; }
else return false; },
nextTextIn=UniDOM.getJuniors(currentTextIn, cb, goDeep)[0];
getElders(element, cb
[, goDeep [, objFltr [, applyDirect [, powerSelect]]]])
Crawls (transverses) the document backwards of all
DOM Elements preceding element
(its preceding siblings and parentNode),
and possibly recursively their children and ancestors’ previous siblings depending on goDeep
,
to gather matching DOM Elements.
See getElements
for details on arguments passed to this function,
and the return value from this function, except:
¡Note that the returned array is in reverse order from the document contents!
hasAncestor(element, unknown)
Crawls (transverses) the document to see if unknown
is an ancestor of element
.
element
*only when called as a functional- The DOM Element from which to begin crawling the document.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument, as the element is then figured by this method’s Object. unknown
- The variable you want to check to see if it is an ancestor of
element
.
Return value:
Returns a Boolean value reflecting the truth of the logic it was passed to evaluate.
hasElement(element, unknown)
Crawls (transverses) the document to see if unknown
is a descendent of element
.
Note that this function is the inverse of hasAncestor; internally it uses
the code hasAncestor(unknown, element)
which is faster than transversing the DOM
tree forward through all branches. But also note that unknown
may be any value,
whereas element
should be a DOM element node;
this function therefore gives the user two advantages: a logical syntax that is easy to understand when read,
and an extra condition to check that unknown
is indeed an element before internally calling hasAncestor
which requires its first argument to be an element
.
element
*only when called as a functional- The DOM Element from which to begin crawling the document.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument, as the element is then figured by this method’s Object. unknown
- The variable you want to check to see if it is a descendent of
element
.
Return value:
Returns a Boolean value reflecting the truth of the logic it was passed to evaluate.
getElementsByName(element, name
[, goDeep [, objFltr [, applyDirect [, powerSelect]]]])
Crawls (transverses) the document to gather the matching childNodes
of element
,
and possibly recursively their children depending on goDeep
.
See getElements
for details on arguments other than name
passed to this function, with the following exception:
¡Note that this function is unique in that it supplies a default objFltr
-function
which will add object-property names to the returned array that match the name
attributes
of the selected Elements!
name
- Each Element’s
name
attribute is compared with thename
you pass into this function. You may pass in a String, a Regular-Expression, or a “logic-Array” of Strings, Regular-Expressions, and/or more nested “logic-Arrays”. See UniDOM’shas
function for more info on “logic-Arrays”. If you don’t pass in a value forname
(or pass innull
or an empty string) all elements with aname
attribute will be collected (typically,<input>
s,<textarea>
s and<select>
s).
Return value:
If matching elements are found, returns an ElementWrapperArray
(a simple Array with added “UniDOM power methods”) of HTML elements (though there may only be one array member).
As noted above, the returned array is by default objectified
with
property names corresponding to the Elements’ names.
Returns false
if no matches found.
getAncestorByClass(element, className
[, goDeep [, objFltr [, applyDirect [, powerSelect]]]])
Crawls (transverses) the document to gather the matching ancestor(s) of element
.
See getAncestor
for details on arguments other than className
passed to this function, and the return value from this function.
className
- Each Element’s
className
attribute is “properly” compared with theclassName
you pass into this function. SeehasClass
for detailed information.
getElementsByClass(element, className
[, goDeep [, objFltr [, applyDirect [, powerSelect]]]])
Crawls (transverses) the document to gather the matching childNodes
of element
,
and possibly recursively their children depending on goDeep
.
See getElements
for details on arguments other than className
passed to this function, and the return value from this function.
className
- Each Element’s
className
attribute is “properly” compared with theclassName
you pass into this function. SeehasClass
for detailed information.
getAncestorByComplex(element, conditions
[, goDeep [, objFltr [, applyDirect [, powerSelect]]]])
Crawls (transverses) the document to gather the matching ancestor(s) of element
.
See getAncestor
for details on arguments other than “conditions
”
passed to this function, and the return value from this function.
conditions
- Should be an Object with two properties:
data
andfilter
.data
should be a “logic-Array,” andfilter
should be a callback function that decides whether each Element passed to it passes each “condition” of the logic array. See UniDOM’shas
function for more info on using filter callback functions with “logic-Arrays”.
getElementsByComplex(element, conditions
[, goDeep [, objFltr [, applyDirect [, powerSelect]]]])
Crawls (transverses) the document to gather the matching childNodes
of element
,
and possibly recursively their children depending on goDeep
.
See getElements
for details on arguments other than “conditions
”
passed to this function, and the return value from this function.
conditions
- Should be an Object with two properties:
data
andfilter
.data
should be a “logic-Array,” andfilter
should be a callback function that decides whether each Element passed to it passes each “condition” of the logic array. See UniDOM’shas
function for more info on using filter callback functions with “logic-Arrays”.
hasClass(element, className [, logic])
element
*only when called as a functional- The DOM Element who’s class name to check.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument (plus 1 optional argument), as the element is then figured by this method’s Object. className
- The Element’s className property (similar to its className attribute) is “properly” compared with the
className
you pass into this function. You may pass in a •String, a •Regular-Expression, a •callback Function, or a •“logic-Array” of Strings, Regular-Expressions, callbacks, and/or more nested “logic-Arrays”. ¡Note howhasClass()
works differently when using a String compared withgetElementsByClass()
andgetAncestorByClass()
! If you pass in multiple class names as a string with a space, the className property (attribute value) of a matching element must have these class names in the given order, adjacent to each-other. For example, given four elements:<div class='foo bar'> <div class='baz foo bar buz'> <div class='foo buz bar'> <div class='bar foo'>
only the first two matchhasClass( 'foo bar' )
but all four matchhasClass( ['foo', 'bar'] )
You can use this fact to style Elements with CSS in a similar fashion, but gather them for use by JavaScript™ in different groups. ¡Contrast this withgetElementsByClass()
andgetAncestorByClass()
which convert a single-string with spaces to an Array before internally callinghasClass()
! So:getElementsByClass( 'foo bar' ) ≡≡≡ hasClass( ['foo', 'bar'] ) getElementsByClass( ['foo bar'] ) ≡≡≡ hasClass( 'foo bar' ) getElementsByClass( ['foo', 'bar'] ) ≡≡≡ hasClass( ['foo', 'bar'] ) getElementsByClass( ['foo bar', 'buz'] ) ≡≡≡ hasClass( ['foo bar', 'buz'] ) ← matches only the second div in the above example
Note that the examples above demonstrate the fact that whenclassName
is a “logic-Array,” the Boolean logical relationship between Array members is “and;” that is, all array members must match the Element’s className. You may change this logical relationship between members by setting the “logic” property of this Array, or by passing a value forlogic
(see below). Given the four<div>
elements in the example above,mySub=['baz', 'buz']; mySub.logic='xor'; hasClass(['foo', 'bar', mySub]);
Above matches<div class='foo fuq bar buz'>
and matches only the third<div>
above. See UniDOM’shas
function for more info on “logic-Arrays.”
In addition to the relational logic in a “logic-Array,” you may also prefix any string you pass in with the ! character for logical “not.” Using the example HTML of 4<div>
s given above, the following example matches only the third<div>
:hasClass(['buz', '!baz'])
; whilehasClass(['foo', 'bar', '!foo bar'])
only matches the last two<div>
s. Note then how'!foo bar'
negates the complete string, not just the first classNamefoo
. And finally, any Regular Expression or callback Function that you pass in as aclassName
may have a property, “not
,” that will negate its evaluated return value. In the example below, an online restaurant menu may have a section that lets users choose certain food-groups or ingredients that they either prefer or don’t want. You could create one RegExp and toggle its “not
” property:// high-calibre example: myViceToAvoid=new RegExp( 'cheese', 'i' ); myViceToAvoid.not= (UniDOM.getElementsByName(dinner_menu_form, 'cheese').getSelected().value==='no'); // ===true myClassnameQuery = [ "dinner", "!Italian", /salad/, myViceToAvoid ]; //pasta and cheese line the gut with paper-maché // above matches: "dinner Peruvian Andes_salad blackBeans" // above matches: "Mexican pintoBeans dinner Acapolco_salad" // but not: "dinner Italian Caesar_salad parmaseanCheese" // but not: "lunch Greek_salad feta_cheese" // continuing example: myClassnameQuery.logic='or' // above matches: "dinner Peruvian Andes_salad blackBeans" // above matches: "Mexican pintoBeans dinner Acapolco_salad" // above matches: "dinner Italian Caesar_salad parmaseanCheese" // above matches: "lunch Greek_salad feta_cheese" // continuing example: myClassnameQuery.logic='xor' // no match: "dinner Peruvian Andes_salad blackBeans" // no match: "Mexican pintoBeans dinner Acapolco_salad" // no match: "dinner Italian Caesar_salad parmaseanCheese" // no match: "lunch Greek_salad feta_cheese" // above matches: "lunch Italian Greek_salad feta_cheese"
logic
- If you pass in a “logic-Array” for the
className
, you may set its “logic” property by passing it as an optional last argument. This facilitates easy function calling with one step instead of 3:hasClass(['cats', 'dogs'], 'xor');
vs.var query=['cats', 'dogs']; query.logic='xor'; hasClass(query);
Return value:
Returns a Boolean value reflecting the truth of the logic it was passed to evaluate.
addClass(element, className)
element
*only when called as a functional- The DOM Element who’s class name to add to.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument (plus 1 optional argument), as the element is then figured by this method’s Object. className
- Must be a String of the class-name to add, or an array of these.
Each
className
String is added toelement
’s className, if it does not exist already. Note this function is indiscriminate when aclassName
String has two or more space-separated class-names, in that it will not allow you to add"foo bar"
to the existing className"baz foo bar buz"
, but you can add it to the existing className"bar baz foo buz"
. You should instead pass an array:['foo', 'bar']
. It also does not check the validity of theclassName
you pass in. This function also automatically cleans extra white-space from theelement
’s existing/final className.
removeClass(element, className)
element
*only when called as a functional- The DOM Element who’s class name to remove from.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument (plus 1 optional argument), as the element is then figured by this method’s Object. className
- Must be a String of the class-name to remove, a Regular-Expression to match the class-name to remove,
or an array of these.
All copies of the
className
String are removed from theelement
’s className. Note this function is indiscriminate when aclassName
String has two or more space-separated class-names, in that it will allow you to remove"foo bar"
from the existing className"baz foo bar buz"
, but you can not remove it from the existing className"bar baz foo buz"
. You should instead pass an array:['foo', 'bar']
. This function also automatically cleans extra white-space from theelement
’s existing/final className.
useClass(element, className, flag)
element
*only when called as a functional- The DOM Element who’s class name is to be modified.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument (plus 1 optional argument), as the element is then figured by this method’s Object. className
- Must be a String or an array of Strings, of the class-name to add or remove (depending on
flag
). SeeaddClass
andremoveClass
for more info, except that note that since theaddClass
function does not use Regular-Expressions, neither can this one. flag
- Boolean: whether to add (
flag=true
) or remove (flag=false
) theclassName
.
swapOutClass(element, removals, additions)
At least one browser I’ve seen will update the DOM immediately upon changing a className as opposed to changing a style-attribute of an Element, which may be postponed until the current (event) function is complete. So if you remove a class in one statement and add another in the next, you still get a “farc-flash” effect displayed to the user. Use this for less farc.
element
*only when called as a functional- The DOM Element who’s class name is to be modified.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument (plus 1 optional argument), as the element is then figured by this method’s Object. removals
- See
removeClass
’className
description. additions
- See
addClass
’className
description.
disable(element, flag [, className])
When you disable/enable a document section, the containing element
has the className
(or its default) added/removed, and its “disabled
” property is set to equal flag
.
All descendents of element
that can accept user input or keyboard “focus” also have their
“disabled
” property set to equal flag
, excepting that
if you disable a section «A», as well as a sub-section «B» of «A»,
when you then enable (flag=false
) section «A», its sub-section «B» will remain disabled if you
pass in the same className (or use the default) for both section «A» and its sub-section «B».
For standards-complient browsers that have the capability (not legacy versions of Micorsoft’s Internet Exploder),
an “onDisabledStateChange
” event is also fired/triggered on the
element
as well as on all of its above-noted user-input descendents.
The Event
-object passed into your onDisabledStateChange
handler will have a property
(event.disable
) with a Boolean value corresponding to flag
.
element
*only when called as a functional- The DOM Element containing the document section to be disabled.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument (plus 1 optional argument), as the element is then figured by this method’s Object. flag
- Boolean: whether to disable (
flag=true
) or enable (flag=false
) this document section. className
- Must be a String or an array of Strings, of the class-name(s) to add or remove (depending on
flag
). The default value forclassName
is “disabled
”. SeeaddClass
andremoveClass
for more info, except that note that since theaddClass
function does not use Regular-Expressions, neither can this one.
has(element, data, filter)
Object.has(data, filter)
SoftMoon.WebWare.objHas(obj, data, filter)
UniDOM’s has
method is a simple but flexible “logic engine” that allows a programmer
to write code that can easily create complex, powerful,
and highly specialized dynamic queries in real-time.
This tool is the heart of all of UniDOM’s query functions/methods.
But it is flexible enough to work with any JavaScript™ Object
.
So not only is it available as a function/method to work with the DOM,
it is also available in “raw” form as a static property of the
JavaScript™ constructor Object
.
(Note that this is not a property of Object.prototype
— don’t confuse this fact.)
You can use it like this:
MyObject={foo: "bar", fi: "buz", fo: "baz", fum: "boz"};
// this way allows you to do many queries simply:
MyObject.has=Object.has;
MyObject.has(data,filter); //now perform a query on myObject
// this way allows you to do one query fast:
Object.has.call(MyObject, data, filter);
myElement=document.getElementById('myElement');
query_result=UniDOM.has(myElement, data, filter); //functional style
query_result=UniDOM(myElement).has(data, filter); //Object-oriented wrapper style
// or prototypify the DOM at page load
UniDOM.prototypify();
query_result=document.getElementById('myElement').has(data, filter); //prototypical style: makes it simple
There are many practical examples shown for hasClass
that demonstrate basic “logic-Arrays.” The UniDOM functions that utilize this “has
” method
accept a “logic-Array” and then use a filter
function similar to this one used by
hasClass
shown below:
function(e, c) { //is passed one className in the “logic-Array“ at a time
var not=false;
if (typeof c === 'function') return c(e)^c.not;
if (typeof c !== 'object' || !(c instanceof RegExp)) {
if (typeof c == 'string' && c.charAt(0)==='!') {c=c.substr(1); not=true;}
c=new RegExp('\\b'+c+'\\b'); }
return (not || c.not) ? (e.className.match(c)===null) : e.className.match(c); }
element
*only when called as a functional- The DOM Element to query.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument (plus 1 optional argument), as the element is then figured by this method’s Object. data
- A random-length “logic-Array” of a user-defined set of “conditions” to be met.
Data members that have a “logic” property should be Arrays that are considered a sub-set of conditions;
and this is recursive, so you may have deeply nested sub-set “logic-Arrays.”
The “logic” property may be any of the following (strings)
(
'and'
is default if no “logic” property is defined):'and' 'or' 'nor' 'not' 'nand' 'xor' 'xnor' 'xnot'
(“nor” and “not” have the same logical meaning) Note that these logical operators take on a slightly new, expanded meaning, as they can operate on multiple values, not only two. For example:([false, true, true]).logic='or' // logic-Array evaluates to true ([false, true, true]).logic='xor' // logic-Array evaluates to false ([false, true, true]).logic='and' // logic-Array evaluates to false ([false, true, true]).logic='xnor' // logic-Array evaluates to false ([false, true, true]).logic='nand' // logic-Array evaluates to true ([false, true, true]).logic='not' // logic-Array evaluates to false ([false, true, true]).logic='xnot' // logic-Array evaluates to true
filter
- Your filtering function should accept the arguments:
filter(obj, query_condition)
and should returntrue
if “query_condition” is met,false
if not. Thefilter
function receives the Object that UniDOM’shas
is applied as a method of (either the DOM Element or a user-Object) as the first argument, and individually each of the members of thedata
“logic-Array,” excepting if any of these members is itself (recursively) a sub-set “logic-Array,” its individual members will each be passed to thefilter
function.
Return value:
Returns a Boolean value reflecting the truth of the logic it was passed to evaluate.
Utilizing your results
objFltr
objectify(filter [, applyDirect [, powerSelect]])
Array.objectify(filter)
SoftMoon.WebWare.objectifyArray(arr, filter)
For functions/methods that return UniDOM.ElementWrapperArray
s
(really just a simple Array with some standard methods & properties tacked on),
additional “named” properties may be added to the Array, holding members of the Array for quick access in the future
without having to know which Array-member (integer) contains the needed element(s).
If the filter
(a.k.a. objFltr
) callback Function returns the
same property name for two or more elements in the Array,
the property will then hold another UniDOM.ElementWrapperArray containing the multiple elements.
==== example:
// first we pass in an “objFltr” directly through the “getElementsByClass” method → ↓
myElementsArray = UniDOM.getElementsByClass(myPageSectionElement, /^my...Blocks/ , true, function(e) {return e.className.match( /_(.+)$/ )[1];} );
// then we further “objectify” the “UniDOM.ElementWrapperArray” with a second “filter”
myElementsArray._.objectify( function(e) {return e.className.match( /my(...)Blocks/ )[1];} );
// myElementArray results might return something like this Array-Object
(note it IS a real JavaScript™ Array):
{
[0] → <div id='b0' class='mySqrBlocks _red'>
[1] → <div id='b1' class='mySqrBlocks _green'>
[2] → <div id='b2' class='mySqrBlocks _blue'>
[3] → <div id='b3' class='mySqrBlocks _yellow'>
[4] → <div id='b4' class='myTriBlocks _blue'>
[5] → <div id='b5' class='myTriBlocks _green'>
[6] → <div id='b6' class='myLogBlocks _green'>
[7] → <div id='b7' class='myLogBlocks _blue'>
[length] → 8
[_] → the “UniDOM power methods” object for this Array
[red] → <div id='b0' class='mySqrBlocks _red'>
[green] → [ <div id='b1' class='mySqrBlocks _green'> , <div id='b5' class='myTriBlocks _green'> , <div id='b6' class='myLogBlocks _green'> ] ← the “power methods” for this Array are also available through its Array._
[blue] → [ <div id='b2' class='mySqrBlocks _blue'> , <div id='b4' class='myTriBlocks _blue'> , <div id='b7' class='myLogBlocks _blue'> ] ← the “power methods” for this Array are also available through its Array._
[yellow] → <div id='b3' class='mySqrBlocks _yellow'>
[Sqr] → [ <div id='b0' class='mySqrBlocks _red'> , <div id='b1' class='mySqrBlocks _green'> , <div id='b2' class='mySqrBlocks _blue'> , <div id='b3' class='mySqrBlocks _yellow'> ]
[Tri] → [ <div id='b4' class='myTriBlocks _blue'> , <div id='b5' class='myTriBlocks _green'> ]
[Log] → [ <div id='b6' class='myLogBlocks _green'> , <div id='b7' class='myLogBlocks _blue'> ]
}
But it is flexible enough to work with any JavaScript™ Array
.
So not only is it available as a function/method to work with DOM query results,
it is also available in “raw” form as a static property of the
JavaScript™ constructor Array
.
(Note that this is not a property of Array.prototype
— don’t confuse this fact.)
You can use it like this:
myArray=["bar", "buz", "baz", "boz"];
Array.objectify.call(myArray, filter);
//or if it better suits your coding style and/or needs:
myArray.objectify=Array.objectify; //do this once…
myArray.objectify(filter); // do this as many times as you need with different filters.
arr
- The array to objectify.
objFltr
filter
- Pass in a callback-function as the
filter
(a.k.a.objFltr
) which should return a property-name (¡numerical values may override existing array members!) for the element passed into the callback, to be added as an Object-property to the finally-returned Array. ¡¡¡ the returned Array may have nonstandard properties added to <select> elements if you pass “true” forpowerSelect
!!! Each added property usually reflects a single member of the returned Array. If thefilter
callback returns the same name for multiple elements in the returned Array, the added property will be a sub- Array of elements, each reflecting a member of the overall returned Array. applyDirect
- Boolean: ¿Apply “power methods” directly to sub-arrays
when multiple elements share the same property name?
See the
UniDOM.ElementWrapperArray
constructor. powerSelect
- Boolean: ¿Apply nonstandard methods (
getSelected()
&setSelected()
) to<select>
elements? See:powerSelect
.
powerSelect
getSelected(forceReturnArray)
setSelected(value)
UniDOM.addPowerSelect(select)
UniDOM.getSelectedOptions(select [, forceReturnArray])
UniDOM.setSelectedOptions(select, value)
UniDOM.powerSelect=true
When using UniDOM’s “element-gathering” functions/methods that return
UniDOM.ElementWrapperArray
s
(really just a simple Array with some standard methods & properties tacked on),
or when using the objectify
method,
you may pass in a final optional Boolean argument “powerSelect
”
which will add nonstandard methods (getSelected()
& setSelected()
) directly to
<select>
elements.
These methods mirror the same methods that are found on the returned
ElementWrapperArray
s.
You can then write code that can get/set either a <select>
or a group of <input>
s in a UniDOM.ElementWrapperArray
without worrying about if the form-format may change a little in the future, giving more flexibility to the HTML developer.
Consider an online menu where users can choose one large side item and one small side item:
==== example: name of the element(s) that match ↓ ↓deep ↓ returns “objectify” property names applyDirect↓ ↓powerSelect
sideOrders = UniDOM.getElementsByName(myMenu, /sideOrders/, true, function(e) {return e.name.match( /\[(.+)\]/ )[1]}, true, true)
largeSide = sideOrders.large.getSelected().value;
smallSide = sideOrders.small.getSelected().value;
May return something like:
sideOrders =
{ //Array-Object: a UniDOM.ElementWrapperArray ← also has standard “power methods” “applied directly” (too many to list)
[0] → <input type='radio' name='sideOrders[large]' value='baked potato with cheese' />
[1] → <input type='radio' name='sideOrders[large]' value='cheesy broccoli' />
[2] → <input type='radio' name='sideOrders[large]' value='vegi-baked beans with cheese' />
[3] → <input type='radio' name='sideOrders[large]' value='Greek salad' checked='checked'/>
[4] → <select name='sideOrders[small]'> ← has options (these options are NOT “in” this array):
<option value='snow peas' selected='selected'>
<option value='string beans'>
<option value='creamed corn'>
[length] → 5
[_] → the “power methods” object for this Array - they are also “applied directly,” but they are not shown here for space limitations
[large] → { //Array-Object: a UniDOM.ElementWrapperArray ← also has standard “power methods” “applied directly” (too many to list)
[0] → <input type='radio' name='sideOrders[large]' value='baked potato with cheese' />
[1] → <input type='radio' name='sideOrders[large]' value='cheesy broccoli' />
[2] → <input type='radio' name='sideOrders[large]' value='vegi-baked beans with cheese' />
[3] → <input type='radio' name='sideOrders[large]' value='Greek salad' checked='checked'/>
[length] → 4
[_] → the “power methods” object for this Array
}
[small] → <select name='sideOrders[small]'> ← has options (these options are NOT “in” this array):
<option value='snow peas' selected='selected'>
<option value='string beans'>
<option value='creamed corn'>
}
largeSide='Greek salad'
smallSide='snow peas'
Now we can develop an online-menu manager software-package that allows restaurant managers to manage their menu
which may change daily based on locally available ingredients or the chef’s specials, etc.
The restaurant manager can choose a <select>
or list of <input>
s for the ingredients or menu items,
and the high-end JavaScript™
logic that puts together a customer’s order need not worry about the form’s format.
How's that go?……write less, do more… …
Also provided, the UniDOM.addPowerSelect()
function will add nonstandard methods
getSelected()
& setSelected()
directly to <select>
elements;
and the static functions UniDOM.getSelectedOptions()
& UniDOM.setSelectedOptions()
are available if you don’t want to tarnish the DOM.
powerSelect
- (The final optional argument passed into UniDOM’s “element-gathering” (and other) methods.)
Boolean: ¿Add nonstandard methods (
getSelected()
&setSelected()
) to<select>
elements? forceReturnArray
- Boolean.
The
getSelected
methods by default will return a single<input type='radio'>
element from aUniDOM.ElementWrapperArray
, or a single<option>
element from a<select>
-one field. In opposition, by default it will return an Array of one or more<input type='checkbox'>
elements, or an Array of one or more<option>
elements from a<select>
-multiple field. By default it will returnnull
if there are nonechecked
orselected
. By passing a Boolean value forforceReturnArray
you may override these defaults: passingtrue
will always return an array, with zero, one, or more elements as members; and passingfalse
will return only one element (no Array) if only one ischecked
orselected
. value
- String or an Array of Strings.
Any
<input>
or<option>
(of aUniDOM.ElementWrapperArray
or<select>
element) with a value attribute, or the text of an<option>
, that matches thevalue
(or ifvalue
is an Array, one of its members) you pass into thesetSelected()
method will bechecked
orselected
. select
- The
<select>
element you want to empower withgetSelected()
&setSelected()
methods.
Return value:
See forceReturnArray
above for details on the return value for getSelected
methods.
There is no return value for the other methods.
UniDOM’s Element Wrappers for OO style code
UniDOM.ElementWrapper(element [, applyDirect])
Object instances
A UniDOM.ElementWrapper
is simply a shell-wrapper for
a DOM element.
This wrapper has all the relevent UniDOM methods to work on the given element.
In this way, you can write Object-oriented code without modifying the
DOM’s prototypes,
and you can “chain” a UniDOM method on to the results of the previous method.
Note you can create a new wrapper using:
myWrapper=new UniDOM.ElementWrapper(myElement)
but it may be easier
to simply use the basic functional interface:
myWrapper=UniDOM(myElement)
which will return the same new ElementWrapper
.
You can always check an unknown value using (unknown instanceof UniDOM.ElementWrapper)
.
element
- The DOM element you want to wrap with UniDOM’s power methods.
applyDirect
- Boolean: this flag does not affect the
ElementWrapper
, rather it is passed on automatically to any of UniDOM’s power methods that are called on this wrapper, and when they return aUniDOM.ElementWrapperArray
thisapplyDirect
flag will affect whether UniDOM’s power methods will be added directly to the said returnedElementWrapperArray
. SeeUniDOM.ElementWrapperArray
for more details.
Instance Properties:
element
Boolean: this property mirrors the same-named argument passed into the
ElementWrapper
constructor.applyDirect
Boolean: this property mirrors the same-named argument passed into the
ElementWrapper
constructor.
Instance Methods
An ElementWrapper
has all the standard relevent UniDOM “power-methods.”
- $
- addEventHandler
- removeEventHandler
- removeAllEventHandlers
- generateEvent
- triggerEvent
- getMouseOffset
- getOffset
- getAncestor
- getElements
- getElders
- getJuniors
- getElementsByName
- getElementsByClass
- getAncestorByClass
- getElementsByComplex
- getAncestorByComplex
- hasAncestor
- hasElement
- has
- hasClass
- addClass
- removeClass
- useClass
- swapOutClass
- disable
- getSelected
- setSelected
UniDOM.ElementWrapperArray([wrapElements [, applyDirect]])
↑ a new Array will be created with the relevant “power methods”
UniDOM.ElementWrapperArray(userArray [, wrapElements [, applyDirect]])
↑ the userArray will have the relevant “power methods” added to it
Object instances
UniDOM’s ElementWrapperArray
s are simply a basic
JavaScript™ Array
with
UniDOM power methods and relevent properties tacked on.
These methods and properties are not prototyped to the Array
(there is no way to do that without affecting all
JavaScript™ arrays,
and creating custom Object instances can not duplicate the inherent functionality of the
Array.length
property).
UniDOM always uses real JavaScript™ Array
s
instead of Object
instances that “hide away” the actual element members.
(UniDOM is oriented toward flexibility for programmers, rather than merely simplicity for less-technical developers.)
We want to manipulate the Array
as an array, rather than being required to use
add()
and remove()
and getArray()
methods.
We can keep track of what we add, where, when, why, and how, and may want to hack the contents.
Since these are real JavaScript™ Array
s
(to keep the inherent length-property-functionality which can not be fully simulated),
and we can not prototype the “power-methods” into a new UniDOM.ElementWrapperArray
,
they are available through the “_
” property of the ElementWrapperArray
.
If you want to access these methods directly through the Array
,
the “power methods” must be individually copied to the new Array
, a burden on the processor.
This is not a big problem with fast modern computers, but may be on older ones in code-loops.
See the applyDirect
argument flag and the static ElementWrapperArray.applyDirect
flag.
Do note that the above-mentioned “_
” property of the ElementWrapperArray
is itself an Object
instance, and has a property referring back to the ElementWrapperArray
,
and is therefore custom-made and not simply transferable.
Also note that the UniDOM “power-methods” that generally return more
than one DOM element
return them in an ElementWrapperArray
.
These “power-methods” automatically determine the value of wrapElements
(depending on the coding style you are using),
but you may pass through them a value for applyDirect
.
wrapElements
- Boolean:
Whether the
Array
members are “wrapped” inUniDOM.ElementWrapper
s, or if they are simply “raw” DOM elements. Each member in theuserArray
and those added to the returned Array should be a DOMElement
or aUniDOM.ElementWrapper
according towrapElements
. Power-methods of thisElementWrapperArray
that return or add DOM Elements will then respect thewrappedElements
flag property, and treat theElementWrapperArray
members accordingly. applyDirect
- Boolean:
Whether to apply the “power methods” directly to this
UniDOM.ElementWrapperArray
(really just a simple Array with some standard properties tacked on). They are always available through its “_
” property.==== example: myInputs=UniDOM.getElementsByClass(myForm, 'sideOrders') myInputs._.setSelected(['potato', 'peas']); ← note the use of the ._. object to hold the methods ==== example: ↓ applyDirect myInputs=UniDOM.getElementsByClass(myForm, 'sideOrders', true, null, true) myInputs.setSelected(['potato', 'peas']); ← note now we don’t need the ._. object
Static Properties & Constructor
The default action of not applying “power-methods” directly to the
ElementWrapperArray
can be overridden by changing
the static value of: UniDOM.ElementWrapperArray.applyDirect
==== example:
UniDOM.ElementWrapperArray.applyDirect=true;
myInputs=UniDOM.getElementsByClass(myForm, 'sideOrders')
myInputs.setSelected(['potato', 'peas']);
It would usually be OK to always apply direct,
but if your program repeatedly and extensively loops through UniDOM methods that return
ElementWrapperArray
s, it may noticeably slow the process.
Likewise, the default type of Array
member is a
DOM element.
This may be overridden by setting the static value of: UniDOM.ElementWrapperArray.wrappedElements=true
to signify the use of UniDOM.ElementWrapper
s
(containing the DOM elements) instead of the
“raw” DOM elements by themselves.
Note ElementWrapper
s allow you to use UniDOM’s power methods on each individual
ElementWrapperArray
member, not only on the Array
(which would affect all members).
The UniDOM.ElementWrapperArray.dfltMethods
constructor is used
to create instances of the “power-method” objects attached to instances of
ElementWrapperArray
s as the “_
” property.
You may add to or otherwise modify it for additional methods, etc., to work on the ElementWrapperArray
,
but be sure you understand how to access the array within your newly added methods.
Instance Properties
_
This property holds all the relevent “power-methods” for the
ElementWrapperArray
. It is always available, even when the methods are also “applied directly.” SeeapplyDirect
above.wrappedElements
Boolean: this property mirrors the
wrapElements
argument passed into theElementWrapperArray
constructor, or the corresponding default value.EWAMAppliedDirect
Boolean: this property mirrors the
applyDirect
argument passed into theElementWrapperArray
constructor, or the corresponding default value. (EWAMAppliedDirect stands for “Element Wrapper Array Methods Applied Directly”).
Instance Methods
An ElementWrapperArray
has all the standard relevent UniDOM “power-methods”
for working with the DOM
(available either through its “_
” property or directly — see applyDirect
above),
plus a few additional methods specifically for working with Array
s of elements.
See UniDOM.ElementWrapper
for details on the standard “power-methods.”
Additional methods specific to ElementWrapperArray
s:
objectify(filter [, applyDirect [, powerSelect]])
Adds properties to the array defined by the
filter
callback function. See the section specific toobjectify
.wrap([flag])
Sets the
wrappedElements
property. Useful when chaining without wasting processor time wrapping intermediate results: given anElementWrapperArray
of “raw” (unwrapped) Elements:====Example: we can now chain on an individual ↓ myEWA.getElements(…).map(…).wrap().filter(…)[1].disable(…)
¡Note
wrap()
andraw()
do not modify the existing Array members, only the results of the next method in the chain!raw([flag])
Sets the
wrappedElements
property. Useful when chaining on elements, while delivering a clean array: given an individualElementWrapper
(myEW
in the example below), chaining creates an Array ofElementWrappers
… untilraw()
is called.element=myEW.getAncestor(…)[1].getElements(…).raw().filter(…)
¡Note
wrap()
andraw()
do not modify the existing Array members, only the results of the next method in the chain!add()
This method takes any number of arguments, each either a DOM element or a
UniDOM.ElementWrapper
, and adds them to the existingElementWrapperArray
. It wraps or unwraps the arguments you pass in depending on theElementWrapperArray
’swrappedElements
property flag.map(cb [, o [, wrap [, applyDirect]]])
This method works just like the standard
Array.map()
method, (with thecb()
function’s return values becoming the members of the new Array returned bymap()
) except with the optional extra arguments specific to UniDOM’s functioning. Ifwrap
is Booleantrue
then the resulting mapped-Array will be aUniDOM.ElementWrapperArray
, and theapplyDirect
flag will then affect this newElementWrapperArray
.filter(cb [, o])
This method works just like a standard
Array.filter()
method, (passing each array member to thecb()
function who’s Boolean return values determine the members of the original Array included in the new Array returned byfilter()
) except that the returned Array is aUniDOM.ElementWrapperArray
. If you pass an Object foro
,cb
will be invoked on that Object.
UniDOM(element [, applyDirect])
UniDOM(ElementWrapper [, applyDirect])
UniDOM(CSSQueryString [, applyDirect])
↑ the third argument, passData
, must be ==false
(or undefined
)
UniDOM(element‖ElementWrapper, CSSQueryString [, applyDirect])
UniDOM(eArray [, applyDirect [, passData]])
UniDOM(element‖ElementWrapper‖eArray‖userData, applyDirect, passData=true)
The basic UniDOM()
function is a catch-all for creating
ElementWrapper
s with UniDOM’s “power-methods”
to work on your chosen DOM element(s).
It is the basis for using the “wrapper-based Object-oriented programming style.”
In this respect, it is similar in function to jQuery’s “$
”.
However in contrast, note UniDOM’s “$
”
function only acts as a CSS-selector-query
Engine without “wrapping” the gathered elements.
element
- The DOM element you want to wrap with UniDOM’s
ElementWrapper
power methods. ElementWrapper
- The
UniDOM.ElementWrapper
containing the DOM element you want to “re-wrap” with UniDOM’s power methods. (note technically “wrappers” are just Objects that “point” to the element, and only give the illusion of “wrapping-around,” so you may have as manyElementWrappers
pointing to a single element as you want, and none will be “wrapped-around” interfering with another) CSSQueryString
- A Cascading-Style-Sheet category of a query-string to gather
DOM elements
that will each be individually wrapped with
UniDOM.ElementWrapper
s, and collected in aUniDOM.ElementWrapperArray
. See UniDOM’s “$
” function for more info. ¡Note that you may not passtrue
for thepassData
argument (see below) if you want to use this query-string as the first argument! eArray
- An Array that may contain any number of legal arguments for the first value
passed to this UniDOM function including nested Arrays.
Each member (recursively) will be “wrapped” in
UniDOM.ElementWrapper
s, and the group of them will be returned in one (or more when nested)UniDOM.ElementWrapperArray
(s). userData
- Any type of data may be passed through the
UniDOM()
function when itspassData
argument istrue
. SeepassData
below. applyDirect
- Boolean: this flag does not affect the
ElementWrapper
created withUniDOM()
, rather it is passed on automatically to any of UniDOM’s power methods that are called on the wrapper, and when they return aUniDOM.ElementWrapperArray
thisapplyDirect
flag will affect whether UniDOM’s power methods will be added directly to the said returnedElementWrapperArray
. SeeUniDOM.ElementWrapperArray
for more details. passData
- This argument is used internally by UniDOM’s
ElementWrapperArray
“power-methods” to pass raw data returned by the methods through theUniDOM()
function without error or confusion of data-type. There is generally no reason for you to need to use it; however if you want to play “hackey-sack” with it, go ahead… Passingtrue
for this argument will still “wrap” elements, “rewrap” existingElementWrapper
s, and array members of these two former; and thispassData
value will be simply ignored in those cases. In contrast, whenpassData=true
, passing a String for the first argument will simply return the string as user-data instead of treating the string as a CSS selector to gather elements; and as well, passing through any other variable-type for the first argument is simply passed back instead of throwing an Error.
DOM queries with CSS selectors
$(CSSQueryString , element [, objFltr [, applyDirect [, powerSelect]]])
UniDOM’s “dollar–sign” function/method $
integrates UniDOM’s total functionality with
the “CSS-Engine” of your choice.
UniDOM does not have an Engine of its own
(but given enough free time I plan on writing one that utilizes UniDOM’s powerful
“has
” method)
but it will automatically use the standard
JavaScript™—querySelectorAll
if it is available,
or else look for “Sizzle” (jQuery’s Engine) or “Slick” (MooTools’ Engine)
(see: http://sizzlejs.com/ &
http://mootools.net/docs/core/Slick/Slick).
Of course you may specify exactly which CSS-Engine
to use including any other similarly compatible.
See the UniDOM.CSSEngine
property specs below.
¡Note that if you call UniDOM.globalize()
to use the
global-functional programming style,
this method’s name $
will over-write any same-named variable in the window,
commonly used by jQuery and many other toolkits!
CSSQueryString
- String: A standard Cascading-Style-Sheet type of description to identify the Elements to be “gathered.”
The exact specifications of this query String may very slightly depending on
the “CSS-Engine” you use.
Please refer to a good tutorial on using the native
JavaScript™
querySelectorAll
method, or if using “Sizzle” or “Slick” (or another CSS Engine), their documentation. element
*only when called as a functional- The DOM Element from which to begin crawling the document.
You may pass in a single Element, or a UniDOM ElementWrapper.
Do not pass in a value for
element
when usingElementWrapper
— or prototype— based Object-oriented programming styles; using an Object-oriented style requires only 1 argument (plus any of the optional arguments), as the element is then figured by this method’s Object. ojbFltr
- An Object-property-name-filter function to enhance the returned Array value with named properties
referring to members of the Array. See:
objectify
. applyDirect
- Boolean: ¿Apply “power methods” directly to returned arrays?
See the
UniDOM.ElementWrapperArray
constructor. powerSelect
- Boolean: ¿Apply nonstandard methods (
getSelected()
&setSelected()
) to<select>
elements? See:powerSelect
.
Return value:
If matching elements are found, returns an
ElementWrapperArray
(a simple Array with added “UniDOM power methods”) of HTML elements (though there may only be one array member).
Returns an empty array
(or an empty “array-like Object: NodeList” when using the standard
DOM querySelectorAll
Engine)
if no matches found.
Note the elements returned are not individually wrapped with
UniDOM.ElementWrapper
s;
only the returned array has UniDOM’s “power-methods.”
You can instead use the code: UniDOM(CSSQueryString)
and
the resulting array members will be individually “wrapped” with “power-methods,”
as well as the returned array.