Displaying all icons in a glyph - javascript
I'm writing a widget UI where the user can manipulate widgets and text. One of the UI functions needed is to select an icon from the list of icons in a glyph and as I'm using twitter bootstrap it should be possible to select the "icon-" classes in the CSS in JavaScript then display them in a DIV. However I'm still relatively new to web development so unsure how I can loop through all the CSS classes selecting all the "icon-" classes. I can see how to do that with a selector to search the HTML body, for example with $.find("[class^='icon-']"); but I'm not sure how to do similar to search the CSS file itself and extract a list of CSS icon classes.
Thanks for any pointers.
Something like this should work if your browser implements the CSSStyleSheet interface:
var icons = [];
var cssRules = document.styleSheets[0].cssRules; // your bootstrap.css
for (var i=0; i<cssRules.length; i++) {
var selectorText = cssRules[i].selectorText;
if (selectorText && selectorText.match(/^\.icon-[a-z_-]+$/)) {
icons.push(selectorText);
}
}
http://jsfiddle.net/V2wjX/
The best approach I can think of is creating an array of the possible values, then looping through them. Here, I made it for you: (from this page)
var icons = ["glass","music","search","envelope","heart","star","star-empty","user","film","th-large","th","th-list","ok","remove","zoom-in","zoom-out","off","signal","cog","trash","home","file","time","road","download-alt","download","upload","inbox","play-circle","repeat","refresh","list-alt","lock","flag","headphones","volume-off","volume-down","volume-up","qrcode","barcode","tag","tags","book","bookmark","print","camera","font","bold","italic","text-height","text-width","align-left","align-center","align-right","align-justify","list","indent-left","indent-right","facetime-video","picture","pencil","map-marker","adjust","tint","edit","share","check","move","step-backward","fast-backward","backward","play","pause","stop","forward","fast-forward","step-forward","eject","chevron-left","chevron-right","plus-sign","minus-sign","remove-sign","ok-sign","question-sign","info-sign","screenshot","remove-circle","ok-circle","ban-circle","arrow-left","arrow-right","arrow-up","arrow-down","share-alt","resize-full","resize-small","plus","minus","asterisk","exclamation-sign","gift","leaf","fire","eye-open","eye-close","warning-sign","plane","calendar","random","comment","magnet","chevron-up","chevron-down","retweet","shopping-cart","folder-close","folder-open","resize-vertical","resize-horizontal","hdd","bullhorn","bell","certificate","thumbs-up","thumbs-down","hand-right","hand-left","hand-up","hand-down","circle-arrow-right","circle-arrow-left","circle-arrow-up","circle-arrow-down","globe","wrench","tasks","filter","briefcase","fullscreen"]
Now you can loop through this array, and create the elements as needed.
for (var i=0,l=icons.length; i<l; i++){
var el = document.createElement('i');
el.className = 'icon-'+icons[i];
document.getElementById("iconContainer").appendChild(el);
}
JSFIDDLE
As for searching the CSS, I can suggest you to write a function like this:
You somehow get the contents of a CSS file into a string, using AJAX (jqXHR) possibly.
Then, write a very basic parsing script, which accepts the CSS string as the parameter.
function getIcons(cssStr){
var matches = cssStr.match(/\.icon\-\w*.*\{/g), icons = [];
for (var i=0,l=matches.length; i<l; i++) icons.push(matches[i].replace(/\.icon\-/g,'').replace(/\W/g,''));
return icons;
}
This will give you the array shown before.
JSFIDDLE
Related
What is a safe alternative to .innerHTML and Jquery .append?
Firefox addon got removed because of unsafe assignment to innerHTML. Replaced it with the Jquery append(), but it is also unsafe. What can I use instead? I need to add content dynamically to the extension's DOM. Mozilla gave me this link when they took down the addon: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Safely_inserting_external_content_into_a_page But I can not figure out from the link how to add nodes to an existing node in a safe way. This is an example of what i'm doing now. I have several places where I append a node to another node. In this case I need to make a div for every category and add it to the node "folders" var folders = $("#folders"); for (var i = 0; i < categories.length; i++) { var s = categories[i]; var categoryFolder = $("<div>"); categoryFolder.addClass("folder"); categoryFolder.attr("id",s); categoryFolder.text(s); folders.append(categoryFolder); }
Material Components Web - mdc attachTo only apply to the first element
I'm using Material Components Web to create a website. I have a list of button with the class .mdc-button and I activated it with the following line into my Javascript File. window.button = new mdc.ripple.MDCRipple.attachTo(document.querySelector('.mdc-button')); The problem is that this only applies to the first element with the class .mdc-button Why is that and how to fix it?
document.querySelector will always return the first instance of the element found within the DOM. You can use document.getElementsByClassName('mdc-button') to return a full list of classes within the DOM. https://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp Perhaps something like this var x = document.getElementsByClassName('mdc-button'); var i; for (i = 0; i < x.length; i++) { mdc.ripple.MDCRipple.attachTo(x[i]); }
Here is an ES6 way of doing the same thing (for anyone else reading this post): const buttons = document.querySelectorAll('.mdc-button'); buttons.forEach(button => MDCRipple.attachTo(button));
Using 'vanilla' JS to set CSS property on selected elements
JavaScript Newbie so the following question maybe 'dumb'. For my work I do a little GreaseMonkey scripting to make our eCommerce store back end a little more friendly to our customer service team. Normally I'd make a new or better UI for them setup a special role or something, but with this current system, this is literally not an option. Specifically I make a selection of links visibility: hidden, as they trigger some reporting functions which can lock up the backend till the reports are completed. Up to this point I have had the script load jQuery, which is fine but not ideal. Then I dug in and saw that the interface was built using YUI, while this is already loaded, the syntax is weird to me, and I don't like it much, plus it is now not supported. Recently I found the Plain JS site, which describes how to use 'vanilla' JS to do jQuery like things. Splendid! I thought, Now I can just write simple JS without extra dependencies or libs! But this is not quite the case. I have tried the following: var links = Array.from(document.querySelectorAll("a")); // creates an actual array from the node list returned by document.query var links_to_hide = links.slice(14, 22); // gets just the bits we want to affect from the array, and is still an array // ok so 'links_to_hide' is an array, and it is an array of 'a' anchor tags. // if I go into the inspector and set the visibility property it affects the tag but doing it via scripting seems to not work. // so if links_to_hide is an array it should be possible to for(var i = links_to_hide.length; i <= links_to_hide.length; i++){ links_to_hide.style['visibility'] = 'hidden'; } // this for loop doesn't seem to actually affect anything What am I missing. Near as I can tell this should work.
Change this: for(var i = links_to_hide.length; i <= links_to_hide.length; i++){ links_to_hide.style['visibility'] = 'hidden'; } To this for(var i = 0; i < links_to_hide.length; i++){ links_to_hide[i].style['visibility'] = 'hidden'; }
You aren't using i links_to_hide[i].style.visibility = 'hidden';
Your for loop should be like below: for(var i = 0; i < links_to_hide.length; i++){ links_to_hide[i].style.visibility = 'hidden'; }
How to change CSS file using JavaScript?
I would ask how to change src of CSS using pure Javascript. I saw on internet that one guy used cookies for this, by i tried sth like this: window.onload = function onload() { setTimeout(function(){ document.styleSheets[1].href = "file:///C:/Users/Ma%C5%9Blan/Desktop/Site/bootstrap-3.3.6-dist/project1a.css"; }, 3000); }; And it didn't work (i want to change CSS after 3 s, i know that actual localization is local, on my PC. Just trying :) ). I want to swap whole file. Any ideas? If it's impossible in pure JS, show me jQuery way then. Thanks!
document.styleSheets is a READ-ONLY property, so you won't be able to change the properties of that array. What you want to do instead is get a list of all the <link> elements in the head, then either use a regex or conditional statement to get the element you are looking to replace, and use .href on that element. E.G. // get all links in the head (including CSS) var allLinks = document.head.getElementsByTagName('link'); // find and replace the element for (var i = 0; i < allLinks.length; i++) { if ( allLinks[i].href = "old/url/to/css/file.css") { allLinks[i].href = "file:///C:/Users/Ma%C5%9Blan/Desktop/Site/bootstrap-3.3.6-dist/project1a.css"; } }
Remove items from an HTML collection based on another HTML collection
I'm trying to crete 3 HTML collections containing all my links on a page, so I can attach 3 separate function to each categories of links. My first HTML collection is "header links", the second is "footer links" and the third is "all other links". I need to attach link tracking functions and other elements as well. Creating the first two collections is fairly easy as I can do document.getElementById('header'); and document.getElementById('footer'); and then this.getElementsByTagName('a'); However, getting the third collection of "all other links" is a bit more tricky. There isn't a clean div that contains just the "middle" of the page, and there are links outside the header and footer that are also difficult to single out. I wish I could do something like allLinks = document.linnks, and then filter out of that all the links already present in the first and second HTML collections. Any way to do that ? Ideally I would like to avoid loading more libraries and pure JS would be welcome Thanks !
You can turn the node lists into arrays, then use filter() to pull out links that are already in one of the other lists: var hdr = document.getElementById('header'); var hlinks = arrayOf(hdr.getElementsByTagName('a')); var ftr = document.getElementById('footer'); var flinks = arrayOf(ftr.getElementsByTagName('a')); var others = arrayOf(document.getElementsByTagName('a')). filter( function(element) { return (hlinks.indexOf(element) < 0) && (flinks.indexOf(element) < 0); } ); function arrayOf(nodelist) { var result = []; for ( var i = 0; i < nodelist.length; ++i ) result.push(nodelist.item(i)); return result; } Example: http://codepen.io/paulroub/pen/ikebh If you need to support older browsers that lack Array.prototype.filter(), include the code from this MDN page to implement it when needed.