I'm trying to figure out how to pull attributes from CSS to be used in Javascript. I've googled what I'm looking for so many times and in so many ways my fingers are about to fall off.
I'm looking to change font size to three different font sizes: 15px, 28px, and 40px. This would be toggled using three buttons. However, when you choose a font size, some of the other CSS attributes need to change in order to resize the text and padding to align with the element "behind" it, so that it doesn't push off the side and look ugly. I'm planning on doing the resizing automatically with Javascript, but for the life of me I can't figure out how to pull the "text size in pixels" attribute from the page in order to apply an "if/else" argument. This would need to be done in browser and I've found a .getComputedStyle command. But as I can't get it to work I'm not sure if that's what I need or not.
<body>
<p id="spaz">Text to be resized.</p>
<button type="button" onclick="txtszl()">large</button>
<button type="button" onclick="txtszm()">medium</button>
<script>
function txtszl(){
document.getElementById("spaz").style.fontSize="40px";
}
function txtszm(){
document.getElementById("spaz").style.fontSize="28px";
}
var $txtelement = document.getElementById("spaz");
var $txtsize = $txtelement.getComputedStyle("fontSize");
if ($txtsize == 40px){
alert("It's forty!");
}else{
alert("Nope!");
}
</script>
</body>
That's what I have come up with. Any help/links would be greatly appreciated!
The getComputedStyle function returns a CSSStyleDeclaration.
var txtElementStyles = getComputedStyle($txtelement, null),
fontSize = txtElementStyles.getPropertyValue('font-size');
Working fiddle: http://jsfiddle.net/wrathchild77/6LJaM/
function txtszl() {
document.getElementById("spaz").style.fontSize = "40px";
check();
}
function txtszm() {
document.getElementById("spaz").style.fontSize = "28px";
check();
}
function check() {
var $txtsize = document.getElementById("spaz").style.fontSize;
if ($txtsize == "40px") {
alert("It's forty!");
} else {
alert("Nope!");
}
}
Related
As per suggestion from a user, I decided to redo my question.
What I'm trying to do is change foreground and background colors of several elements without using a stylesheet.
Next to each colourIt call just under the script tag is the style I'm trying to reproduce Javascript style. This is because my stylesheet is too large and is taking up more than 1/2 my website code, especially with all those background color declarations.
This is my new code:
<table>
<tr>
<td ID="CELL">
GREENonYELLOW
<p>BLUEonRED<i>REDonGREEN<b>YELLOWonBLUE</b>REDonGREEN</i>BLUEonRED</p>
<p>BLUEonRED<i>REDonGREEN<b>YELLOWonBLUE</b>REDonGREEN</i>BLUEonRED</p>
GREENonYELLOW
</td>
</tr>
</table>
<script>
colorIt('CELL','','#FF0','#0F0'); //#CELL {background:#F00;color:#0F0}
colorIt('CELL','P','#F00','#00F'); //#CELL P{background:#00F;color:#F00}
colorIt('CELL','P I','#0F0','#F00'); //#CELL P I{background:#F00;color:#0F0}
colorIt('CELL','P I B','#00F','#FF0'); //#CELL P I B{background:#FF0;color:#00F}
//populate array with pointers as parents to the children are found
function getKidValues(parent,children){
var allKids=[],childrenSet=document.getElementsByTagName(children);
childrenSetSize=childrenSet.length;
for(kidsIndex=0;kidsIndex < childrenSetSize;kidsIndex++){
if(childrenSet[kidsIndex].parentNode==parent){
allKids.push(childrenSet[kidsIndex])
}
}
return allKids;
}
function colorIt(parent,kids,backgroundColor,foregroundColor){
if(parent){
parentPtr=document.getElementById(parent);
if(kids){
kidSet=kids.split(' ');
kidSetSize=kids.length;
for (index=0;index < kidSetSize;index++){
//get proper kids. I think I need to pass new parameters but idk which??
currentKids=getKidValues(parentPtr,kidSet[index]);
//go through the kids setting the colors.
for (thisKidIndex in currentKids){
setColor(currentKids[thisKidIndex],backgroundColor,foregroundColor);
}
}
}
}
}
//just sets color of element: This function isn't problematic.
function setColor(item,back,fore){
if(item){
item=item.style;
if(item){
if(back){item.backgroundColor=back}
if(fore){item.color=fore}
}
}
}
</script>
I feel I need to add recursion to solve this, but if there's another way to solve it without killing a computer processor and that works in Internet Explorer 7, then I'm looking forward to that answer.
So far, this javascript was only able to satisfy one child to the ColorIt function correctly, It does not work with more than one child.
What can I do to fix this?
UPDATE
I changed my javascript code to:
function setValues(parent,children,depth,b,f){
var childrenSet=document.getElementsByTagName(children[depth]),childrenSetSize=childrenSet.length;
for(kidsIndex=0;kidsIndex < childrenSetSize;kidsIndex++){
var m=childrenSet[kidsIndex];
if(m.parentNode==parent){
if ((depth+1) < children.length){
setValues(m,children,depth+1,b,f);
}else{
setColor(m,b,f);
}
}
}
}
function colorIt(parent,kids,backgroundColor,foregroundColor){
if(parent){
parentPtr=document.getElementById(parent);
if(kids){
kidSet=kids.split(' ');
setValues(parentPtr,kidSet,0,backgroundColor,foregroundColor);
}
}
}
function setColor(item,back,fore){
if(item){
item=item.style;
if(item){
if(back){item.backgroundColor=back}
if(fore){item.color=fore}
}
}
}
and everything works but only the first line of text is being affected. I want both lines to be the same way, not one being just one color. Remember, I'm trying to rewrite some of my CSS. see above.
IGNORE THIS PART EDIT 4 IS THE MOST PERTINENT (see below)
loving Polymer! Just trying to adapt three functions into my code:
Polymer('my-element', {
// JavaScript for Box (Also Beta)
unhidePanel: function(panelName) {
var panel = this.$.panelName;
var hidden = panel.getAttribute('isPanelHidden');
if (hidden == "true") {
panel.style.display="block";
panel.setAttribute('isPanelHidden', "false");
}
else {
panel.style.display="none";
panel.setAttribute('isPanelHidden', "true");
}
},
voteDefPercent: function(val,defid) {
var def = this.$.defid;
var upvotes = parseInt(def.getAttribute("data-upvotes"),10) + val;
var votes = parseInt(def.getAttribute("data-votes"),10) + 1;
var percent = Math.round((upvotes / votes) * 100);
def.setAttribute('data-upvotes', upvotes);
def.setAttribute('data-votes', votes);
def.value = percent;
},
voteidPercent: function(val,tagid) {
var tag = this.$.tagid;
var upvotes = parseInt(tag.getAttribute("data-upvotes"),10) + val;
var votes = parseInt(tag.getAttribute("data-votes"),10) + 1;
var percent = Math.round((upvotes / votes) * 100);
tag.style.backgroundSize = percent + "%, 100%, 100%, 100%";
tag.setAttribute('data-upvotes', upvotes);
tag.setAttribute('data-votes', votes);
},
// End JavaScript
});
These functions were originally JavaScript, with a couple changes. The code isn't working for any of the three so I'm wondering if there is a syntax problem or some other thing I need to change. Is it possible to pass variables using the form onclick: {{ functionName(variableName) }} or is there some sort of other special syntax? Thanks so much!!
EDIT 1
Example of HTML code:
<button type="button" class="btn btn-default tag-upvote" on-click="voteidPercent(1,'sample-tag-1')"></button>
<button type="button" class="btn btn-default tag-link" id="sample-tag-1" data-upvotes="0" data-votes="0">Official Symbol</button>
<button type="button" class="btn btn-default tag-downvote" on-click="voteidPercent(0,'sample-tag-1')"></button>
EDIT 2
The system has three generic functions which are called many times by many different components. I have a feeling getting just one of them working will help me determine on my own how to fix the rest.
The HTML shown in EDIT 1 describes a group of buttons. Only the center button is visible unless the user hovers over it, splitting it into three buttons.
The three buttons are: (Upvote Button)(Link Button)(Downvote Button)
Depending on the percentage of "upvotes" vs. "total votes", when the user is no longer hovering over the button, the original center button is the only one remaining, but the percentage red or green changes depending on the percentage of upvotes vs. total votes.
There are about 50 - 80 of these button groups per page so passing each as an individual function is a tad cumbersome, but each has an individual value.
In order to store/calculate the percentage, the center button has two attributes "data-upvotes" and "data-votes". Further, whenever the upvote button is pressed it passes a parameter 1 (to add to the upvote count) and the name of the center button, whereas the downvote button passes a 0 (to add to the upvote count) and the name of the center button.
I can't think of an efficient way to do this without parameters and desperately need some pointing in the right direction. Thank you so much and thanks to Dirk for his help getting this far!
EDIT 3
I've given this a few days and I'm still lost. My current HTML example is as follows:
<p><button type="button" class="btn btn-default btn-circle" isPanelHidden="true" on-tap="{{ unhidePanel }}" panelName="relational-tags-area-1"><span class="glyphicon glyphicon-play" id="category-button"></span></button></p>
And then my refined JavaScript:
unhidePanel: function() {
var panelName = this.$.getAttribute('panelName');
var hidden = panel.getAttribute('isPanelHidden');
console.log(panelName);
if (hidden == "true") {
panel.style.display="block";
panel.setAttribute('isPanelHidden', "false");
}
else {
panel.style.display="none";
panel.setAttribute('isPanelHidden', "true");
}
},
I'm getting an "Uncaught Type error: undefined is not a function" at var panelName = this.$.getAttribute('panelName');
EDIT 4
Ignoring everything I've done above, I've run into a larger issue of the same type. Is there any way at all to use JavaScript within a Polymer element? Can I do anything along these lines:
<script language="javascript" type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js">
$(function() {
var sys = arbor.ParticleSystem(1000, 400, 1);
sys.parameters({gravity:true});
sys.renderer = Renderer("#viewport");
var animals = sys.addNode('Animals',{'color':'red','shape':'dot','label':'Animals'});
});
</script>
(This uses arbor.js, which was declared above this statement)
If not, is there a quick fix or work around that won't require rewriting all of my code? Thanks so much, sorry for the trouble.
If 'not working' means that your functions are not called, then indeed it's because your event declarations are wrong (you should have posted the HTML code instead).
You cannot pass parameters to the event handlers
The event attribute is named on-click
So you need to write on-click="{{functionName}}". Please refer to the delcarative event mapping section in the Polymer documentation.
I'm creating a PHP script that will dynamically generate tr and td elements for a table. When the user clicks in a specific cell in the first column, an AJAX function executes to display additional content. This is working as it should, however, I'm having trouble with what should be simple styling. When the user clicks on a given cell, I want that row to change colour (works) until they click on another cell (doesn't work).
Since my PHP file is rather large, I'm only posting the relevant parts.
<?php
$myFiles = showMyAttrs();
foreach($myFiles as $myFile) {
echo("<tr class = 'gradeC' onClick = 'changeColour(this)' onchange = 'restoreColour(this)' >");
echo("<td onClick = 'sendCell(this)' ><img src = $msEx /></td>");
echo("<td>$myFile</td>");
echo("</tr>");
}
I've also tried using onblur instead of onchange but that gave the same result.
The Javascript functions:
function changeColour(z) {
z.style.backgroundColor = "#FFFFFF";
}
function restoreColour(y) {
y.style.backgroundColor = "#00FF00";
}
Before I also tried:
function changeColour(z) {
document.getElementsByTagName("tr").style.backgroundColor = "#00FF00";
z.style.backgroundColor = "#FFFFFF";
<!-- document.getElementsByTagName("td").style.backgroundColor = "#00FF00"; -->
}
function changeColour(z) {
z.style.backgroundColor = "#FFFFFF";
document.getElementsByTagName("tr").style.backgroundColor = "#00FF00";
}
$('tr').click(function() {
$('tr').css('backgroundColor', '#0F0');
$(this).css('backgroundColor', '#FFF');
});
With each of them (except the last), the colour does change to white, however, when the user clicks on any other row, the previous row doesn't return to green. I don't mind if this works with Javascript or JQuery, as long as it is compatible across browsers. Even a fancy CSS trick I'm fine with using.
You're on the right track. I think adding/removing a class would be a good way to go. You could try this:
jQuery
$('tr').on('click', function() {
$('tr').children('td').removeClass('active');
$(this).children('td').addClass('active');
});
CSS
.active { background-color: yellow; }
See jsFiddle
Try using a css class to assign the background color:
$('.gradeC td').on('click',function(e){
if(!$(this).closest('tr').hasClass('green')){
$(this).closest('tr').addClass('green');
}else{
$(this).closest('tr').removeClass('green');
}
});
See demo here
i am trying to make a colour change when a button is clicked and i managed to do this however i want to change the colour of not just the main content container but more containers how do i do this?
function changeblackandwhite(objDivID) {
if(document.getElementById(objDivID).style.color=='black'){
document.getElementById(objDivID).style.color='white';
document.getElementById(objDivID).style.backgroundColor='black';
}
else if(document.getElementById(objDivID).style.color=='white'){
document.getElementById(objDivID).style.color='black';
document.getElementById(objDivID).style.backgroundColor = 'white';
}
else{
document.getElementById(objDivID).style.color='black';
document.getElementById(objDivID).style.backgroundColor='white';
}
}
<img src="images/colour.jpg" title="Change Text/Backgroud Colors">
There are dozens of ways you can accomplish this.
You could change the argument of your function to be an array of strings. You could also reduce the complexity of your function as well
<script type="text/javascript">
changeblackandwhite = function() {
for( var idx=0; idx < arguments.length; idx++) {
var tgtDiv= document.getElementById(arguments[i]);
if(tgtDiv.style.color=='black'){
tgtDiv.style.color='white';
tgtDiv.style.backgroundColor='black';
}
else{
tgtDiv.style.color='black';
tgtDiv.style.backgroundColor='white';
}
}
};
</script>
<img src="images/colour.jpg" title="Change Text/Backgroud Colors">
As another reader questioned - you can do this with jQuery in a single line.
With jQuery, you can declare the elements in question to have a class attribute.
Using jQuery, you can then do something like:
$('div.someClass').css({'color': 'black', 'background-color': 'white'});
The argument to jQuery can be a class based selector, an id based selector, or any other selector you choose.
If you are open to jquery and you assign 1 class in common with these two divs you can do the following:
This should get you started (see this jsfiddle): I changed the fiddle to include a neater solution where clicking on the button adds and removes classes on the containers which allows you to set multiple attributes including the text color in one quick call.
<div class='container'>
</div>
<div class='container'>
</div>
<button id="changeColor" type="button">Change Color </button>
<script type="text/javascript">
$(document).ready( function() {
$('#changeColor').click( function() {
if ($('.container').hasClass("blackContainer")){
$('.container').addClass("whiteContainer");
$('.container').removeClass("blackContainer");
} else {
$('.container').removeClass("whiteContainer");
$('.container').addClass("blackContainer");
}
});
});
</script>
//CSS
.blackContainer {
background-color: black;
color: white;
}
.whiteContainer {
background-color: white;
color: black;
}
I made a jsfiddle for you to play around with jsfiddle
I also did the javascript/jQuery in a similar way as the OP since it usually helps them understand.
As stated above, there are several different ways to do this, I've done but one.
The document.ready function sets up an event listener for the object to be clicked, most of the time this is how you'll see events coded. So when the link is clicked, it calls the function with the string name of the object the listener is for.
$(document).ready(function() {
$("#changeit").click(function(){
changeblackandwhite("Maincontainer");
})
});
After the event listener is assigned, it will call the function below when the link is clicked on.
// Here's your function, put the current color in a var, check if it's black
// if black, change colors, else make it black.
function changeblackandwhite(objDivID) {
var curColor = $("#" + objDivID).css("color");
if( curColor == 'rgb(0, 0, 0)'){
$("#"+objDivID).css({'color':'white','background-color':'black'});
} else {
$("#"+objDivID).css({'color':'black','background-color':'ghostwhite'});
}
}
I know blinking is not a nice thing. However...
I have a long complex HTML form with a number of compulsory fields. As well as highlighting the empty text boxes I want to draw attention to them by flashing the text of the question for maybe three seconds.
All the javascript/css methods I can find all seem to fall over when there is more than one such item to blink or are designed for leaving the item blinking all the time.
Any suggestions for how to achieve this?
The method at What is the replacement for a blinking text in a web page? seems like overkill.
thanks
Derek
I've tried this (to blink each designated span just over three seconds) but it only works on the first item it's called for:
function blinkOn(span){
span.counter=0;
span.defColor=span.style.color;
span.alertTimerId =setInterval("blinkOnce('"+span.id+"')", 400 );
}
function blinkOnce(spanID){
var span=document.getElementById(spanID)
span.counter++;
if(span.style.color==span.defColor){
span.style.color='transparent'}
else{
span.style.color=span.defColor;
}
if(span.counter>8){
blinkOff(span);
}
}
function blinkOff(span){
clearInterval(span.alertTimerId);
span.style.color=span.defColor;
}
I use jQuery for this kind of thing, personally:
$('#element_id')
.fadeOut(300)
.fadeIn(300)
.fadeOut(300)
.fadeIn(300)
.fadeOut(300)
.fadeIn(300)
.fadeOut(300)
.fadeIn(300)
.fadeOut(300)
.fadeIn(300);
Quite inelegant I know but it does the job. jQuery UI does have some more concise effects.
The only place I use it is for when a user adds something to a shopping basket without redirecting to the basket page, just to make sure they know that it's been added.
See:
http://api.jquery.com/fadeIn/, http://api.jquery.com/fadeOut/ and http://jqueryui.com/docs/show/ (pulsate, in particular)
I'm not exactly clear about the behavior you desire, but it sounds like you might be able to flash the question (or take some kind of action) using a Javascript timer. You can create unique timers for each element that you want to flash. And you can flash them once or set them up to repeat infinitely or up to a limit. Here's one example:
http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/
I took some time to work this out this morning. If you haven't gotten yours to work yet, I hope you can adapt this to help.
<html>
<head>
<script type="text/javascript">
var idArray = [];
var defaultColor = '#000000';
function makeItemsBlink(blinkTime) {
blinkForTime('q1', blinkTime, '#ff0000');
blinkForTime('q2', blinkTime, '#00ff00');
blinkForTime('q3', blinkTime, '#0000ff');
}
function blinkForTime(id, blinkTime, blinkColor) {
idArray[id] = setInterval('toggleColor("' + id + '", "' + blinkColor + '")', 400);
setTimeout('stopBlinking("' + id + '")', blinkTime);
}
function stopBlinking(id) {
clearInterval(idArray[id]);
document.getElementById(id).style.color = defaultColor;
}
function toggleColor(id, blinkColor) {
var e = document.getElementById(id);
var currentColor = e.style.color;
if (currentColor == defaultColor) {
e.style.color = blinkColor;
}
else {
e.style.color = defaultColor;
}
}
</script>
</head>
<body onload="makeItemsBlink(3000);">
<div id="q1">Test question 1</div>
<div id="q2">Test question 2</div>
<div id="q3">Test question 3</div>
</body>
</html>