Scrungepipes
Scrungepipes

Reputation: 37581

How does one make the whole of a list item clickable?

I have a list containing list items which appear like a row in a table (actually it mimics the table view on iPhone) and want to make each row of the list selectable, so I can change its color when the user clicks on it and also add a listener to perform some event.

   <ul>
   <li>
    <img id = "image" src="image.jpg" />
    <h1 id = "Title">Title</h1>
        etc.
    </li>

I tried adding a href attribute of # to the <li> but that didn't work. I also tried this:

      <ul>
       <li>
        <a  href="#" onclick="action();">
        <img id = "image" src="image.jpg" />
        <h1 id = "Title">Title</h1>
            etc.
        </li>

But that turns each individual item within the list item into a clickable link, how can I turn each list item into something that is clickable as a whole?

Upvotes: 0

Views: 5755

Answers (3)

Pebbl
Pebbl

Reputation: 35995

Pure JavaScript

The first answer specifically relies on jQuery, which I'd recommend using, as it's drastically cuts down the amount of browser-targetted JavaScript you have to write (for mobile you can use jQuery mobile). However as you do not state jQuery in your question here is the best way to do it in pure JavaScript (avoiding inline event handlers):

<script type="text/javascript">
  /// wrap all our code in our own scope so to keep things local
  (function(){
    /// store any previous handler on the window.onload
    var previousOnload = window.onload;
    /// create our ready function
    var fullyLoaded = function(){
      /// grab the UL element
      var li, ul = document.getElementById('target_ul');
      /// grab the LI elements
      var lis = ul.getElementsByTagName('li'), i = lis.length;
      /// loop each LI and apply a click handler
      while( i-- ){
        if ( !(li = lis[i]) ){ continue };
        /// internet explorer version
        if ( li.attachEvent ) {
          li.attachEvent('onclick', clickEvent);
        }
        /// pretty much everything else
        else if ( li.addEventListener ) {
          li.addEventListener('click', clickEvent);
        }
      }
    }
    /// create our click event listener
    var clickEvent = function( e ){
      /// fallback support for IE events
      if ( !e ){ e = window.Event };
      /// fallback support for IE .srcElement
      alert( 'Clicked! ' + ( e.target ? e.target : e.srcElement ) );
    }
    /// override/set the window.onload with our own listener for window load
    window.onload = function(){
      /// trigger the our onload function
      fullyLoaded();
      /// once we've triggered our code 'onload', fire anyone elses.
      if ( previousOnload ) {
        previousOnload();
      }
    }
  })();
</script>
<ul id="target_ul">
  <li>test</li>
  <li>test2</li>
</ul>

Inline event handlers

Obviously the easier method is just to place the onclick on the LI element, however inline event listeners should be avoided for numerous reasons:

  1. You should always strive to keep your design/markup seperate from your code - this helps future-proof your work and means that the markup can be edited without fear of breaking the script.

  2. You can only apply one function per inline event listener - this means it becomes much more difficult to run your code alongside other plugins or libraries that might operate on the same elements... or to even extend your code with extra interactional features.

  3. There are numerous situations where memory leaks can occur due to javascript methods being bound by way of inline event listeners. (on mobiles memory usage can be a big thing to watch out for, especially if your page is to be loaded many times or have many inline event listeners).

  4. Inline event listeners need to access global functions, which means all of your event functions have to be part of the global scope which pollutes the global namespace (more chance of naming collisions with other code), this also often leads to quite awkward code to manage.

Conclusion

The sheer complication of having to implement the long winded pure JavaScript above is exactly the reason why I recommend using jQuery mobile ;) although it does take all the fun out of it.

Upvotes: 1

The Alpha
The Alpha

Reputation: 146191

You can also try this (Plain javascript)

window.onload=function(){
    var lis=document.getElementById('target_ul').getElementsByTagName('li');
    for(i=0;i<lis.length;i++) { 
        lis[i].onclick=myFunction;
    }
}

function myFunction()
{
    alert('This list item contains "'+this.innerHTML+'"');
}

DEMO.

Upvotes: 1

Fraser
Fraser

Reputation: 14244

You can do this with jQuery:

$('ul li').click(function(){
   .......
})

Upvotes: 0

Related Questions