2

I get two error messages when trying to load the page with the code below. The error messages are:

  1. "Uncaught TypeError: Cannot set property 'href' of null at HTMLAnchorElement.col.(anonymous function).onclick (http://www.jimbrink.org/:363:17)"
  2. "Uncaught ReferenceError: bindEvents is not defined at (index):375"

I'm trying to create a link that, when clicked, would switch to another css file (with different fonts).

(BONUS QUESTION: Is there a way for the link to toggle between the two stylesheets?)

I've taken this from another StackOverflow question, but I can't seem to get the code to work my situation.

Here's the link:

                <li><a href="#" class="changeStyle" data-style="css/style.comicsans.css" data-type="text/css" data-rel="stylesheet">JB's Fav Font</a></li>

Here's the js function from the bottom of the page:

<!-- cssswitcher js -->
<script type='text/javascript'>
window.onload = function bindEvents(){

  var css=document.getElementById('style');
  var col=document.querySelectorAll('a.changeStyle');

  /* iterate through collection and assign listener */
  for( var n in col )if( col[n].nodeType==1 ) col[n].onclick=function(e){
    e.preventDefault();/* prevent jumping to top of page etc */
    var el=typeof(e.target)!='undefined' ? e.target : e.srcElement;

    /* assign style attributes */
    css.href=el.dataset.style;
    css.rel=el.dataset.rel;
    css.type=el.dataset.type;

    /* store reference to style selected in localstorage */
    localStorage.setItem( 'style', el.dataset.style );
    };

  /* if there is a reference to the user's css choice in storage, assign it */
  if( localStorage.getItem( 'style' )!=null ) css.href=localStorage.getItem( 'style' );
  }

  document.addEventListener( 'DOMContentLoaded', bindEvents, false );
</script>
3
  • 2
    No element at html at Question has id set to "style". Commented Dec 28, 2016 at 4:33
  • Yeah. But shouldn't css.style be set from "el.dataset.style", which is defined in the code? Commented Dec 28, 2016 at 5:05
  • What does console.log(css) log at console following var css=document.getElementById('style');? You can select the element using attribute selectors. Though current html at Question does not contain element having id "style"? Commented Dec 28, 2016 at 5:26

2 Answers 2

3

First, start by defining the original style like this:

HTML:

<link id="style" rel="stylesheet" type="text/css" href="style.css" />

Notice the id=style that we'll use to find the element. That might fix your first error.

For the second one, you have to decide whether to use document.addEventListener( 'DOMContentLoaded', bindEvents, false ); or window.onload because they're different functions. This might help you window.onload vs. body.onload vs. document.onready.

So, now we can do some Javascript:

HTML (the links):

 <li><button onclick='setStyle("css/style.comicsans.css")'>JB's Fav Font</button></li>
 <li><button onclick='setStyle("css/style.other.css")'>Other Font</button></li>

First, notice that I'm only using a parameter to call setStyle function on click, and btw it's better to work with <button>, this way we get a cleaner result.

Javascript:

var cssStyle = document.getElementById('style');

window.onload = function(){
    if(localStorage && localStorage.getItem("style"))
        cssStyle.href = localStorage.getItem("style");
};

function setStyle(newStyle){
    cssStyle.href = newStyle;

    if(localStorage)
        localStorage.setItem("style", newStyle);
};

BONUS: But if you are only be using two styles, then try to simplify, and do a shorthand method to do this:

HTML:

<li><button onclick='toggleStyle()'>Toggle</button></li>

<!-- cssswitcher js -->
<script type='text/javascript'>

    var cssStyle = document.getElementById('style');
    var listStyles = ["css/style.comicsans.css", "css/style.other.css"];

    window.onload = function(){
        if(localStorage && localStorage.getItem("style"))
            cssStyle.href = localStorage.getItem("style");
    };

    function toggleStyle(){
        var previousStyle = cssStyle.href;

        if(previousStyle.endsWith(listStyles[0]))
            newStyle = listStyles[1];
        else
            newStyle = listStyles[0];

        cssStyle.href = newStyle;

        if(localStorage)
            localStorage.setItem("style", newStyle);
    };
</script>
Sign up to request clarification or add additional context in comments.

2 Comments

Also, It would be a better idea to know if you only need to change the font because there is going to be a faster way to get that. Something like changing the font-family style or so. Something like this: http://www.w3schools.com/jsref/prop_style_fontfamily.asp
Amazing answer! Thanks so much!
1

I did this in one of my projects using JQuery, I hope this will help you :

HTML :

<ul id="projectList">
  <li class="project">Lorem Lorem</li>
  <li class="project viewed">Lorem Lorem</li>
  <li class="project viewed selected">Lorem Lorem</li>
  <li class="project viewed selected">Lorem Lorem</li>
  <li class="project viewed">Lorem Lorem</li>
</ul>

JavaScript with Dynamic CSS Code :

var data = {
  "projectColors": {
    "viewedColor": "#fffc20",
    "selectedColor": "#ff7920"
  }
};

var style = $(document.createElement("style")).attr("type", "text/css");
style.append("#projectList .project.viewed {color: " + data.projectColors.viewedColor + ";}");
style.append("#projectList .project.selected {color: " + data.projectColors.selectedColor + ";}");
style.appendTo("head");

JSFiddle :

https://jsfiddle.net/nikdtu/9gberp5o/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.