I have a simple function of switching between two different css files by clicking on the button on site. The css is replaced with another when I click once. But when I click for the second time, the first css does not resume. So in other words, I need that clicking on one and the same button, I have changing of theme css (e.g. blue and green and vice versa). I tried tens of variants, but I'm new to JS and have some difficulties with that.
Here is my code
function switchTheme() {
let css = document.getElementById('css_file').href = "css/style.css";
if (css) {
return document.getElementById('css_file').href = "css/green-theme.css";
}
}
let changeButton = document.querySelector(".change_theme");
changeButton.addEventListener('click', switchTheme);
The reason is simple: You don't have proper code to switch back. It should look more like this (not tested):
var currentState = true;
function switchTheme() {
if (currentState) {
document.getElementById('css_file').href = "css/green-theme.css";
}
else{
document.getElementById('css_file').href = "css/style.css";
}
currentState = !currentState;
}
let changeButton = document.querySelector(".change_theme");
changeButton.addEventListener('click', switchTheme);
The problem is that you always set it to the normal theme and then back to the green theme which makes no sense to do because that changes nothing. What you want to do is save if you currently use the normal theme, if that's the case, then you enable the green theme, otherwise the normal one. currentState = !currentState means that you set current state to its opposite value, so true if it was false and false if it was true.
What your old code did was this:
function switchTheme() { //Button was pressed
let css = document.getElementById('css_file').href = "css/style.css";//Set the
//current theme to the normal one. Because it's css = href = "style", you set css to "style" (I think, or maybe just true because it's a valid operation, so don't quote me on that)
if (css) { //If css contains something true, this code is executed.
//Note that css is always "[...]style", so it's always a non-empty string which is true
return document.getElementById('css_file').href = "css/green-theme.css"; //Then set the style to green - this always happens so you can essentially delete every other line and nothing would change.
}
}
Here, try this code:
function switchTheme() {
let css = document.getElementById('css_file').href;
if (css == "css/style.css" ) {
return document.getElementById('css_file').href = "css/green-theme.css";
}
else {
return document.getElementById('css_file').href = "css/style.css";
}
}
let changeButton = document.querySelector(".change_theme");
changeButton.addEventListener('click', switchTheme);
The operator a=b doesn't check the equality but just affect b to a so document.getElementById('css_file').href = "css/style.css" is not doing what you suppose.
To check something use ===:
function switchTheme() {
const file = document.getElementById('css_file')
let isStyle = file.href === "css/style.css"
let path
if (isStyle) {
path = "css/green-theme.css"
} else {
path = "css/style.css"
}
file.setAttribute('href', path)
}
let changeButton = document.querySelector(".change_theme");
changeButton.addEventListener('click', switchTheme);
<button class="change_theme">
change_theme
</button>
<a id="css_file" href="css/style.css"></a>
Related
Very briefly, I'm trying to create a way to slide out a div and make it visible by clicking a button on the webpage. I have the css and the layout looking correct and the animation runs once but then doesn't work again.
this is the full js file
var button1Toggle;
var button2Toggle;
var button3Toggle;
button1Toggle = false;
function slideOutFunc() {
if (button1Toggle == false) {
document.getElementById('fade-in1').style.left = '0';
document.getElementById('fade-in1').style.opacity = '1';
button1Toggle = true;
} else {
document.getElementById('fade-in1').style.left = '-33vw';
document.getElementById('fade-in1').style.opacity = '0';
button1Toggle = true;
}
}
<button id="clickApply" class="applyButton" onclick="slideOutFunc()"><a>Apply</a></button>
this is the html portion that calls the function
Any help understanding why it only works once would be appreciated.
Both conditions in sildeOutFunc set buttonToggle to true
var mpegArray = ["1.m4a", "2.m4a", "3.m4a", "4.m4a", "5.m4a", "6.m4a", "7.m4a", "8.m4a", "9.m4a", "10.m4a"];
var choice = Math.floor(Math.random() * mpegArray.length);
function btnPlay_onClick() {
var player = document.getElementById('sound');
player.src = mpegArray[choice];
player.play();
player.addEventListener('ended', function () {
if (player.ended) {
mpeg();
}
}, true);
}
function btnN1_onClick() {
var Audio1 = document.getElementById("audio1");
Audio1.play();
if (choice == 0) {
document.getElementById("btnN1").src = "1GR.gif";
ans.innerText = CORRECT;
}
else
document.getElementById("btnN1").src = "1RD.gif";
ans.innerText = INCORRECT;
}
hiya the code here is meant to get number tiles to change colour based on if the requirements of the if statements are met. here the if statement is asking if button 1 is pressed after the audio file 1.m4a is played change the colour of he tile to green if not change it to red
You might be better served changing the css with a background colour/image instead of the src attribute.
document.getElementById("btnN1").style.backgroundColor = "green";
or
document.getElementById("btnN1").style.backgroundImage = "url('1GR.gif')";
EDIT: GiaFil7 is right. You're missing a closing } after the second if statement which might be causing your issue.
I'm having toruble with this function, it requires two clicks before the if statement is satisfied even though in the CSS the condition should be met. On the fist click, the console shows triggered but not if state on the second click it does show if state can anyone understand why the condition is not being met?
function searchShow() {
console.log('started');
document.getElementById('top_line_2a').addEventListener('click', function() {
console.log('triggered')
var searchClickIcon = document.getElementById('top_line_2a');
var searchClick = document.getElementById('top_line_3');
if(searchClick.style.height == '0em') {
console.log('if state');
//searchClick.style.display = 'block';
searchClick.style.height = '3em';
searchClickIcon.style.color = 'white';
searchClickIcon.style.textShadow = '0px 0px 7px white';
document.getElementsByClassName('search')[0].focus();
} else {
//searchClick.style.display = 'none';
searchClick.style.height = '0em';
searchClickIcon.style.color = 'rgba(255, 187, 61, 1)';
searchClickIcon.style.textShadow = '';
}
})
console.log('added');
}
When implementing ping-pong / toggle effects, try not to compare with attribute value directly. The zero height could be "0em", "0", or numeric 0. You could try normalizing the value for this one particular case:
if (parseInt(searchClick.style.height,10)==0) {
// show the container
} else {
// hide the container
}
A much more reliable way is to take advantage of the fact that every DOM element can be dynamically assigned new attributes. Since you already have a handle to the searchClick object:
if (searchClick.showing){
searchClick.showing=null;
// hide the container
} else {
searchClick.showing=true;
// show the container
}
"showing" is your own attribute. When you first click on it, the marker is not there, so it'll show the container (initially hidden). Then the showing flag is attached to it, so you can detect it in the next click. If your initial state is showing, then use a different flag to reverse the logic. This is a sure fire method to implement a toggle.
You shouldn't be using the height. Use a variable instead.
var triggered = false;
function searchShow() {
document.getElementById('top_line_2a').addEventListener('click', function() {
//Do stuff
if(!triggered) {
triggered = true;
//Do stuff
} else {
triggered = false;
//Do stuff
}
})
}
Checking for a style in an if statement isn't a good practice. If you ever change the size of your container for X reason, you'll also have to change the if/else statement to fit the change. It also make the code that much less clear to whoever will read it. Always try to avoid using hardcoded numbers when you can use something more effective.
I have a webpage using a javascript. The code sample:
<script type="text/javascript">
var shown = 0;
function showOrHidePanel()
{
var isComplete = '<h:outputText value="#{general.sessionCompleted}" />';
if (isComplete == true){
if (shown==0) {
Richfaces.showModalPanel('pnl',{width:550, top:200});
}
shown = 1;
} else {
if (shown == 1) {
Richfaces.hideModalPanel('pnl');
}
shown = 0;
}
return;
}
</script>
<a4j:region>
<h:form>
<a4j:poll id="poll" interval="10000" reRender="pnl" action="#{general.checkOnDrcSession}"
oncomplete="showOrHidePanel()" />
</h:form>
</a4j:region>
The effect i'm trying to achieve is to make the modalpanel be shown by the polling component only once whenever sessionCompleted becomes true (So it wont show the flickering page effect on every re-show of the modalpanel.
But i'm a javascript newb and i'm afraid that, in addition to this not working correctly, I get a 'true' text at the top of the page.
When i take down the var isComplete = '<h:output... declaration, the 'true' text disappears.
Thanks for the help...
Get rid of those singlequotes.
var isComplete = <h:outputText value="#{general.sessionCompleted}" />;
You want to end up with
var isComplete = true; // or false
and not with
var isComplete = 'true'; // or 'false'
in the generated output.
Alternatively, you can also just do
if (<h:outputText value="#{general.sessionCompleted}" />) {
Try changing isComplete to just:
var isComplete = Boolean("#{general.sessionCompleted}");
This should (in theory) create a boolean value based on the text that is rendered by the server.
I created a simple RSS web app using the template in Dashcode. Problem is, when choosing items in the list from the feed the transition flickers (even with the default settings). I am guessing its because of the images in the posts.
I tried disabling the transitions completely but even then I get a flickering when returning to the list. This problem does not appear to affect safari on OSX only on the iphone.
Here is the code that I think is responsible:
var topStories = parseInt(attributes.topStories, 30);
function load()
{
dashcode.setupParts();
// set today's date
var todaysDate = document.getElementById("todaysDate");
todaysDate.innerText = createDateStr(new Date()).toUpperCase();
setupFilters("headlineList");
// This message checks for common errors with the RSS feed or setup.
// The handler will hide the split view and display the error message.
handleCommonErrors(attributes.dataSource,
function(errorMessage) {
var stackLayout = document.getElementById("StackLayout")
if (stackLayout) {
stackLayout.style.display = 'none';
}
showError(errorMessage);
});
// get notifications from the stack layout when the transition ends
document.getElementById("StackLayout").object.endTransitionCallback = function(stackLayout, oldView, newView) {
// clear selection of lists when navigating to the first view
var firstView = stackLayout.getAllViews()[0];
if (newView == firstView) {
document.getElementById("headlineList").object.clearSelection(true);
}
}
}
function articleClicked(event)
{
document.getElementById("StackLayout").object.setCurrentView("articlePage", false, true);
}
function backToArticlesClicked(event)
{
document.getElementById("StackLayout").object.setCurrentView("frontPage", true);
}
function readMoreClicked(event)
{
var headlineList = dashcode.getDataSource('headlineList');
var secondHeadlines = dashcode.getDataSource("secondHeadlines");
var selectedItem = null;
if (headlineList.hasSelection()) {
selectedItem = headlineList.selectedObjects()[0];
} else if (secondHeadlines.hasSelection()) {
selectedItem = secondHeadlines.selectedObjects()[0];
}
if (selectedItem) {
var link = selectedItem.valueForKeyPath('link');
// If the link is an object, not a string, then this may be an ATOM feed, grab the actual
// href from the href attr
if (typeof(link) == 'object') {
link = selectedItem.valueForKeyPath('link.$href');
// If the link is an array (there is more then one link), just grab the first one
if (DC.typeOf(link) == 'array') {
link = link[0];
}
}
window.location = link;
}
}
var headlineListDataSource = {
// The List calls this method once for every row.
prepareRow: function(rowElement, rowIndex, templateElements) {
if (rowIndex >= topStories) {
templateElements['headlineDescription'].style.display = 'none';
templateElements['headlineTitle'].style.fontSize = '15px';
}
}
};
The following CSS rule fixed all of my "-webkit-transition" animation flickering issues on the iPad:
body {-webkit-transform:translate3d(0,0,0);}
I am not sure how well that applies to your problem but in general you should set the backface visibility to hidden if not needed. That will most likely kill all flickering on a page.
-webkit-backface-visibility: hidden;