views:

108

answers:

5

Searching for a script, which can do show/hide functions without framework.

Something like:

<span rel="toggle" href="/somelink.html">Title</span>
<div class="toggle">Hidden block</div>

.toggle { display: none; }

Block .toggle should be displayed after clicking on span. Like toggle() on jQuery.

Thanks.

A: 

I would create two methods that add/remove toggle class with native JavaScript:

function show(element) {
    element.className += " toggle";
}

function hide(element) {
    element.className = (element.className).replace(/\s*toggle/g, "");
}

You will need code that places the onclick event on the span. Are you familiar with that?

Jason McCreary
Maybe, `/\s*toggle/g` in case there is no leading space and replace it with a space character?
tvanfosson
inline javascript is not allowed
Happy
@tvanfosson, this should not happen if you reliably use the `show`/`hide`. Nonetheless, I have updated the code as it is still a good idea. @Happy, it is not inline. Put this with your other JavaScript.
Jason McCreary
+2  A: 

look here to create a getElementByClass function - http://www.dustindiaz.com/getelementsbyclass/

then something like this (haven't checked if it works, but you get the idea):

toggleItem = function(){
  var item = getElementByClass('toggle')[0];
  if (item.style.display == "block")
  {
    item.style.display = 'none';
  }
  else
  {
    item.style.display = 'block';
  }
}
programatique
What about onclick event for <span>?
Happy
With the above example, just use `<span onclick="toggleItem();">`
casablanca
display inline?
galambalazs
any way to not use inline javascript?
Happy
http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html this shows you a few functions to attach/detach eventhandlers cross-browser. attach the events when the page is loaded and you can avoid inline js.
programatique
A: 

This uses an id on the hidden block to figure out which div to toggle. This is with the assumption that you want to toggle one block per clickable span. The event listener method is a W3C standard, but I'm not sure if IE implements it - do some testing to be sure.

HTML:

<!-- the rel attribute in the span specifies which div to toggle -->
<span rel="target" id="trigger">Title</span>

<div id="target">Hidden block</div>

JavaScript, goes in a script block in your HEAD or in a separate .js file:

window.addEventListener('load', init, false);

function init() {
    document.getElementById('trigger').addEventListener(
        'click',
        function() {
            targetId = this.getAttribute('rel');
            var element = document.getElementById(targetId);
            if (element.style.display == 'block')
                element.style.display = 'none';
            else
                element.style.display = 'block';
        },
        false
    );
}

There, no JS in your HTML.

Jeff
BTW, if you have multiple clickable spans, you could assign each span a class like "trigger". Then in the init() function, put the event listener registration in a loop that attaches the listener to everything that has a "trigger" class.
Jeff
looks good, but doesn't work for me.
Happy
I'm sorry but css display can have much more values, than just 2: http://www.w3schools.com/css/pr_class_display.asp
galambalazs
and it doesn't work in IE... :) bamm semantic...
galambalazs
Of course it doesn't work in IE... sigh. Happy, if you look at the jQuery source code, you'll probably find the code you need to accomplish your goal. If I recall, they had to put in some ugly hackish code to get this sort of thing working in IE. Frankly, you should just use inline JS or use a library like jQuery, which will let you do this without inline JS because they've taken care of doing all the, well, ugly hackish IE compatibility code for you.
Jeff
A: 

See it in action.

HTML

<span rel="hidden" href="/somelink.html" onclick="toggle(this)">Title</span>
<div class="toggle" id="hidden">Hidden block</div>

Javascript

function toggle(el) {
  if (!el.getAttribute("rel")) return;
  el = document.getElementById( el.getAttribute("rel"));
  var cname = " " + el.className + " ";
  if (cname.indexOf("toggle") !== -1) {
    cname = cname.replace(" toggle ", " ");
    el.className = cname.substring(1, cname.length-1);
  } else {
    el.className += " toggle";
  }
}
galambalazs
thanks, but inline javascript is not valid
Happy
Really? Have you read the specification? http://www.w3.org/TR/REC-html40/interact/scripts.html
galambalazs
A: 

First, there's a function that will create a unique toggle function for whatever element you give it. Then, we wait for the window to load, and when it does, we create some toggle functions. In this example, we assume you have an element with id='some_id', but you can use whatever you need to get an element. Then, we stick the toggle function into a global variable.

// returns a function that will toggle the given element
function makeToggleFunction(el) {
        var element = el;
        return function() {
                if (element.style.display == 'none')
                        element.style.display = 'block';        
                else
                        element.style.display = 'none';

        };
}

window.addEventListener('load', on_window_load, false);
var GLOBAL = {};
function on_window_load() {
        GLOBAL.toggle_element = makeToggleFunction(document.getElementById('some_id'));
}

You can then toggle the element whenever you need, with GLOBAL.toggle_element().

Also, I think this is the code for IE if you want to wait for the page to load.

document.addEventListener("DOMContentLoaded", on_window_load, false);

EDIT:

Add this function (from http://www.dustindiaz.com/getelementsbyclass/ as mentioed by programatique)


function getElementsByClass(searchClass,node,tag) {
        var classElements = new Array();
        if ( node == null )
                node = document;
        if ( tag == null )
                tag = '*';
        var els = node.getElementsByTagName(tag);
        var elsLen = els.length;
        var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
        for (i = 0, j = 0; i < elsLen; i++) {
                if ( pattern.test(els[i].className) ) {
                        classElements[j] = els[i];
                        j++;
                }
        }
        return classElements;
}

And then add the following inside the function on_window_load:

GLOBAL.toggleable = new Array();
or each(var element in getElementsByClass('toggle')) {
        GLOBAL.toggleable.push(makeToggleFunction(element));
}
GLOBAL.toggle_all = function() {
        for each(var f in GLOBAL.toggleable) {
                f.call();
        }
};  

And now you can call GLOBAL.toggle_all() and it will hide all elements that have the class toggle.

Steve