I would like to know how can I define a bigger variable for a set of variables that I have in javascript: showFootnotesPanel();, showReferencesPanel();, showImagesPanel();, showInformationPanel();.
Would it be something like this?
function showPanel() {
var x = [showFootnotesPanel();showReferencesPanel();showImagesPanel();showInformationPanel();]
}
Update:
I have this function that used to open a side panel on the right side and color the content:
var els = document.getElementsByClassName('change-color'),
target = document.getElementsByClassName('resources'),
changeColor = function(a) {
elements = document.getElementsByClassName("note");
for (var i = 0; i < elements.length; i++) {
console.log(elements[i])
elements[i].style.backgroundColor = "";
}
target = a.getAttribute('href');
element = document.querySelector('[data-id="' + target.substring(1, target.length) + '"]');
element.style.backgroundColor = a.getAttribute('data-color');
};
for (var i = els.length - 1; i >= 0; --i) {
els[i].onclick = function() {
showFootnotesPanel();
changeColor(this);
}
Now I have 4 side panels that need to respond to the same script, and I thought that by defining something like showPanel() is showFootnotesPanel() or showReferencesPanel() or showImagesPanel() or showInformationPanel() I might simplify things, so the last line of the script would be this instead just:
els[i].onclick = function(){showPanel();changeColor(this);}
Update 2:
Or is it possible to do this with the logical operator OR?
els[i].onclick = function(){showFootnotesPanel(); || showReferencesPanel(); || showImagesPanel(); || showInformationPanel();changeColor(this);}
Update 3:
This is the new script that I am using to hide and show the panels:
function showPanel(myPanel) {
var elem = document.getElementById(myPanel);
if (elem.classList) {
console.log("classList supported");
elem.classList.toggle("show");
} else {
var classes = elem.className;
if (classes.indexOf("show") >= 0) {
elem.className = classes.replace("show", "");
} else {
elem.className = classes + " show";
}
console.log(elem.className);
}
}
function hideOthers(one, two, three, four) {
if (one > "") {
var elem1 = document.getElementById(one);
var classes = elem1.className;
elem1.className = classes.replace("show", "");
}
if (two > "") {
var elem2 = document.getElementById(two);
var classes = elem2.className;
elem2.className = classes.replace("show", "");
}
if (three > "") {
var elem3 = document.getElementById(three);
var classes = elem3.className;
elem3.className = classes.replace("show", "");
}
if (four > "") {
var elem4 = document.getElementById(four);
var classes = elem4.className;
elem4.className = classes.replace("show", "");
}
return;
}
And this is the script that calls the panels and highlights the text on them:
var els = document.getElementsByClassName('change-color'),
target = document.getElementsByClassName('resources'),
changeColor = function(a) {
elements = document.getElementsByClassName("note");
for (var i = 0; i < elements.length; i++) {
console.log(elements[i])
elements[i].style.backgroundColor = "";
}
target = a.getAttribute('href');
element = document.querySelector('[data-id="' + target.substring(1, target.length) + '"]');
element.style.backgroundColor = a.getAttribute('data-color');
};
for (var i = els.length - 1; i >= 0; --i) {
els[i].onclick = function() {
hideOthers('footnotes-section', 'references-section', 'images-section', 'information-section');
showPanel('references-section');
changeColor(this);
}
}
Thank you!
Updated with a final solution.
In javascript you can declare variables by this way:
var text = ""; // String variable.
var number = 0; //Numeric variable.
var boolValue = true; //Boolean variable.
var arrayValue = []; // Array variable. This array can contain objects {}.
var obj = {}; // Object variable.
Check this version of your code.
// var text = ""; => String variable.
// var number = 0; => Numeric variable.
// var boolValue = true; => Boolean variable.
// var arrayValue = []; => Array variable. This array can contain objects {}.
// var obj = {}; => Object variable.
// This section of code is only to explain the first question.
(function() {
function showFootnotesPanel() {
return 10; // Random value.
}
function showReferencesPanel() {
return 30; // Random value.
}
function showImagesPanel() {
return 50; // Random value.
}
function showInformationPanel() {
return 90; // Random value.
}
function showPanel() {
return [
showFootnotesPanel(), // Index = 0
showReferencesPanel(), // Index = 1
showImagesPanel(), // Index = 2
showInformationPanel() // Index = 3
];
}
var bigVariable = showPanel(); // bigVariable is array of numeric values.
// Using logical operator to check status of variable about this demo code.
if (bigVariable[0] === 10 || bigVariable[1] === 30) {
console.log("Hey, with these values can show the FootnotesPanel and ReferencesPanel.");
} else {
console.log("With the current values can't show anything...");
}
console.log(bigVariable);
})();
// https://jsfiddle.net/dannyjhonston/t5e8g22b/
// This section of code attempts to answer the question of this post.
(function() {
// This function can be executed when the page is loaded.
function showPanel(panels) {
var panel, panelVisible = "";
var selPanels = document.getElementById("selPanels");
// In panels array...
for (var i = 0; i < panels.length; i++) {
// panels[0] = "ReferencesPanel";
panel = document.getElementById(panels[i]); // Get in the DOM tag context of the panel to set in the variable "panel".
panelVisible = panel.getAttribute("data-visible"); // HTML5 data attribute.
if (panelVisible == "true") {
panel.setAttribute("class", "show");
} else {
panel.setAttribute("class", "hide");
}
}
}
// This function is for set panel visibilty.
function setPanel(panelId, status) {
panel = document.getElementById(panelId);
panel.setAttribute("data-visible", status);
// Calling the showPanel function to check in the DOM.
showPanel(["ReferencesPanel", "InformationPanel", "ImagesPanel", "FootnotesPanel"]);
}
// Binding the change event to the select tag.
selPanels.addEventListener("change", function() {
// Executes setPanel function with panelId and true to update the data-visible attribute in the DOM.
setPanel(this.options[this.selectedIndex].value, "true");
});
// Executes showPanel function with array argument with panels Id. You need to specify every panel that want to handle.
showPanel(["ReferencesPanel", "InformationPanel", "ImagesPanel", "FootnotesPanel"]);
})();
#global {
border: solid 1px #6291AD;
}
.tools {
background-image: linear-gradient(#FFFFFF, #8999CE);
}
#global div[data-visible] {
height: 80px;
padding: 5px 0;
}
#global div p {
padding: 10px;
}
#ReferencesPanel {
background-image: linear-gradient(#FFFFFF, #FD9A9A);
float: left;
width: 20%;
}
#InformationPanel {
background-image: linear-gradient(#FFFFFF, #A1C7F1);
float: left;
width: 80%;
}
#ImagesPanel {
background-image: linear-gradient(#C6E9FB, #FFF);
width: 100%;
}
#FootnotesPanel {
background-image: linear-gradient(#C6E999, #FFF);
width: 100%;
}
.clear {
clear: both;
}
.show {
display: block;
}
.hide {
display: none;
}
<div id="global">
<div class="tools">Show Panel:
<br />
<!-- Demo -->
<select id="selPanels">
<option value="">[SELECT]</option>
<option value="ReferencesPanel">ReferencesPanel</option>
<option value="InformationPanel">InformationPanel</option>
<option value="ImagesPanel">ImagesPanel</option>
<option value="FootnotesPanel">FootnotesPanel</option>
</select>
</div>
<!-- You need to set data-visible attribute with true or false to show or hide a panel. -->
<div id="ReferencesPanel" data-visible="false">
<p>References Panel</p>
</div>
<div id="InformationPanel" data-visible="false">
<p>Information Panel</p>
</div>
<div class="clear"></div>
<div id="ImagesPanel" data-visible="false">
<p>Images Panel</p>
</div>
<div id="FootnotesPanel" data-visible="false">
<p>Foot notes Panel</p>
</div>
</div>
I dont understand your question exactly, but if you want to define a variable that contains other variables then you can use an object.
e.g:
var footNotesPanel = true;
var referencesPanel = true;
var imagesPanel = true;
var showPanels = {
footNotesPanel: footNotesPanel,
referencesPanel: referencesPanel,
imagesPanel: imagesPanel
}
/*
Option 2 - for showing/hiding side panels
1 ) create all your panels as they would appear, with all the data, but hide them with display:none;
2 ) call show panel function to show a panel.
*/
var showPanel(panel_id) {
var panel_element = $("#" + panel_id); /*panel that you want to show ( is hidden atm but somewhere on the page */
if (!panel_element.length) {
return false; //no panel with this id currently on page
} else {
//check the panel id and do some custom editing if needed, eg.
if (panel_id == "main_side_panel") {
//add some additional classes to body element etc
}
panel_element.show();
//Or Another option that you probably are looking for is below
if (panel_id == "footnotes_panel") {
showFootnotesPanel();
} else if (panel_id == "images_panel") {
showImagesPanel();
}
}
}
// And use it like this:
<div id="footnotes_panel" onclick="showPanel('footnotes_panel')"></div>
// Or simply get the element id from `event.target` and use `showPanel()` without arguments.
Related
I am using the following jQuery script from enter link description here
<script>
var calendarObjects = [
{name:"Event Type 1", colour:"#735f9e"},
{name:"Event Type 2", colour:"#0000FF"},
{name:"Event Type 3", colour:"#0066cc"},
{name:"Event Type 4", colour:"#83b53f"},
{name:"Event Type 5", colour:"#ff99cc"} ,
]
</script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript">
LoadSodByKey("SP.UI.ApplicationPages.Calendar.js", function () {
WaitForCalendarToLoad();
});
var SEPARATOR = "|||";
function WaitForCalendarToLoad() {
var _renderGrids = SP.UI.ApplicationPages.SummaryCalendarView.prototype.renderGrids;
SP.UI.ApplicationPages.SummaryCalendarView.prototype.renderGrids = function($p0) {
_renderGrids.call(this, $p0);
ColourCalendar();
}
var _onItemsSucceed = SP.UI.ApplicationPages.CalendarStateHandler.prototype.onItemsSucceed;
SP.UI.ApplicationPages.CalendarStateHandler.prototype.onItemsSucceed = function($p0, $p1) {
_onItemsSucceed.call(this, $p0, $p1);
ColourCalendar();
}
}
function ColourCalendar() {
// Find calendar links (i.e. links that contain the separator |||)
if ($('a:contains(' + SEPARATOR + ')') != null) {
// Loop through calendar links
$('a:contains(' + SEPARATOR + ')').each(function (i) {
// Get the div of the calendar entry
$box = $(this).parents('div[title]');
// Get the category, colour and actual text
var category = GetCategory(this.innerHTML);
if (category != "")
{
var colour = GetColourCodeFromName(category);
var actualText = GetActualText(this.innerHTML);
// Set html of calendar entry
this.innerHTML = actualText;
// Set the title of the div
$($box).attr("title", GetActualText($($box).attr("title")));
// Set class of div to category without spaces
$($box).attr("class", "calendarEvent " + category.replace(/ /g, ""));
// Set the background colour
$box.css('background-color', '#da7b2f');
}
else
{
// Set html of calendar entry
this.innerHTML = GetActualText(this.innerHTML);
// Set class of div to category without spaces
$($box).attr("class", "calendarEvent");
// Set the background colour
$box.css('background-color', '#da7b2f');
}
});
}
// Setup filter links
SetupFilterLinks();
// If filter already selected
var selectedFilter = document.getElementById('hfdSelectedFilter').value;
if (selectedFilter != "") {
FilterCategory(document.getElementById('hfdSelectedFilter').value);
}
}
function GetActualText(originalText) {
var parts = originalText.split(SEPARATOR);
return parts[0] + parts[2];
}
function GetCategory(originalText) {
var parts = originalText.split(SEPARATOR);
return parts[1];
}
function GetColourCodeFromName(name) {
// Iterate calendar objects
for (var i = 0, len = calendarObjects.length; i < len; i++) {
if (calendarObjects[i].name === name)
return calendarObjects[i].colour; // Return as soon as the object is found
}
return "#999999"; // Default to dark grey
}
function FilterCategory(category) {
// Get category with no spaces
var categoryNoSpaces = category.replace(/ /g, "");
// If divs with class "calendarEvent" exist
if ($('div.calendarEvent') != null) {
// Loop through divs
$('div.calendarEvent').each(function (i) {
// Hide divs
this.style.display = "none";
});
}
// If div(s) with category class exist
if ($('div.' + categoryNoSpaces) != null) {
// Loop through divs
$('div.' + categoryNoSpaces).each(function (i) {
// Set display to block
this.style.display = "block";
});
}
// Set hidden field value
document.getElementById('hfdSelectedFilter').value = categoryNoSpaces;
// Expand all days
expandCalCheck();
// Hide collapse links
hideCollapseLinks();
}
function expandCalCheck() {
var a = $("a.ms-cal-nav", $("div.ms-acal-rootdiv:last>div")).get(0);
if (a) {
for (var r = 0; r < 6; r++) {
var a = $("a.ms-cal-nav", $("div.ms-acal-rootdiv:last>div").get(r)).get(0);
if (a)
if (a.innerText.indexOf("more") >= 0) {
a.click();
}
}
}
}
function hideCollapseLinks() {
if ($('a:contains(collapse)') != null) {
// Loop through collapse links
$('a:contains(collapse)').each(function (i) {
this.style.display = "none";
});
}
}
function ShowAllEvents() {
// If divs with class "calendarEvent" exist
if ($('div.calendarEvent') != null) {
// Loop through divs
$('div.calendarEvent').each(function (i) {
// Hide divs
this.style.display = "block";
});
// Set hidden field value
document.getElementById('hfdSelectedFilter').value = "";
}
}
function SetupFilterLinks()
{
// Variables
var filters = [];
// Loop through calendar objects
$(calendarObjects).each(function (i) {
var name = this.name;
var colour = GetColourCodeFromName(name);
// Add filters variable
filters.push("<a href='javascript:void(0)' id='" + name.replace(/ /g, "") + "' class='filterLink' style='background-color:" + colour + "' onclick='FilterCategory(\"" + name + "\")'>" + name + "</a> ");
});
// Add filters to page
$('.calendarFilters').replaceWith(filters.join(''));
$('.filters a').click(function () {
$(this).addClass('selected');
$(this).siblings().removeClass('selected');
});
}
</script>
<style>
.filters
{
margin:10px 0 0 0;
}
.filters .title
{
font-size:15px;
margin:0 5px 0 0;
}
.filters .filterLink
{
color:#ffffff !important;
padding:3px 6px 4px 6px;
display: inline-block;
margin-bottom: 5px;
}
.filters .filterLinkShowAll
{
color:#ffffff !important;
background:#666666;
}
.filters .selected
{
border:2px solid #000000 !important;
padding:1px 4px 2px 4px;
}
</style>
<input type="hidden" id="hfdSelectedFilter" name="hfdSelectedFilter">
<div class="filters">
<span class="title">Filters:</span>
Show all
<div class="calendarFilters">
<!-- -->
</div>
</div>
There is a variable that controls color
$box.css('background-color', '#da7b2f');
The problem is when I try to remove the background-color variable, it does not use the following stylesheet and just inherits the color from the table it's from. How can I incorporate this stylesheet so it works with the jQuery script?
<style>
.ms-acal-time, .ms-acal-apanel-color {
DISPLAY: none;
}
.ms-acal-color6{
background-color:#0066cc!important;
}
.ms-acal-apanel-color6{
background-color:#0066cc!important;
}
.ms-acal-color8{
background-color:#787878!important;
}
.ms-acal-apanel-color8{
background-color:#787878!important;
}
</style>
I want to change the innerHTML so for every circle thats the same it adds +1
if (document.getElementById("circle1").style.backgroundColor == document.getElementById("circle5").style.backgroundColor) {
document.getElementById("point2").innerHTML = +1
}
if (document.getElementById("circle2").style.backgroundColor == document.getElementById("circle6").style.backgroundColor) {
document.getElementById("point2").innerHTML = +1
}
I suggest you to use innerText then. First get the old value and cast to Number then add by 1 and replace the old value. Example:
if (document.getElementById("circle1").style.backgroundColor == document.getElementById("circle5").style.backgroundColor) {
let obj = document.getElementById("point2");
let oldValue = Number(obj.innerText);
obj.innerText = oldValue + 1;
}
if (document.getElementById("circle2").style.backgroundColor == document.getElementById("circle6").style.backgroundColor) {
let obj = document.getElementById("point2");
let oldValue = Number(obj.innerText);
obj.innerText = oldValue + 1;
}
See difference between innerText and innerHtml.
document.getElementById("point2").innerHTML doesn't give you a number, so you cannot add 1 to it. first you need to parse the content to a number (like with parseInt or Number), and then you can add 1.
// creating the reference variable (for smaller code)
var point2 = document.getElementById("point2").innerHTML
if (document.getElementById("circle1").style.backgroundColor ==
document.getElementById("circle5").style.backgroundColor) {
document.getElementById("point2").innerHTML = increment(point2)
}
if (document.getElementById("circle2").style.backgroundColor ==
document.getElementById("circle6").style.backgroundColor) {
document.getElementById("point2").innerHTML = increment(point2)
}
// function to increment the value of point2
function increment(html) {
return Number(document.getElementById("point2").innerHTML) + 1
}
#circle1 {
background-color: red;
}
#circle5 {
background-color: red;
}
#circle2 {
background-color: red;
}
#circle6 {
background-color: red;
}
<div id="circle1">C1</div>
<div id="circle5">C5</div>
<br />
<div id="circle2">C2</div>
<div id="circle6">C6</div>
<div id="point2">0</div>
I'm using fancybox to display image gallery.
I have this layout:
<div class="avatar">
<a class="avatar-item" data-fancybox="group" data-caption="Caption #1" href="img/avatars/jessica1.jpeg">
<img src="./img/avatars/jessica1.jpeg" width="145" height="145" alt="">
</a>
<a class="avatar-item" data-fancybox="group" data-caption="Caption #2" href="img/avatars/jessica2.jpeg">
<img src="./img/avatars/jessica2.jpeg" alt="">
</a>
</div>
And when I click on preview - gallery popup occurs, but it shows 4 images instead of 2. I included fancybox via data-attributes, without javascript. Tried magnific popup with gallery option - got same result.
link href attribute value and internal image src attribute are the same.
I don't have a thumbnail, display image cropped with css.
Hee is CSS:
.avatar {
&.slick-dotted.slick-slider {
margin-bottom: 0;
}
a.avatar-item {
width: 146px;
height: 146px;
display: inline-block;
}
width: 146px;
height: 146px;
border: 4px solid #FFF;
float: left;
position: relative;
overflow: hidden;
img {
height: 100%;
}
}
Found the problem. I use slick-slider before with infinite: true parameter, which creates an extra slides, so I got count slides x2
I have extended the _run function. Now duplicate images are removed from the gallery and still the correct key is returned. Furthermore I have the possibility to arrange the images in any order via data-facybox position.
So it is also possible to use the infinity version of the slick slider.
function _run(e, opts) {
var tempItems,
items = [],
newItem,
reOrder,
duplicates = false,
pos,
index = 0,
$target,
value,
instance;
// Avoid opening multiple times
if (e && e.isDefaultPrevented()) {
return;
}
e.preventDefault();
opts = opts || {};
if (e && e.data) {
opts = mergeOpts(e.data.options, opts);
}
$target = opts.$target || $(e.currentTarget).trigger("blur");
instance = $.fancybox.getInstance();
if (instance && instance.$trigger && instance.$trigger.is($target)) {
return;
}
if (opts.selector) {
tempItems = $(opts.selector);
} else {
// Get all related items and find index for clicked one
value = $target.attr("data-fancybox") || "";
if (value) {
tempItems = e.data ? e.data.items : [];
tempItems = tempItems.length ? tempItems.filter('[data-fancybox="' +
value + '"]') : $('[data-fancybox="' + value + '"]');
} else {
tempItems = [$target];
}
}
if (tempItems.length > 1) {
$.each(tempItems, function(key, item) { // prevents duplicate images in the gallery
newItem = false;
if (typeof item !== 'undefined') {
if (items.length > 0) {
var found = items.filter(function (items) { return items.href ==
item.href });
if (found.length == 0) {
newItem = true;
} else {
duplicates = true;
}
} else {
newItem = true;
}
}
if (newItem) {
// Sort if the attribute data-fancybox-pos exists
if ($(item).data('fancybox-pos')) {
reOrder = true;
pos = $(item).data('fancybox-pos') - 1;
if (pos in items) {
tempItem = items[pos];
items[pos] = item;
items.push(tempItem);
} else {
items[pos] = item;
}
} else {
items.push(item);
}
}
});
} else {
items = tempItems;
}
if (duplicates || reOrder) {
// find correct index if there were duplicates
$.each(items, function(key, item) {
if (item.href == $target[0].href) {
index = key;
}
});
} else {
index = $(items).index($target);
}
// Sometimes current item can not be found
if (index < 0) {
index = 0;
}
instance = $.fancybox.open(items, opts, index);
// Save last active element
instance.$trigger = $target;
}
This script when included in an HTML document which includes any declared styles (excluding those set by style="") will output an optimized stylesheet to the to the page. The script uses the following methods...
Ignore any # or : rules to leave responsive styles as is.
Separate the rules into single selector rules so we can test for inheritance later on.
Remove rules that apply to selectors which don't exist in the document, thanks to #RickHitchcock for this.
Retrieve both the declared and computed styles in the same format (excluding percentages) then compare both values each other, then remove the property and check again.
if the declared value matches the computed value and by removing the property the value changes, then set the keep flag. This tells us whether the property has an effect on an element, if no elements were affected by the property... remove it.
If there are no properties in the remaining CSSRule then remove that rule.
As a side effect most selectors which don't change the browsers default setting will be removed (unless using font as opposed to font-* and similar which will activate the rest of the settings for that property).
While running this script on a site which includes styles relating to dynamic elements, I just wrap them in a media query
#media (min-width: 0px) {
/* This says that these styles always apply */
}
Question
How can I group the selectors with common properties?
(Demo)
var stylesheets = document.styleSheets, stylesheet, i;
var ruleText = "";
if(stylesheets && stylesheets.length) {
for (i = 0; (stylesheet = stylesheets[i]); i++) {
var rules = stylesheet.rules, rule, j;
if(rules && rules.length) {
for (j = 0; (rule = rules[j]); j++) {
if(rule.type === rule.STYLE_RULE) {
if(rule.selectorText.indexOf(',') >= 0) {
var newRules = [];
var selectors = rule.selectorText.split(','), selector, k;
for(k = 0; (selector = selectors[k]); k++) {
var styles = rule.style, style, l;
var elements = document.querySelectorAll(selector.trim()), element, l;
if(elements.length) {
var styleString = '';
for(m = 0; (style = styles[m]); m++) {
styleString += style + ': ' + styles.getPropertyValue(style) + "; ";
}
newRules.push((selector.trim() + ' { ' + styleString.trim() + ' }'));
}
}
stylesheet.deleteRule(j);
for(k = 0; (rule = newRules[k]); k++) {
stylesheet.insertRule(rule, j);
}
}
}
}
for (j = 0; (rule = rules[j]); j++) {
if(rule.type === rule.STYLE_RULE && rule.selectorText.indexOf(':') < 0) {
var styles = rule.style, style, k;
var elements = document.querySelectorAll(rule.selectorText);
if(elements && elements.length) {
for(k = 0; (style = styles[k]); k++) {
var value = styles.getPropertyValue(style);
if(value.indexOf('%') < 0) {
var elements = document.querySelectorAll(rule.selectorText), element, m;
var keep = false;
for(m = 0; (element = elements[m]); m++) {
var computed = window.getComputedStyle(element).getPropertyValue(style);
var match1 = value === computed;
styles.removeProperty(style);
var computed = window.getComputedStyle(element).getPropertyValue(style);
var match2 = value === computed;
styles.setProperty(style, value);
if( match1 && !match2 ) {
keep = true;
}
}
if(!keep) {
styles.removeProperty(style);
}
}
}
ruleText += rule.cssText + "\n";
}
} else {
ruleText += rule.cssText + "\n";
}
}
}
}
}
document.body.innerHTML = '<pre>' + ruleText + '<pre>';
Future viewers: this is available on github as optiCSS (read: eye-pleasing)
This looks great, and I have only a minor suggestion.
Change your code as follows:
for (j = 0; rule = rules[j]; j++) {
var styles = rule.style, style, k;
var elements = document.querySelectorAll(rule.selectorText);
if(elements.length) {
for(k = 0; style = styles[k]; k++) {
...
}
console.log(rule.cssText);
}
}
This will prevent the output of rules that don't have any matching HTML.
In this Fiddle, the li rule is output with your code, but it's not output with the above modification.
The next challenge is to simplify those font, border, padding, … styles.
Based on your Edit #25, you're left with a string that looks like this:
html { margin-right: 0px; margin-left: 0px; height: 100%; }
body { margin-right: 0px; margin-left: 0px; height: 100%; margin-top: 0px; }
body { margin-bottom: 5px; background-color: rgb(255, 0, 0); }
#media (max-width: 500px) {
body { background: blue; }
}
Here's how to turn it into this:
html {margin-right:0px;margin-left:0px;height:100%;}
body {margin-right:0px;margin-left:0px;height:100%;margin-top:0px;margin-bottom:5px;background-color:rgb(255 0 0);}
#media (max-width: 500px) {
body { background: blue; }
}
In the process, you'll get two objects:
html {"margin-right":"0px;","margin-left":"0px;","height":"100%;"}
body {"margin-right":"0px;","margin-left":"0px;","height":"100%;","margin-top":"0px;","margin-bottom":"5px;","background-color":"rgb(255, 0, 0);"}
First, keep your media query output separate since you don't want it to be affected:
var ruleText = "", mediaText = "";
...
if (styles.length) {
ruleText += rule.cssText + "\n";
}
} else {
mediaText += rule.cssText + "\n";
}
Then place this after your loop:
var inp= ruleText.split('\n'),
out= '',
selectors= {};
inp.forEach(function(val) {
if(val) {
var selector= val.split(/ *{/)[0],
styles= val.split(/{ */)[1].split('}')[0].split(/; */);
selectors[selector]= selectors[selector] || {};
styles.forEach(function(val) {
if(val) {
var st= val.split(/ *: */);
selectors[selector][st[0]]= st[1]+';';
}
});
}
});
for(var i in selectors) {
out+= i+' '+JSON.stringify(selectors[i]).replace(/[,"]/g,'')+'\n';
}
document.body.innerHTML= '<pre>'+out+mediaText+'</pre>';
For simplicity, the code above assumes there is no string content in the CSS that contains double quotes, semicolons, commas, or curly braces. That would complicate things somewhat.
Fiddle
I have three elements, the first element clicked needs to change, lets say to red. no matter what element is clicked. The second element clicked needs to turn green then last element clicked needs to turn blue. When these elements are clicked a second time they need to turn back to white.
The first element is not a problem but how do I move on to change the other elements?
css
.container {
background-color: #ffffff;
border: 1px solid blue;
border-radius: 10px;
width: 100px;
height: 50px;
}
.red { background-color: #ff0000; }
.green { background-color: #00ff00; }
.blue { background-color: #0000ff; }
html
<div class='container' id='1' onclick='changeColor(1);'></div>
<div class='container' id='2' onclick='changeColor(2);'></div>
<div class='container' id='3' onclick='changeColor(3);'></div>
javascript
function changeColor(whichOne)
{
var element = document.getElementById(whichOne);
if ( whichOne == 1 || whichOne == 2 || whichOne == 3 )
{
element.classList.toggle("red");
}
}//end
The general process for something like this is:
Use an Array to hold the values you want to cycle through and a counter to indicate the position of the next value to use.
When you need to apply a value, pull it from the Array using the counter as the index.
After using a value, increment the counter so it indicates the next value in the Array. If the counter has reached the end of the Array, reset it back to 0.
Here is an example:
var valuesToUse = ['classA', 'classB', 'classC'],
nextIndex = 0;
function applyValue(target) {
var value = valuesToUse[nextIndex];
nextIndex = (nextIndex + 1) % valuesToUse.length;
// use `value` on `target`
}
Here is this idea applied to your problem via either cycling through classnames or through color values in JavaScript.
http://jsfiddle.net/teTTR/1/
var colors = ['#ff0000', '#00ff00', '#0000ff'],
nextColor = 0;
var classes = ['red', 'green', 'blue'],
nextClass = 0;
var elms = document.querySelectorAll('.color-changer'),
len = elms.length,
i = 0;
for (; i < len; i++) {
elms[i].addEventListener('click', changeColor);
}
elms = document.querySelectorAll('.class-changer');
len = elms.length;
i = 0;
for (; i < len; i++) {
elms[i].addEventListener('click', changeClass);
}
function changeClass(event) {
var elm = event.currentTarget,
currentClass = hasClass(elm, classes);
if (currentClass) {
elm.classList.remove(currentClass);
} else {
elm.classList.add(classes[nextClass]);
nextClass = (nextClass + 1) % classes.length;
}
}
function changeColor(event) {
var element = event.currentTarget;
if (element.style.backgroundColor) {
element.style.backgroundColor = '';
} else {
element.style.backgroundColor = colors[nextColor];
nextColor = (nextColor + 1) % colors.length;
}
}
function hasClass(elm, classes) {
var len,
i;
if (isArray(classes)) {
len = classes.length;
i = 0;
for (; i < len; i++) {
if (elm.classList.contains(classes[i])) {
return classes[i];
}
}
return false;
}
return elm.classList.contains(classes) ? classes : false;
}
function isArray(item) {
return Object.prototype.toString.call(item) === '[object Array]';
}