-1

EDIT: solved: IDs can't start with a digit.


Here's what's it about -->

I made a div with tabs above it (2009 - 2013). In the div where the content should show up, I wrote just the year to indicate if my code works.

If I write $('div#updates div.content div').hide();, all the content hides (just as it should), but if I write $('div#updates div.content div#2009').show();, nothing happens. Does anyone know why (I supposed wrong selector, but I checked that and it didn't work.

HTML:

<div id="updates">
<div class="tabs">
    <div id="2009">2009</div>
    <div id="2010">2010</div>
    <div id="2011">2011</div>
    <div id="2012">2012</div>
    <div id="2013">2013</div>
</div><br />
<div class="content">
    <div id="2009">
        2009
    </div>
    <div id="2010">
        2010
    </div>
    <div id="2011">
        2011
    </div>
    <div id="2012">
        2012
    </div>
    <div id="2013" class="active">
        2013
    </div>
</div>

JS (jQuery):

        $(document).ready(function(e) {
            $('div#updates div.tabs div#2013').addClass("active");

            $('div#updates div.tabs div').click(function(e) {
                $('div#updates div.tabs div').removeClass("active");
                $(this).addClass("active");
                $('div#updates div.content div').hide();
            });

            $('div#updates div.tabs div#2009').click(function(e) {
                $('div#updates div.content div#2009').show();
            });
            $('div#updates div.tabs div#2010').click(function(e) {
                $('div#updates div.content div#2010').show();
            });
            $('div#updates div.tabs div#2011').click(function(e) {
                $('div#updates div.content div#2011').show();
            });
            $('div#updates div.tabs div#2012').click(function(e) {
                $('div#updates div.content div#2012').show();
            });
            $('div#updates div.tabs div#2013').click(function(e) {
                $('div#updates div.content div#2013').show();
            });
    });

css:

        div#updates div.tabs div{
        float: left;
        padding: 5px 10px 4px 10px;
        background-color: #a90000;
        border: 1px solid #600;
        z-index: inherit;
        position: relative;
        margin-right: -1px;
        cursor: default;
    }
    div#updates div.tabs div.active{
        background-color: #f00;
        border-bottom: none;
        padding-bottom: 5px;
        z-index: 10;
    }
    div#updates div.content{
        background-color: #f00;
        position: absolute;
        top: 38px;
        width:500px;
        border: 1px solid #600;
        padding: 10px;
        z-index: 9;
    }
    div#updates div.content div{
        display: none;
    }
    div#updates div.content div.active{
        display: block;
    }
    /*opmaak berichten*/
    div#updates div.content div h3{
        color: #0f0;
        font: 24px Impact , sans-serif;
        text-decoration: none;
    }
Axel Köhler
  • 911
  • 1
  • 8
  • 34

6 Answers6

5

Your selectors are invalid. Even though id values starting with a digit are valid in HTML, they are not valid in CSS. Put an x in front of them or something to make them valid, e.g.

<div id="1">...</div>

becomes

<div id="x1">...</div>

so the selector #x1 can be used (which is valid).

Additionally, as Arun points out in his answer, you have used the same id value on more than one element. That's also invalid. id means "identifier," and identifiers are unique (that's the whole point). The behavior of the selector engine when you have the same id value on more than one element is undefined (because it's invalid), but usually the browser uses the first element in the document with that id.

I think you may have wanted this:

<div id="updates">
<div class="tabs">
    <div data-id="year2009">2009</div>
    <div data-id="year2010">2010</div>
    <div data-id="year2011">2011</div>
    <div data-id="year2012">2012</div>
    <div data-id="year2013">2013</div>
</div><br />
<div class="content">
    <div id="year2009">
        2009
    </div>
    <div id="year2010">
        2010
    </div>
    <div id="year2011">
        2011
    </div>
    <div id="year2012">
        2012
    </div>
    <div id="year2013" class="active">
        2013
    </div>
</div>

With this:

$(".tabs").on("click", "> div", function() {
    $(".active").removeClass("active");
    $("#" + this.getAttribute("data-id")).addClass("active");
});

What I changed:

  1. I removed the id values from the divs within .tabs and used data-id to indicate which div they should activate.

  2. I made the id values valid.

  3. I had the code respond to clicks on the .tabs element, but only if the click was on one of its div children (delegated handling).

  4. Use the data-id attribute to make the relevant div active.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • but the [spec for class](http://www.w3.org/TR/2011/WD-html5-20110525/elements.html#classes) does not say that, it just says `must have a value that is a set of [space-separated tokens](http://www.w3.org/TR/2011/WD-html5-20110525/common-microsyntaxes.html#set-of-space-separated-tokens) representing the various classes that the element belongs to`. so if a class name is not used as a css selector then it should be fine right – Arun P Johny Jul 16 '13 at 12:22
  • so which of these two spec is valid in this case? :( – Arun P Johny Jul 16 '13 at 12:23
  • @ArunPJohny: It's another case of context, just like `id`. It's fine to use `id` values starting with digits in HTML as long as you're not trying to use them with CSS. Similarly, it's fine to use class names starting with digits in HTML...as long as you don't use them with CSS. :-) The CSS rules apply if you're going to apply styling to those `id`s or classes, or look up elements using CSS selectors via jQuery or `querySelector` or similar. The CSS spec is quite clear: *"In CSS, identifiers (including element names, classes, and IDs in selectors)...cannot start with a digit..."* – T.J. Crowder Jul 16 '13 at 13:02
  • @ArunPJohny: I did wonder if maybe you could escape the `id` or selector with a backslash, because the spec goes on to say *"... Identifiers can also contain escaped characters...For instance, the identifier "B&W?" may be written as "B\&W\?" or "B\26 W\3F"."* But Chrome, at least, rejects `querySelector("#\\123")` and `querySelector(".\\456")`. :-) – T.J. Crowder Jul 16 '13 at 13:04
2

according to the spec, IDs in HTML4 have to begin with a letter. Numeric IDs are ok in HTML5, but they still aren't in CSS. most likely that causes your problems.

What are valid values for the id attribute in HTML?

Community
  • 1
  • 1
oezi
  • 51,017
  • 10
  • 98
  • 115
0

The id should not start with a number, that's correct. Only works in Internet Explorer.

Theo
  • 150
  • 11
0

I would simplify your JS like this (and you can get rid of ID's):

$(function(e) {
    $(".tabs div").click(function(){
        var _index = $(this).index();

        $(".tabs div").removeClass("active");
        $(".tabs div:eq("+_index+")").addClass("active");

        $(".content div").hide();
        $(".content div:eq("+_index+")").show();
    });
});
NXT
  • 1,981
  • 1
  • 24
  • 30
  • I woud like to, but since I'm not that far with learning JS, it would just make things to complicate, but thanx for your answer anyway. When I'm done programming the website I did this for, I'll have a better look at it. – Axel Köhler Jul 16 '13 at 12:14
  • and `$('.tabs div:eq(4)').addClass("active");` to initially set `active` class to the last tab. – palaѕн Jul 16 '13 at 12:16
0

Hi when using they should be unique and then you can link to them directly without telling about the parents. Direct link to the ID is the fastest way.

The jQuery:

$(document).ready(function(e) {
        $('#a2013').addClass("active");
        $('#b2013').show();
        $('div#updates div.tabs div').click(function(e) {
            $('div#updates div.tabs div').removeClass("active");
            $(this).addClass("active");
            $('div#updates div.content div').hide();
        });

        $('#a2009').click(function(e) {
            $('#b2009').show();
        });
        $('#a2010').click(function(e) {
            $('#b2010').show();
        });
        $('#a2011').click(function(e) {
            $('#b2011').show();
        });
        $('#a2012').click(function(e) {
            $('#b2012').show();
        });
        $('#a2013').click(function(e) {
            $('#b2013').show();
        });
});

And the html:

  <div id="updates">
    <div class="tabs">
        <div id="a2009">2009</div>
        <div id="a2010">2010</div>
        <div id="a2011">2011</div>
        <div id="a2012">2012</div>
        <div id="a2013">2013</div>
    </div><br />
    <div class="content">
        <div id="b2009">
            2009
        </div>
        <div id="b2010">
            2010
        </div>
        <div id="b2011">
            2011
        </div>
        <div id="b2012">
            2012
        </div>
        <div id="b2013">
            2013
        </div>
    </div>
  </div>
Lundeman
  • 51
  • 2
  • I know, but this was an example which I have to put in a large website I'm working on later, so id might not be unique anymore, but thanx for your response. – Axel Köhler Jul 16 '13 at 12:30
0

To fix this problem you have to follow 2 steps:

  1. As my friend has said, you have to change the ID as it is invalid in CSS but valid in HTML5 (integer values for CSS simply does not work and jQuery uses CSS)

  2. The purpose of IDs are to make it unique and identify it between all of the elements without typing the full path. You should use something like this

$('#x2009').show();
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Jamil Hneini
  • 545
  • 3
  • 13
  • As soon as I finish the final website, I'll look for ids I could clean up. Thanx for your response. – Axel Köhler Jul 16 '13 at 12:42
  • @Jamil Please Do Not Use Capital Letters In The Middle Of Sentences Since It Reads Very Poorly!!! - I have fixed it for you – mplungjan Jul 16 '13 at 13:01