0

I'm rather new to web programming and javascript. I'm used to working with as3 or java for non-web projects.

I have written a bit of javascript to show and hide divs on a website. I wish to show the div that corresponds to a clicked menu item and hide all the others.

The code however, isn't working. I have tried several things but I im clearly not familiar enough with javascript to make it work.

Basically I want to add a .visibleContent class to the div I wish to show, so that css3 transition will make it fade in, and when the class is removed, css3 transitions will make it fade out.

could anyone please explain to me what im doing wrong? am I even approaching this the right way? I know of Jquery, but I think its overkill to import that library just for this. I would like to use javascript itself.

The links and divs in my html:

<li><a href="javascript:;" onClick='navClick("page1");'>page 1 button</a></li>
<li><a href="javascript:;" onClick='navClick("page2");'>page 2 button</a></li>

<div id="pages">
    <div id="page1">
        <p> page 1 content </p>
    </div>

    <div id="page2">
        <p> page 2 content </p>
    </div>
</div>

and here is the javascript, note that I have copied the hasClass, addClass and removeClass functions from here: dynamically add/remove style in javascript

var page1 = document.getElementById('page1');
var page2 = document.getElementById('page2');

var pageArray = new Array;
pageArray.push(page1);
pageArray.push(page2);


function hasClass(element,class) {
    return element.className.match(new RegExp('(\\s|^)'+class+'(\\s|$)'));
}

function addClass(element,class) {
    if (!this.hasClass(element,class)) element.className += " "+class;
}

function removeClass(ele,cls) {
    if (hasClass(element,class)) {
        var reg = new RegExp('(\\s|^)'+class+'(\\s|$)');
        element.className=element.className.replace(reg,' ');
    }
}

function navClick(id) {
    var e = document.getElementById(id);
    for (i = 0; i < pageArray.length; i++) {
        if (pageArray[i] == e) {
            if (!hasClass(pageArray[i], 'visibleContent')) {
                addClass(pageArray[i], 'visibleContent');
            }
        } else {
            if (hasClass(pageArray[i], 'visibleContent')) {
                removeClass(pageArray[i], 'visibleContent');    
            }
        }
    }
}

here is the relevant css:

 #pages div {
        opacity: 0;
        position: fixed;
        width:55%;
        height: 65%;
        top: 10%;
        left: 100%;
        background: #00FF00;
        animation fadeOutAnimation 1s linear 1; 
    }

    .visibleContent {
        opacity: 1;
        position: fixed;
        width: 55%;
        height: 65%;
        top:10%;
        left:40%;
        background: #00FF00;
        animation: fadeInAnimation 1s linear 1;
    }

when I add the .visibleContent class to a div directly in the html markup, the content shows up as it should, when I don't add the class to a div, it is indeed invisible. When I use my navClick function to try and add the class dynamically, nothing happens... Whats wrong?

Community
  • 1
  • 1
Laurens
  • 101
  • 1
  • 6
  • 2
    I guess I'll be the first to say it: Why not use jQuery? – Mike Robinson Apr 15 '13 at 17:27
  • Can you use JQuery in your web site/ project ? – InspiredBy Apr 15 '13 at 17:29
  • http://stackoverflow.com/questions/7388626/how-do-i-add-a-class-to-the-html-element-without-jquery – Smern Apr 15 '13 at 17:30
  • 2
    Why do you ask if he can't use jQuery when he already explained why he doesn't want to ? Besides people should only use jQuery when they already know how to make the stuff themselves, or else people remain assisted newbies. – Virus721 Apr 15 '13 at 17:49
  • Virus721, beside the fact that adding a huge library for such a small functionality is overkill, I completely agree with your point. I don't like to use libraries until Im familiar with the programming language itself because I want to be able to write my own code rather than be constricted by tutorials, examples and libraries. – Laurens Apr 15 '13 at 19:02
  • sometime you need to call `object.setAttribute('class',values);` instead of className. same issue i had often while heavy constructions on the DOM or very large DOM trees – Ol Sen Apr 15 '13 at 19:12

4 Answers4

1

This is a slightly modified code running on Firefox (Linux). Please remember that not all browsers (like Chrome etc.) accept the "pure" CSS3 and may need extra CSS code.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="icon" href="favicon1.ico" type="image/x-icon">
<style type="text/css">

    .initial {
        opacity: 0;
    }

    .unvisibleContent {
        opacity: 0;
        /*position: fixed;*/
        width:55%;
        height: 65%;
        top: 10%;
        left: 100%;
        background: #00FF00;
        animation: fadeOutAnimation 1s linear 1;
        animation-iteration-count: 1;
    }

    @keyframes fadeOutAnimation
    {
        from {opacity:1;}
        to {opacity:0;}
    }

    .visibleContent {
         opacity: 1;
        /*position: fixed;*/
        width: 55%;
        height: 65%;
        top:10%;
        left:40%;
        background: #00FF00;
        animation: fadeInAnimation 1s linear 1;
        animation-iteration-count: 1;
    }
    @keyframes fadeInAnimation
    {
        from {opacity:0;}
        to {opacity:1;}
    }
</style>

</head>
<body>
<ul>
    <li><a href="javascript:;" onClick='navClick("page1");'>page 1 button</a></li>
    <li><a href="javascript:;" onClick='navClick("page2");'>page 2 button</a></li>
</ul>
<div id="pages">
    <div id="page1" class="initial">
    <p> page 1 content </p>
    </div>

    <div id="page2" class="initial">
    <p> page 2 content </p>
    </div>
</div>
<script type="text/javascript">
    var page1 = document.getElementById('page1');
    var page2 = document.getElementById('page2');

    var pageArray = new Array();
    pageArray.push(page1);
    pageArray.push(page2);

    function hasClass(element,cls) {
    return element.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
    }

    function addClass(element,cls) {
    element.className += (" "+cls);
    }

    function removeClass(ele) {
    ele.className="";
    }

    function navClick(id) {
    var e = document.getElementById(id);
    for (var i = 0; i < pageArray.length; i++) {
        if (pageArray[i] == e) {
        if (!hasClass(e, 'visibleContent')) {
            removeClass(e);
            addClass(e, 'visibleContent');
        }
        } else
        if (hasClass(pageArray[i], 'visibleContent')) {
            removeClass(pageArray[i]);
            addClass(pageArray[i], 'unvisibleContent');
        }
    }
    }
</script>
</body>
</html>
Michael Besteck
  • 2,415
  • 18
  • 10
  • dont use reserverd keywords `class`. thats it! – Ol Sen Apr 15 '13 at 19:45
  • thanks codelio, Quentin pointed this out to me in the answer below. After changing 'class' to 'cls' it still did not run. Micheal Besteck's code above fixed it. Can anyone clarify how I mark a post as solved? I seem to have forgotten how.. – Laurens Apr 15 '13 at 21:36
0

Check your browser's error console for error messages. You have a syntax error. (The below is copy/pasted from Firebug).

function hasClass(element, class) {
SyntaxError: class is a reserved identifier

This would also have been picked up by JSLint and JSHint.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Since when are there classes in JavaScript ? :/ – Virus721 Apr 15 '13 at 17:55
  • 1
    @Virus721 — There aren't. The keyword was reserved for (presumably) possible future features. – Quentin Apr 15 '13 at 17:55
  • Yeah so they realize, like PHP, that this language is a pure crap and want to try turning it into a classical inheritance/classes language. Can't wait for it. – Virus721 Apr 15 '13 at 17:56
  • thank you, I've changed 'class' to 'cls', but still it does not work. – Laurens Apr 15 '13 at 18:52
  • your lookup mechanism for pageArray is not working, is all time `null`. also hasClass regex could be easier with `cls.test(element.className)`, this will check if cls is inside className and gives back true or false – Ol Sen Apr 15 '13 at 20:23
  • the moment you call for pageArray in your for loop it is empty, so it has no length, better to check for DOM tree entrys short before your main-routine does work and also never check for entrys if the DOM is not ready loaded, thats why @Michael calls it after the html markup – Ol Sen Apr 15 '13 at 20:26
0

If you really want to do it in native javascript you need a better lookup mechanism to find DOM entrys 'page1' and 'page2'.

Here some sweets i made and use often, where loop and pool is going forward and backward thru objects o of elements. Function sel() gives back an Array() of all elements in o with attribute atr and a given value. So you see also how loop and pool work in this function. I wrote this because i needed also some native javascript to speed up and shorten some code i wrote in a larger project.

var dc = document;

function byid() {
    return dc.getElementById(arguments[0]) || null;
}

function byclass() {
    var a = arguments.length == 2 ? arguments[1] : dc.all;
    return sel(a, "class", arguments[0]) || null;
}

function bytag() {
    return dc.getElementsByTagName(arguments[0], arguments[1]) || null;
}

function byname() {
    return dc.getElementsByName(arguments[0])[0] || null;
}

function taglength() {
    return bytag(arguments[0], arguments[1]).length || null;
}

function loop(o, f) {
    var l = o.length;
    for (var i = 0; l > i; i++) f(o[i]);
} //forward


function pool(o, f) {
    var l = o.length;
    for (var i = l; i--;) f(o[i]);
} //backward


function sel(o, atr, val) {
    var r = [];
    var e = 0;
    pool(o, function(o) {
        if (o.getAttribute(atr) === val) {
            r[e++] = o;
        }
    });
    return r;
}
Ol Sen
  • 3,163
  • 2
  • 21
  • 30
  • loop(o=objectlist,f=function to work on each object); pool.. same but goes backward from last to first element in o – Ol Sen Apr 15 '13 at 20:38
-1

If you don't want to use jQuery, you can still use : http://james.padolsey.com/jquery/#v=1.7.2&fn=hasClass I understand that you don't want to include 10k lines of js code only for something that simple, but if you have other javascript stuff in your website, don't hesitate to do it. It's not only cleaner, but also safer as it's certainly well coded, shorter, and readable by anyone who knows jQuery.

Virus721
  • 8,061
  • 12
  • 67
  • 123
  • thank you, but I would really like to have it work by my own code. Its important that I gain an understanding of how to use javascript because I plan to do more web development. Normally I would study up on a new language, but this site needs to be online as soon as possible so thats why Im asking for help. – Laurens Apr 15 '13 at 18:57
  • Actually the best way to learn is by trying to understand the choices made in a well created piece of code, which you can find there. – Virus721 Apr 16 '13 at 07:36