UNPKG

crossbrowdy

Version:

A Multimedia JavaScript framework to create real cross-platform and hybrid game engines, games, emulators, multimedia libraries and apps.

925 lines (816 loc) 136 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>CrossBrowdy API documentation Source: CrossBase/general/CB_Elements.js</title> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/sunlight.default.css"> <link type="text/css" rel="stylesheet" href="styles/site.cosmo.css"> </head> <body style="min-width:800px; overflow-wrap:break-word; word-wrap:break-word; word-break:break-word; line-break:strict; hyphens:none; -webkit-hyphens:none; -moz-hyphens:none;"> <div class="navbar navbar-default navbar-fixed-top "> <div class="container"> <div class="navbar-header"> <a class="navbar-brand" href="index.html">CrossBrowdy API documentation</a> <button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#topNavigation"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div class="navbar-collapse collapse" id="topNavigation"> <ul class="nav navbar-nav"> <li class="dropdown"> <a href="namespaces.list.html" class="dropdown-toggle" data-toggle="dropdown">Namespaces<b class="caret"></b></a> <ul class="dropdown-menu inline"> <li><a href="CB_Arrays.html">CB_Arrays</a></li><li><a href="CB_AudioDetector.html">CB_AudioDetector</a></li><li><a href="CB_Client.html">CB_Client</a></li><li><a href="CB_Collisions.html">CB_Collisions</a></li><li><a href="CB_Configuration.html">CB_Configuration</a></li><li><a href="CB_Configuration.CrossBase.html">CB_Configuration.CrossBase</a></li><li><a href="CB_Configuration.CrossBrowdy.html">CB_Configuration.CrossBrowdy</a></li><li><a href="CB_Controllers.html">CB_Controllers</a></li><li><a href="CB_Controllers_Proprietary.html">CB_Controllers_Proprietary</a></li><li><a href="CB_Controllers_Proprietary.WII.html">CB_Controllers_Proprietary.WII</a></li><li><a href="CB_Controllers_Proprietary.WII_U.html">CB_Controllers_Proprietary.WII_U</a></li><li><a href="CB_Device.html">CB_Device</a></li><li><a href="CB_Device.AmbientLight.html">CB_Device.AmbientLight</a></li><li><a href="CB_Device.Battery.html">CB_Device.Battery</a></li><li><a href="CB_Device.Location.html">CB_Device.Location</a></li><li><a href="CB_Device.Motion.html">CB_Device.Motion</a></li><li><a href="CB_Device.Orientation.html">CB_Device.Orientation</a></li><li><a href="CB_Device.Proximity.html">CB_Device.Proximity</a></li><li><a href="CB_Device.Vibration.html">CB_Device.Vibration</a></li><li><a href="CB_Elements.html">CB_Elements</a></li><li><a href="CB_Events.html">CB_Events</a></li><li><a href="CB_Keyboard.html">CB_Keyboard</a></li><li><a href="CB_Keyboard.chars.html">CB_Keyboard.chars</a></li><li><a href="CB_Keyboard.extended.html">CB_Keyboard.extended</a></li><li><a href="CB_Keyboard.keys.html">CB_Keyboard.keys</a></li><li><a href="CB_Modules.html">CB_Modules</a></li><li><a href="CB_Mouse.html">CB_Mouse</a></li><li><a href="CB_Mouse.CursorImage.html">CB_Mouse.CursorImage</a></li><li><a href="CB_Net.html">CB_Net</a></li><li><a href="CB_Net.Fetch.html">CB_Net.Fetch</a></li><li><a href="CB_Net.REST.html">CB_Net.REST</a></li><li><a href="CB_Net.Sockets.html">CB_Net.Sockets</a></li><li><a href="CB_Net.Sockets.SockJS.html">CB_Net.Sockets.SockJS</a></li><li><a href="CB_Net.XHR.html">CB_Net.XHR</a></li><li><a href="CB_Pointer.html">CB_Pointer</a></li><li><a href="CB_Screen.html">CB_Screen</a></li><li><a href="CB_Speaker.html">CB_Speaker</a></li><li><a href="CB_Touch.html">CB_Touch</a></li><li><a href="CB_baseSymbols.html">CB_baseSymbols</a></li> </ul> </li> <li class="dropdown"> <a href="classes.list.html" class="dropdown-toggle" data-toggle="dropdown">Classes<b class="caret"></b></a> <ul class="dropdown-menu inline"> <li><a href="CB_AudioFile.html">CB_AudioFile</a></li><li><a href="CB_AudioFileCache.html">CB_AudioFileCache</a></li><li><a href="CB_AudioFileSprites.html">CB_AudioFileSprites</a></li><li><a href="CB_AudioFileSpritesPool.html">CB_AudioFileSpritesPool</a></li><li><a href="CB_AudioFile_API.AAPI.html">CB_AudioFile_API.AAPI</a></li><li><a href="CB_AudioFile_API.ACMP.html">CB_AudioFile_API.ACMP</a></li><li><a href="CB_AudioFile_API.SM2.html">CB_AudioFile_API.SM2</a></li><li><a href="CB_AudioFile_API.WAAPI.html">CB_AudioFile_API.WAAPI</a></li><li><a href="CB_Canvas.html">CB_Canvas</a></li><li><a href="CB_GraphicSprites.html">CB_GraphicSprites</a></li><li><a href="CB_GraphicSpritesScene.html">CB_GraphicSpritesScene</a></li> </ul> </li> <li class="dropdown"> <a href="global.html" class="dropdown-toggle" data-toggle="dropdown">Global<b class="caret"></b></a> <ul class="dropdown-menu inline"> <li><a href="global.html#CB_BASE_NAME">CB_BASE_NAME</a></li><li><a href="global.html#CB_CREDITS_DEFAULT">CB_CREDITS_DEFAULT</a></li><li><a href="global.html#CB_NAME">CB_NAME</a></li><li><a href="global.html#CB_OPTIONS">CB_OPTIONS</a></li><li><a href="global.html#CB_VERSION">CB_VERSION</a></li><li><a href="global.html#CB_addCredits">CB_addCredits</a></li><li><a href="global.html#CB_baseToBase">CB_baseToBase</a></li><li><a href="global.html#CB_baseToInt">CB_baseToInt</a></li><li><a href="global.html#CB_br2nl">CB_br2nl</a></li><li><a href="global.html#CB_brToNl">CB_brToNl</a></li><li><a href="global.html#CB_combineArraysOrObjects">CB_combineArraysOrObjects</a></li><li><a href="global.html#CB_combineAutomatically">CB_combineAutomatically</a></li><li><a href="global.html#CB_combineJSON">CB_combineJSON</a></li><li><a href="global.html#CB_combineURIParameters">CB_combineURIParameters</a></li><li><a href="global.html#CB_combineURLParameters">CB_combineURLParameters</a></li><li><a href="global.html#CB_console">CB_console</a></li><li><a href="global.html#CB_copyObject">CB_copyObject</a></li><li><a href="global.html#CB_countDecimalDigits">CB_countDecimalDigits</a></li><li><a href="global.html#CB_countDecimalPart">CB_countDecimalPart</a></li><li><a href="global.html#CB_countDecimals">CB_countDecimals</a></li><li><a href="global.html#CB_countIntegerDigits">CB_countIntegerDigits</a></li><li><a href="global.html#CB_countIntegerPart">CB_countIntegerPart</a></li><li><a href="global.html#CB_credits">CB_credits</a></li><li><a href="global.html#CB_forEach">CB_forEach</a></li><li><a href="global.html#CB_forceString">CB_forceString</a></li><li><a href="global.html#CB_getBase64StringObject">CB_getBase64StringObject</a></li><li><a href="global.html#CB_getCookie">CB_getCookie</a></li><li><a href="global.html#CB_getDatum">CB_getDatum</a></li><li><a href="global.html#CB_getJSONPropertyValue">CB_getJSONPropertyValue</a></li><li><a href="global.html#CB_getLZStringObject">CB_getLZStringObject</a></li><li><a href="global.html#CB_getValueIndex">CB_getValueIndex</a></li><li><a href="global.html#CB_getValuePath">CB_getValuePath</a></li><li><a href="global.html#CB_includeJSFile">CB_includeJSFile</a></li><li><a href="global.html#CB_indexOf">CB_indexOf</a></li><li><a href="global.html#CB_init">CB_init</a></li><li><a href="global.html#CB_intToBase">CB_intToBase</a></li><li><a href="global.html#CB_isArray">CB_isArray</a></li><li><a href="global.html#CB_isEmail">CB_isEmail</a></li><li><a href="global.html#CB_isFileLocal">CB_isFileLocal</a></li><li><a href="global.html#CB_isString">CB_isString</a></li><li><a href="global.html#CB_lastIndexOf">CB_lastIndexOf</a></li><li><a href="global.html#CB_ltrim">CB_ltrim</a></li><li><a href="global.html#CB_nl2br">CB_nl2br</a></li><li><a href="global.html#CB_nlToBr">CB_nlToBr</a></li><li><a href="global.html#CB_numberFormat">CB_numberFormat</a></li><li><a href="global.html#CB_numberOfDecimalDigits">CB_numberOfDecimalDigits</a></li><li><a href="global.html#CB_numberOfDecimals">CB_numberOfDecimals</a></li><li><a href="global.html#CB_numberOfIntegerDigits">CB_numberOfIntegerDigits</a></li><li><a href="global.html#CB_parseJSON">CB_parseJSON</a></li><li><a href="global.html#CB_parseString">CB_parseString</a></li><li><a href="global.html#CB_regularExpressionString">CB_regularExpressionString</a></li><li><a href="global.html#CB_renderString">CB_renderString</a></li><li><a href="global.html#CB_replaceAll">CB_replaceAll</a></li><li><a href="global.html#CB_rtrim">CB_rtrim</a></li><li><a href="global.html#CB_scriptPath">CB_scriptPath</a></li><li><a href="global.html#CB_scriptPathCalculate">CB_scriptPathCalculate</a></li><li><a href="global.html#CB_setCookie">CB_setCookie</a></li><li><a href="global.html#CB_setDatum">CB_setDatum</a></li><li><a href="global.html#CB_sizeOf">CB_sizeOf</a></li><li><a href="global.html#CB_sizeof">CB_sizeof</a></li><li><a href="global.html#CB_stringifyJSON">CB_stringifyJSON</a></li><li><a href="global.html#CB_symmetricCall">CB_symmetricCall</a></li><li><a href="global.html#CB_symmetricCallClear">CB_symmetricCallClear</a></li><li><a href="global.html#CB_this">CB_this</a></li><li><a href="global.html#CB_trim">CB_trim</a></li> </ul> </li> </ul> <div class="col-sm-3 col-md-3"> <form class="navbar-form" role="search"> <div class="input-group"> <input type="text" class="form-control" placeholder="Search" name="q" id="search-input"> <div class="input-group-btn"> <button class="btn btn-default" id="search-submit"><i class="glyphicon glyphicon-search"></i></button> </div> </div> </form> </div> </div> </div> </div> <div class="container" id="toc-content" style="width:100%;"> <div class="row" style="width:100%;"> <div class="col-md-12"> <div id="main"> <h1 class="page-title">Source: CrossBase/general/CB_Elements.js</h1> <section> <article> <pre class="sunlight-highlight-javascript linenums">/** * @file DOM elements management. Contains the {@link CB_Elements} static class. * @author Joan Alba Maldonado &lt;workindalian@gmail.com> * @license Creative Commons Attribution 4.0 International. See more at {@link https://crossbrowdy.com/about#what_is_the_crossbrowdy_copyright_and_license}. */ /** * Static class to manage DOM elements. It will return itself if it is tried to be instantiated. * @namespace * @todo Think about creating a function called "add" or "create" to create a new element (it could accept "tagName", "id" and "content" parameters). * @todo Think about creating "setStyle" and "setStyleById" methods to add a given style attribute and also supporting a boolean parameter to also add the style attribute with vendor prefixes (webkit, moz, ms, o, khtml) if we want to. */ var CB_Elements = function() { return CB_Elements; }; { CB_Elements.initialized = false; //It will tells whether the object has been initialized or not. //Initializes all values: CB_Elements.init = function() { //If this is the fist time: if (CB_Elements.initialized) { return CB_Elements; } //The object has been initialized: CB_Elements.initialized = true; //TODO. if (!document.body) { var tagBody = CB_Elements.tag("body", document); if (typeof(tagBody) !== "undefined" &amp;&amp; tagBody !== null &amp;&amp; typeof(tagBody[0]) !== "undefined" &amp;&amp; tagBody[0] !== null) { document.body = tagBody[0]; } } return CB_Elements; } CB_Elements._tagCache = {}; /** * Returns elements by their tag name. * @function * @param {string} [tagName='*'] - The name of the tag whose elements we want to find. Use asterisk ("*") in the case that we want all the elements. * @param {Node} [baseElement=document] - The node element parent where we want to focus our search. * @param {boolean} [useCache={@link CB_Configuration.CrossBase.CB_Elements_tag_USE_CACHE}] - Defines whether to try to get the result from an internal cache (it will exist if we previously called the function with the same parameters) or not. The internal cache will be updated when this parameter is set to false or it will be created automatically when it did not exist before. * @returns {NodeList|array} Returns the elements (NodeList or array, depending on the web client). */ CB_Elements.tag = function(tagName, baseElement, useCache) { if (typeof(baseElement) === "undefined" || baseElement === null) { baseElement = document; } //Uses document as default base element. if (typeof(useCache) === "undefined" || useCache === null) { useCache = CB_Configuration[CB_BASE_NAME].CB_Elements_tag_USE_CACHE; } //If no tag name is sent, uses "*" (all) by default: tagName = CB_trim(tagName).toLowerCase(); if (tagName === "") { tagName = "*"; } if (!useCache || typeof(CB_Elements._tagCache[baseElement]) === "undefined" || CB_Elements._tagCache[baseElement] === null || typeof(CB_Elements._tagCache[baseElement][tagName]) === "undefined" || CB_Elements._tagCache[baseElement][tagName] === null) { if (typeof(CB_Elements._tagCache[baseElement]) === "undefined" || CB_Elements._tagCache[baseElement] === null) { CB_Elements._tagCache[baseElement] = {}; } if (typeof(baseElement.getElementsByTagName) !== "undefined" &amp;&amp; baseElement.getElementsByTagName !== null) { CB_Elements._tagCache[baseElement][tagName] = baseElement.getElementsByTagName(tagName); if (tagName === "*" &amp;&amp; CB_Elements._tagCache[baseElement][tagName].length === 0 &amp;&amp; typeof(document.all) !== "undefined" &amp;&amp; document.all !== null) { CB_Elements._tagCache[baseElement][tagName] = document.all; } } else if (baseElement.querySelectorAll) { CB_Elements._tagCache[baseElement][tagName] = baseElement.querySelectorAll(tagName); } else if (document.querySelectorAll) { CB_Elements._tagCache[baseElement][tagName] = document.querySelectorAll(tagName); } else if (typeof(baseElement.all) !== "undefined" &amp;&amp; baseElement.all !== null) { if (tagName === "*") { CB_Elements._tagCache[baseElement][tagName] = baseElement.all; } else { CB_Elements._tagCache[baseElement][tagName] = baseElement.all.tags(tagName); } } else if (typeof(document.all) !== "undefined" &amp;&amp; document.all !== null) { if (tagName === "*") { CB_Elements._tagCache[baseElement][tagName] = document.all; } else { CB_Elements._tagCache[baseElement][tagName] = document.all.tags(tagName); } } else if (baseElement.layers || document.layers) { if (typeof(CB_Elements._tagCache[baseElement][tagName]) === "undefined" || CB_Elements._tagCache[baseElement][tagName] === null) { CB_Elements._tagCache[baseElement][tagName] = []; } var allElements = baseElement.layers || document.layers; //If we want all elements, then we get all of them: if (tagName === "*") { CB_Elements._tagCache[baseElement][tagName] = allElements; } //...otherwise, obtains all elements with the given tag name: else { //If any elements were obtained, we select just the ones with the desired tag name: var allElementsLength = allElements.length; var elementCurrent; for (var x = 0; x &lt; allElementsLength; x++) { elementCurrent = allElements[x]; if (elementCurrent !== null &amp;&amp; typeof(elementCurrent.tagName) !== "undefined") { if (CB_trim(elementCurrent.tagName).toLowerCase() === tagName) { CB_Elements._tagCache[baseElement][tagName].push(elementCurrent); } } } //CB_Elements._tagCache[baseElement][tagName] = baseElement.layers[tagName]; } } else if (typeof(CB_Elements._tagCache[baseElement][tagName]) === "undefined" || CB_Elements._tagCache[baseElement][tagName] === null) { CB_Elements._tagCache[baseElement][tagName] = []; } /* else if (baseElement.layers) { CB_Elements._tagCache[baseElement][tagName] = baseElement.layers[tagName]; } else if (document.layers) { CB_Elements._tagCache[baseElement][tagName] = document.layers[tagName]; }*/ //If we used "*" and there is no elements, we try to use document.all instead (for old web clients): //if (tagName === "*" &amp;&amp; CB_Elements._tagCache[baseElement][tagName].length === 0) //{ //if (all in document) { CB_Elements._tagCache[baseElement][tagName] = document.all; } //} CB_Elements._tagCache[baseElement][tagName] = CB_Elements._tagCache[baseElement][tagName] || []; } return CB_Elements._tagCache[baseElement][tagName]; } /** * Returns elements by their tag name, updating (or creating) the internal cache. Calls the {@link CB_Elements.tag} function internally, with the "useCache" parameter set to false. * @function * @param {string} [tagName='*'] - The name of the tag whose elements we want to find. Use asterisk ("*") in the case that we want all the elements. * @param {Node} [baseElement=document] - The node element parent where we want to focus our search. * @returns {NodeList|array} Returns the elements (NodeList or array, depending on the web client). */ CB_Elements.tagCacheUpdate = function(tagName, baseElement) { return CB_Elements.tag(tagName, baseElement, false); } /** * Clears the internal cache user by {@link CB_Elements.tag} and others. If no parameter is given, whole internal cache will be cleared. * @function * @param {string} [tagName] - The name of the tag whose internal cache we want to clear. Use asterisk ("*") in the case that we want to clear the internal cache for {@link CB_Elements.tag} which is used when it is called with this exact parameter. If not provided, it will clear the whole internal cache or the internal cache that belongs to the "baseElement" given (if provided). * @param {Node} [baseElement] - The node element parent whose internal cache we want to clear. If not provided but "tagName" is provided, it will clear the internal cache which matches the given "tagName" for any nodes. If it is provided but "tagName" is not, it will clear all the internal cache that belongs to this node element. * @returns {Object} Returns the current internal cache after clearing it (if it is has been possible), which is an associative array of two dimensions (JavaScript object) whose first index belongs to the nodes, the second and last index belongs to the tag name and the value belongs to the returning value of the {@link CB_Elements.tag} function when it was called for those parameters. */ CB_Elements.tagCacheClear = function(tagName, baseElement) { tagName = CB_trim(tagName).toLowerCase(); //If no base element and no tag name are defined, we clean all the array: if (typeof(baseElement) === "undefined" &amp;&amp; tagName === "" || baseElement === null &amp;&amp; (typeof(tagName) === "undefined" || tagName === null)) { CB_Elements._tagCache = {}; } //...otherwise, if both base element and tag name are defined, we clear the elements of that base element: else if (typeof(baseElement) !== "undefined" &amp;&amp; baseElement !== null &amp;&amp; tagName !== "") { if (typeof(CB_Elements._tagCache[baseElement]) !== "undefined" &amp;&amp; CB_Elements._tagCache[baseElement] !== null) { if (typeof(CB_Elements._tagCache[baseElement][tagName]) !== "undefined" &amp;&amp; CB_Elements._tagCache[baseElement][tagName] !== null) { CB_Elements._tagCache[baseElement][tagName] = null; } } } //...otherwise, if a base element is defined (but not a tagName), we clear all elements of that base element: else if (typeof(baseElement) !== "undefined" &amp;&amp; baseElement !== null) { if (typeof(CB_Elements._tagCache[baseElement]) !== "undefined" &amp;&amp; CB_Elements._tagCache[baseElement] !== null) { CB_Elements._tagCache[baseElement] = {}; } } //...otherwise, if a tag name is defined (but not a base element), we clear all the elements of that tag name from all the element bases: else if (tagName !== "") { for (var currentBaseElement in CB_Elements._tagCache) { if (typeof(CB_Elements._tagCache[currentBaseElement][tagName]) !== "undefined" &amp;&amp; CB_Elements._tagCache[currentBaseElement][tagName] !== null) { CB_Elements._tagCache[currentBaseElement][tagName] = null; } } } return CB_Elements._tagCache; } /** * Alias for {@link CB_Elements.tagRemove}. * @function CB_Elements.removeByTagName * @see {@link CB_Elements.tagRemove} */ /** * Removes elements by their tag name. * @function * @param {string} [tagName='*'] - The name of the tag whose elements we want to delete. Use asterisk ("*") in the case that we want all the elements. * @param {Node} [baseElement=document] - The node element parent where we want to focus our search. * @param {boolean} [useCache={@link CB_Configuration.CrossBase.CB_Elements_tag_USE_CACHE}] - Defines whether to try to get the result from an internal cache (it will exist if we previously called the function with the same parameters) or not. The internal cache will be updated when this parameter is set to false or it will be created automatically when it did not exist before. */ CB_Elements.tagRemove = CB_Elements.removeByTagName = function(tagName, baseElement, useCache) { if (typeof(baseElement) === "undefined" || baseElement === null) { baseElement = document; } //Uses document as default base element. tagName = CB_trim(tagName); if (tagName === "") { tagName = "*"; } var elementsOriginal = CB_Elements.tag(tagName, baseElement, useCache); if (typeof(elementsOriginal) !== "undefined" &amp;&amp; elementsOriginal !== null &amp;&amp; typeof(elementsOriginal.length) !== "undefined" &amp;&amp; elementsOriginal.length !== null &amp;&amp; elementsOriginal.length > 0) { var elements = []; var elementsLength = elementsOriginal.length; for (var x = 0; x &lt; elementsLength; x++) { elements[x] = elementsOriginal[x]; } elementsLength = elements.length; for (var x = 0; x &lt; elementsLength; x++) { //elements[x].parentNode.removeChild(elements[x]); CB_Elements.remove(elements[x]); } CB_Elements._tagCache[baseElement][tagName] = null; } } CB_Elements._classesCache = {}; /** * Returns elements by their class or classes name. * @function * @param {string} classNames - The name of the class or classes (separated by a blank space) whose elements we want to find. The order of the classes is just important for the internal cache. * @param {Node} [baseElement=document] - The node element parent where we want to focus our search. * @param {boolean} [useCache={@link CB_Configuration.CrossBase.CB_Elements_classes_USE_CACHE}] - Defines whether to try to get the result from an internal cache (it will exist if we previously called the function with the same parameters) or not. The internal cache will be updated when this parameter is set to false or it will be created automatically when it did not exist before. * @returns {NodeList|array} Returns the elements (NodeList or array, depending on the web client). */ CB_Elements.classes = function(classNames, baseElement, useCache) { if (typeof(useCache) === "undefined" || useCache === null) { useCache = CB_Configuration[CB_BASE_NAME].CB_Elements_classes_USE_CACHE; } if (typeof(baseElement) === "undefined" || baseElement === null) { baseElement = document; } //If no class name is sent, returns am empty array: classNames = CB_trim(classNames);//.toLowerCase(); if (classNames === "") { return []; } if (!useCache || typeof(CB_Elements._classesCache[baseElement]) === "undefined" || CB_Elements._classesCache[baseElement] === null || typeof(CB_Elements._classesCache[baseElement][classNames]) === "undefined" || CB_Elements._classesCache[baseElement][classNames] === null) { if (typeof(CB_Elements._classesCache[baseElement]) === "undefined" || CB_Elements._classesCache[baseElement] === null) { CB_Elements._classesCache[baseElement] = {}; } //CB_Elements._classesCache[baseElement][classNames] = baseElement.getElementsByClassName(classNames); if (typeof(baseElement.getElementsByClassName) !== "undefined" &amp;&amp; baseElement.getElementsByClassName !== null) { CB_Elements._classesCache[baseElement][classNames] = baseElement.getElementsByClassName(classNames); } else if (baseElement.querySelectorAll) { CB_Elements._classesCache[baseElement][classNames] = baseElement.querySelectorAll("." + classNames.replace(/ /g, ".")); } else if (document.querySelectorAll) { CB_Elements._classesCache[baseElement][classNames] = document.querySelectorAll("." + classNames.replace(/ /g, ".")); } else { //Obtains all elements: var allElements = CB_Elements.tag("*", baseElement, useCache); //If any elements were obtained, we select just the ones with the desired class name: var allElementsLength = allElements.length; if (allElementsLength > 0) { if (typeof(CB_Elements._classesCache[baseElement][classNames]) === "undefined" || CB_Elements._classesCache[baseElement][classNames] === null) { CB_Elements._classesCache[baseElement][classNames] = []; } /* //classNames = classNames.toLowerCase(); var elementCurrent; var classes; var classesLength; for (var x = 0; x &lt; allElementsLength; x++) { elementCurrent = allElements[x]; if (elementCurrent !== null) { classes = elementCurrent.className.split(" "); classesLength = classes.length; for (var y = 0; y &lt; classesLength; y++) { classes[y] = CB_trim(classes[y]).toLowerCase(); //TODO: make it compatible with regular expressions (be careful with web clients not compatible with RegExp!). if (classes[y] === classNames) { CB_Elements._classesCache[baseElement][classNames].push(elementCurrent); break; } } } } */ //TODO: make it compatible with regular expressions (be careful with web clients not compatible with RegExp!). var classesDesired = classNames.split(" "); var classesDesiredLength = classesDesired.length; for (var x = 0; x &lt; classesDesiredLength; x++) { classesDesired[x] = CB_trim(classesDesired[x]);//.toLowerCase(); } var elementCurrent; var elementCurrentClass; var classes; var classesLength; var y, z; var allClassesFound; for (x = 0; x &lt; allElementsLength; x++) { elementCurrent = allElements[x]; if (elementCurrent !== null) { elementCurrentClass = CB_trim(elementCurrent.className); if (elementCurrentClass === "") { continue; } classes = elementCurrentClass.split(" "); classesLength = classes.length; for (y = 0; y &lt; classesLength; y++) { classes[y] = CB_trim(classes[y]);//.toLowerCase(); } allClassesFound = true; for (z = 0; z &lt; classesDesiredLength; z++) { if (CB_indexOf(classes, classesDesired[z]) === -1) { allClassesFound = false; break; } } if (allClassesFound) { CB_Elements._classesCache[baseElement][classNames].push(elementCurrent); //elements[elements.length] = elementCurrent; } } } } } /* else if (typeof(baseElement.all) !== "undefined" &amp;&amp; baseElement.all !== null) { //allElements = baseElement.all; allElements = CB_Elements.tag("*", baseElement, useCache); } else if (typeof(document.all) !== "undefined" &amp;&amp; document.all !== null) { //allElements = document.all; allElements = CB_Elements.tag("*", document, useCache); } */ /* else if (baseElement.layers) { CB_Elements._classesCache[baseElement][classNames] = baseElement.layers[classNames]; } else if (document.layers) { CB_Elements._classesCache[baseElement][classNames] = document.layers[classNames]; }*/ CB_Elements._classesCache[baseElement][classNames] = CB_Elements._classesCache[baseElement][classNames] || []; } return CB_Elements._classesCache[baseElement][classNames]; } /** * Returns elements by their class or classes name, updating (or creating) the internal cache. Calls the {@link CB_Elements.classes} function internally, with the "useCache" parameter set to false. * @function * @param {string} classNames - The name of the class or classes (separated by a blank space) whose elements we want to find. The order of the classes is just important for the internal cache. * @param {Node} [baseElement=document] - The node element parent where we want to focus our search. * @returns {NodeList|array} Returns the elements (NodeList or array, depending on the web client). */ CB_Elements.classesCacheUpdate = function(classNames, baseElement) { return CB_Elements.classes(classNames, baseElement, false); } /** * Clears the internal cache used by {@link CB_Elements.classes} and others. If no parameter is given, whole internal cache will be cleared. * @function * @param {string} [classNames] - The name of the class or classes (separated by a blank space) whose internal cache we want to clear. The order of the classes is important for the internal cache. If not provided, it will clear the whole internal cache or the internal cache that belongs to the "baseElement" given (if provided). * @param {Node} [baseElement] - The node element parent whose internal cache we want to clear. If not provided but "classNames" is provided, it will clear the internal cache which matches the given "classNames" for any nodes. If it is provided but "classNames" is not, it will clear all the internal cache that belongs to this node element. * @returns {Object} Returns the current internal cache after cleaning it (if it is has been possible), which is an associative array of two dimensions (JavaScript object) whose first index belongs to the nodes, the second and last index belongs to the class name or class names and the value belongs to the returning value of the {@link CB_Elements.classes} function when it was called for those parameters. */ CB_Elements.classesCacheClear = function(classNames, baseElement) { classNames = CB_trim(classNames);//.toLowerCase(); //If no base element and no class name are defined, we clean all the array: if (typeof(baseElement) === "undefined" &amp;&amp; classNames === "" || baseElement === null &amp;&amp; (typeof(classNames) === "undefined" || classNames === null)) { CB_Elements._classesCache = {}; } //...otherwise, if both base element and class name are defined, we clear the elements of that base element: else if (typeof(baseElement) !== "undefined" &amp;&amp; baseElement !== null &amp;&amp; classNames !== "") { if (typeof(CB_Elements._classesCache[baseElement]) !== "undefined" &amp;&amp; CB_Elements._classesCache[baseElement] !== null) { if (typeof(CB_Elements._classesCache[baseElement][classNames]) !== "undefined" &amp;&amp; CB_Elements._classesCache[baseElement][classNames] !== null) { CB_Elements._classesCache[baseElement][classNames] = null; } } } //...otherwise, if a base element is defined (but not a classNames), we clear all elements of that base element: else if (typeof(baseElement) !== "undefined" &amp;&amp; baseElement !== null) { if (typeof(CB_Elements._classesCache[baseElement]) !== "undefined" &amp;&amp; CB_Elements._classesCache[baseElement] !== null) { CB_Elements._classesCache[baseElement] = {}; } } //...otherwise, if a class name is defined (but not a base element), we clear all the elements of that class name from all the element bases: else if (classNames !== "") { for (var currentBaseElement in CB_Elements._classesCache) { if (typeof(CB_Elements._classesCache[currentBaseElement][classNames]) !== "undefined" &amp;&amp; CB_Elements._classesCache[currentBaseElement][classNames] !== null) { CB_Elements._classesCache[currentBaseElement][classNames] = null; } } } return CB_Elements._classesCache; } /** * Alias for {@link CB_Elements.classesRemove}. * @function CB_Elements.removeByClasses * @see {@link CB_Elements.classesRemove} */ /** * Removes elements by their class or classes name. * @function * @param {string} classNames - The name of the class or classes (separated by a blank space) whose elements we want to delete. The order of the classes is just important for the internal cache. * @param {Node} [baseElement=document] - The node element parent where we want to focus our search. * @param {boolean} [useCache={@link CB_Configuration.CrossBase.CB_Elements_classes_USE_CACHE}] - Defines whether to try to get the result from an internal cache (it will exist if we previously called the function with the same parameters) or not. The internal cache will be updated when this parameter is set to false or it will be created automatically when it did not exist before. */ CB_Elements.classesRemove = CB_Elements.removeByClasses = function(classNames, baseElement, useCache) { if (typeof(baseElement) === "undefined" || baseElement === null) { baseElement = document; } classNames = CB_trim(classNames);//.toLowerCase(); if (classNames === "") { return; } var elementsOriginal = CB_Elements.classes(classNames, baseElement, useCache); if (typeof(elementsOriginal) !== "undefined" &amp;&amp; elementsOriginal !== null &amp;&amp; typeof(elementsOriginal.length) !== "undefined" &amp;&amp; elementsOriginal.length !== null &amp;&amp; elementsOriginal.length > 0) { var elements = []; var elementsLength = elementsOriginal.length; for (var x = 0; x &lt; elementsLength; x++) { elements[x] = elementsOriginal[x]; } var elementsLength = elements.length; for (var x = 0; x &lt; elementsLength; x++) { //elements[x].parentNode.removeChild(elements[x]); CB_Elements.remove(elements[x]); } CB_Elements._classesCache[baseElement][classNames] = null; } } CB_Elements._idCache = {}; /** * Alias for {@link CB_Elements.id}. * @function CB_Elements.byId * @see {@link CB_Elements.id} */ /** * Alias for {@link CB_Elements.id}. * @function CB_Elements.get * @see {@link CB_Elements.id} */ /** * Alias for {@link CB_Elements.id}. * @function CB_Elements.getById * @see {@link CB_Elements.id} */ /** * Returns an element by its ID. * @function * @param {string} id - The identifier of the element that we want to find. * @param {boolean} [useCache={@link CB_Configuration.CrossBase.CB_Elements_id_USE_CACHE}] - Defines whether to try to get the result from an internal cache (it will exist if we previously called the function with the same parameters) or not. The internal cache will be updated when this parameter is set to false or it will be created automatically when it did not exist before. * @returns {Node|Object|null} Returns the elements (Node or object, depending on the web client). It will return null when not found. */ CB_Elements.id = CB_Elements.byId = CB_Elements.get = CB_Elements.getById = function(id, useCache) { if (typeof(useCache) === "undefined" || useCache === null) { useCache = CB_Configuration[CB_BASE_NAME].CB_Elements_id_USE_CACHE; } id = CB_trim(id);//.toLowerCase(); //If no id is sent, returns null: if (id === "") { return null; } if (!useCache || typeof(CB_Elements._idCache[id]) === "undefined" || CB_Elements._idCache[id] === null) { if (document.getElementById) { CB_Elements._idCache[id] = document.getElementById(id); } else if (document.querySelector) { CB_Elements._idCache[id] = document.querySelector("#" + id); } else if (document.all) { if (typeof(document.all) !== "function") { CB_Elements._idCache[id] = document.all[id]; } else { CB_Elements._idCache[id] = document.all(id); } } else if (document.layers) { CB_Elements._idCache[id] = document.layers[id]; } else { CB_Elements._idCache[id] = null; } CB_Elements._idCache[id] = CB_Elements._idCache[id] || null; } return CB_Elements._idCache[id]; } /** * Returns an element by its ID, updating (or creating) the internal cache. Calls the {@link CB_Elements.id} function internally, with the "useCache" parameter set to false. * @function * @param {string} id - The identifier of the element that we want to find. * @returns {node|Object|null} Returns the elements (Node or object, depending on the web client). It will return null when not found. */ CB_Elements.idCacheUpdate = function(id) { return CB_Elements.id(id, false); } /** * Clears the internal cache used by {@link CB_Elements.id} and others. If no parameter is given, whole internal cache will be cleared. * @function * @param {string} [id] - The identifier of the element whose internal cache we want to clear. If not provided, it will clear the whole internal cache. * @returns {Object} Returns the current internal cache after cleaning it (if it is has been possible), which is an associative array of one dimension (JavaScript object) whose first and unique index belongs to the identifier and the value belongs to each element. */ CB_Elements.idCacheClear = function(id) { id = CB_trim(id); if (id === "") { CB_Elements._idCache = {}; } else { CB_Elements._idCache[id] = null; } return CB_Elements._idCache; } /** * Alias for {@link CB_Elements.idRemove}. * @function CB_Elements.removeById * @see {@link CB_Elements.idRemove} */ /** * Removes an element by its ID. * @function * @param {string} id - The identifier of the element that we want to delete. * @param {boolean} [useCache={@link CB_Configuration.CrossBase.CB_Elements_id_USE_CACHE}] - Defines whether to try to get the result from an internal cache (it will exist if we previously called the function with the same parameters) or not. The internal cache will be updated when this parameter is set to false or it will be created automatically when it did not exist before. */ CB_Elements.idRemove = CB_Elements.removeById = function(id, useCache) { id = CB_trim(id); if (id === "") { return; } var element = CB_Elements.id(id, useCache); //if (typeof(CB_Elements._idCache[id]) !== "undefined" &amp;&amp; CB_Elements._idCache[id] !== null) //{ CB_Elements._idCache[id] = null; //} return CB_Elements.remove(element); } /** * Removes an element given. * @function * @param {Node} element - The element that we want to delete. */ CB_Elements.remove = function(element) { if (typeof(element) !== "undefined" &amp;&amp; element !== null) { var elementParent = CB_Elements.getParent(element); if (typeof(elementParent) !== "undefined" &amp;&amp; elementParent !== null &amp;&amp; typeof(elementParent.removeChild) !== "undefined" &amp;&amp; elementParent.removeChild !== null) { ///////return elementParent.removeChild(element); elementParent.removeChild(element); } else if (typeof(element.removeNode) !== "undefined" &amp;&amp; element.removeNode !== null) { ///////return element.removeNode(true); element.removeNode(true); } else if (document.all) { if (typeof(document.all) !== "function" &amp;&amp; element.id &amp;&amp; typeof(document.all[element.id]) !== "undefined" &amp;&amp; document.all[element.id] !== null) { document.all[element.id].innerHTML = document.all[element.id].outerHTML = ""; } else if (element.id) { //Uses try-catch because otherwise it fails on IE 8: try { document.all(element.id).innerHTML = document.all(element.id).outerHTML = ""; } catch(E) {} } } else if (document.layers &amp;&amp; element.id) { document.layers[element.id].visibility = "hide"; delete document.layers[element.id]; } if (typeof(element.remove) !== "undefined") { element.remove(); } ///////////////delete(element); //Just in case (for some strange web clients). NOTE: commented since it gives problems with JSDoc ("ERROR: Unable to parse CB_Elements.js: Deleting local variable in strict mode"). element = null; element = undefined; } } /** * Returns an array with the parents of a given element, with the topmost parent in the highest index: * @function * @param {Node} element - The element whose parents we want to get. * @returns {array} */ CB_Elements.getParents = function(element) { var elementParents = []; var x = 0; var currentParent; while (currentParent = CB_Elements.getParent(element)) { elementParents[x++] = currentParent; element = currentParent; } return elementParents; } /** * Returns an array with the parents of a given element (by its identifier), with the topmost parent in the highest index: * @function * @param {string} elementId - The identifier of the element whose parents we want to get. * @returns {array} */ CB_Elements.getParentsById = function(elementId) { return CB_Elements.getParents(CB_Elements.id(elementId)); } /** * Returns the first parent of a given element: * @function * @param {Node} element - The element whose parent we want to get. * @returns {Node|null} Returns null if the parent cannot be found. */ CB_Elements.getParent = function(element) { if (typeof(element) === "undefined" || element === null) { return null; } var elementParent = null; if (typeof(element.parentNode) !== "undefined" &amp;&amp; element.parentNode !== null) { elementParent = element.parentNode; } else if (typeof(element.parentElement) !== "undefined" &amp;&amp; element.parentElement !== null) { elementParent = element.parentElement; } return elementParent; } /** * Returns the first parent of a given element (by its identifier): * @function * @param {string} elementId - The identifier of the element whose parent we want to get. * @returns {Node|null} Returns null if the parent cannot be found. */ CB_Elements.getParentById = function(elementId) { return CB_Elements.getParent(CB_Elements.id(elementId)); } /** * Changes a desired element property with the given value. * @function * @param {Node} element - The element whose property we want to modify. * @param {string} property - The name of the property that we want to modify. * @param {*} propertyValue - The value desired for the property. * @param {boolean} [checkValues=false] - If set to true, it will only modify the property if the current value is different from the given one. * @param {function} [onSetProperty] - Callback function that will be called if the property of the element has been set, after doing it (this will happens always if "checkValues" is false). The first and unique parameter passed will be the affected element itself. * @returns {Node|null} Returns the given element again or null. */ CB_Elements.setProperty = function(element, property, propertyValue, checkValues, onSetProperty) { if (typeof(element) === "undefined" || element === null) { return null; } if (!checkValues || element[property] !== propertyValue) { element[property] = propertyValue; if (typeof(onSetProperty) === "function") { onSetProperty(element); } } return element; } /** * Changes a desired element property with the given value (by its identifier). * @function * @param {string} elementId - The identifier of the element whose property we want to modify. * @param {string} property - The name of the property that we want to modify. * @param {*} propertyValue - The value desired for the property. * @param {boolean} [checkValues=false] - If set to true, it will only modify the property if the current value is different from the given one. * @param {function} [onSetProperty] - Callback function that will be called if the property of the element has been set, after doing it (this will happens always if "checkValues" is false). The first and unique parameter passed will be the affected element itself. * @returns {Node|null} Returns the affected element (if any) or null otherwise. */ CB_Elements.setPropertyById = function(elementId, property, propertyValue, checkValues, onSetProperty) { return CB_Elements.setProperty(CB_Elements.id(elementId), property, propertyValue, checkValues, onSetProperty); } /** * Inserts the desired content inside a given element (using [innerHTML]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML}). * @function * @param {Node} container - The element whose content we want to modify. * @param {string} content - The content that we want to add. * @param {string} [displayValue] - If provided, it will call {@link CB_Elements.show} internally after inserting the content to set the given [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property to the element. * @param {boolean} [checkValues=false] - If it is set to true, it will only change the content if the current one is different from the given one and it will pass the same parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given). * @param {boolean} [computed=false] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given). * @param {function} [onContentWritten] - Callback function that will be called if the content has been written, after doing it (this will happens always if "checkValues" is false). The unique parameter passed will be the container itself. * @param {function} [onShow] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} when it is called internally. * @param {boolean} [append=false] - If set to true, it will append the given content to the existing one instead of overwritten it. By default, it appends it at the end unless that the "appendAtBeginning" is set to true. * @param {boolean} [appendAtBeginning=false] - If set to true, it will append the given content to the existing one instead of overwritten it. * @returns {Node} Returns the given container again. */ CB_Elements.insertContent = function(container, content, displayValue, checkValues, computed, onContentWritten, onShow, append, appendAtBeginning) { if (container !== null) { if (!checkValues || append || container.innerHTML !== content) { if (append) { container.innerHTML = appendAtBeginning ? content + container.innerHTML : container.innerHTML + content; } else { container.innerHTML = content; } if (typeof(onContentWritten) === "function") { onContentWritten(container); } } if (displayValue) { CB_Elements.show(container, displayValue, checkValues, computed, onShow); } } return container; } /** * Appends the desired content inside a given element, keeping the existing one (using [innerHTML]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML}). Calls the {@link CB_Elements.insertContent} internally. * @function * @param {Node} container - The element whose content we want to modify. * @param {string} content - The content that we want to add. * @param {string} [displayValue] - If provided, it will call {@link CB_Elements.show} internally after inserting the content to set the given [display]{@link https://developer.mozilla.org/en-US/docs/Web/CSS/display} property to the element. * @param {boolean} [checkValues=false] - If it is set to true, it will only change the content if the current one is different from the given one and it will pass the same parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given). * @param {boolean} [computed=false] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} if it is called internally (when "displayValue" is given). * @param {function} [onContentWritten] - Callback function that will be called if the content has been written, after doing it (this will happens always if "checkValues" is false). The unique parameter passed will be the container itself. * @param {function} [onShow] - If "displayValue" is given, it will pass this parameter to {@link CB_Elements.show} when it is called internally. * @param {boolean} [appendAtBeginning=false] - If set to true, it will append the given content to the existing one instead of overwritten it. * @returns {Node} Returns the given container again. */ CB_Elements.appendContent = function(container, content, displayValue, checkValues, computed, onContentWritten, onShow, appendAtBeginning) { return CB_Elements.insertContent(container, content, displayValue, checkValues, computed, onContentWritten, onShow, true, appendAtBeginning); }