17

The issue is with Internet Explorer 8 and below. Have found a decent working solution.

Issue

Internet Explorer 8 and below is not triggering click() event set by jQuery (or even may be inline, not sure) on <input /> elements, which have CSS property, display set to none. It works in Internet Explorer 9, Mozilla Firefox, and Google Chrome. Weird. This is how the code is and is there any work-around for Internet Explorer 8 and below?

Context

The input to be clicked is given a style display: none;. And the function is given in the click event of the input. Since the whole stuff is inside the label, it triggers the click event on the input when the label clicked. You can take this as some kind of pretty selector, hiding the input.

The label implicitly transfers the click event to the first input by default, and that is what I wanna use it here. I don't want the users to see the ugly input here. Expected browser behaviour, but not working.

HTML

<ul>
    <li>
        <label>
            <input type="button" value="Button 1" />
            Hello! This is a list item #1.
        </label>
    </li>
    <li>
        <label>
            <input type="button" value="Button 2" />
            Hello! This is a list item #2.
        </label>
    </li>
    <li>
        <label>
            <input type="button" value="Button 3" />
            Hello! This is a list item #3.
        </label>
    </li>
</ul>​

The Exact CSS which caused the Issue

ul li,
ul li label {display: block; padding: 5px; cursor: pointer;}
ul li label input {display: none;}
ul li {border-bottom: 1px solid #ccc;}
ul li:hover {background-color: #eee;}​

JavaScript

$(document).ready(function(){
    $("input").click(function(){
        alert("Hey you! " + $(this).attr("value"));
    });
});​

Fiddle: http://jsfiddle.net/qSYuP/


Update #1: Tried giving for attribute:

<label for="btn1">
    <input type="button" value="Button 1" id="btn1" />

Still doesn't work!


Update #2: Tried CSS visibility: hidden;:

ul li label input {visibility: hidden;}

Breaks layout. But, still doesn't work!


Update #3: Tried CSS position: absolute;:

ul li label {overflow: hidden;}
ul li label input {position: absolute; left: -99em;}

Works! I am not in a position to use overflow: hidden;, seriously caught!


Update #4: Manually triggering the click() function:

$(document).ready(function(){
    $("input").click(function(){
        console.log("Hey you! " + $(this).attr("value"));
    });
    $("label").click(function(){
        $(this).find("input").click();
    });
});

Well, IE 8 goes out of stack after printing LOG: Hey you! Button 3 for 1209 times!

LOG: Hey you! Button 3 
LOG: Hey you! Button 3 
LOG: Hey you! Button 3 
LOG: Hey you! Button 3 
LOG: Hey you! Button 3 
SCRIPT28: Out of stack space 

Works Infinitely! Should be an issue with my script!


Solution: Kind of crappy fix, but did the trick!

Since it is because IE 8, which supports opacity, I had to use display: inline-block; with opacity: 0;.

ul li label input {
    opacity: 0;
    width: 0px;
    height: 0px;
    display: inline-block;
    padding: 0;
    margin: 0;
    border: 0;
}

Now the input's box is hidden, literally. This fix is only for IE 8!

Had to fix using the IE 8 and below Hack:

ul li label input {
    opacity: 0\9;
    width: 0px\9;
    height: 0px\9;
    display: inline-block\9;
    padding: 0\9;
    margin: 0\9;
    border: 0\9;
}

Fiddle: http://jsfiddle.net/VSQbD/

Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252

6 Answers6

6

I think this is pretty straightforward. You just have to use click handlers on visible items. If you want a click on the <label> or the <li> to work when the <input> object is hidden and you want it to work in all browsers, then you just need to put a click handler on either the <label> or the <li> because that is a visible object that will receive the click when the <input> is hidden.

ahren
  • 16,803
  • 5
  • 50
  • 70
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 2
    The `label` implicitly transfers the `click` event to the first `input` by default, and that is what I wanna use it here. I don't want the users to see the ugly `input` here. Expected browser behaviour, but not working. The thing is, it works in all the standard browsers! – Praveen Kumar Purushothaman Dec 10 '12 at 07:45
  • 6
    *Expected browser behaviour* isn't something that really exists in web development... – ahren Dec 10 '12 at 07:47
  • @PraveenKumar - are you expecting some magic incantation that will give features to IE8 that it doesn't have. The work-around is to attach a click handler to a visible object. You can keep the `` item hidden, but you need a click handler on a visible item if you want code to act on the click. – jfriend00 Dec 10 '12 at 07:47
  • The idea is to trigger the click event on the `input`. :) – Praveen Kumar Purushothaman Dec 10 '12 at 07:48
  • 2
    @PraveenKumar - guess what! IE8 doesn't do give the click event to the hidden `` item so stop asking for it to do that - it doesn't. You need to code around that by having a click handler on a visible item and then triggering the same code that you have for click handlers on the `` item. This is how you solve interoperability issues in older browsers. – jfriend00 Dec 10 '12 at 07:49
  • `+1` Grrr.. Stupid IE! I know... No other way? – Praveen Kumar Purushothaman Dec 10 '12 at 07:50
  • 3
    @ahren - love your comment about "expected browser behavior"! – jfriend00 Dec 10 '12 at 07:51
  • @ahren Yeah, me too. Nice explanation. Web developers enter hell when trying for cross browser compatibility. `:(` – Praveen Kumar Purushothaman Dec 10 '12 at 08:06
  • @jfriend00 Consider this. Having a `form` submission with the value of the `input type="radio"`, and I need something like pretty forms. That time, what I do is, I just use a toggle class of `selected` and when selected is there, an inline hidden tick image is shown inline. Got my point? – Praveen Kumar Purushothaman Dec 10 '12 at 08:31
  • @PraveenKumar - I have no idea what your last comment means. – jfriend00 Dec 10 '12 at 08:34
  • Anyways, added `+1` for your explanation. Will explain you in detail in a fiddle. Give me some time. `:)` – Praveen Kumar Purushothaman Dec 10 '12 at 08:47
5

Kind of crappy fix, but did the trick!

Since it is because IE 8, which supports opacity, I had to use display: inline-block; with opacity: 0;.

ul li label input {
    opacity: 0;
    width: 0px;
    height: 0px;
    display: inline-block;
    padding: 0;
    margin: 0;
    border: 0;
}

Now the input's box is hidden, literally. This fix is only for IE 8!

Tried using the IE 8 Hack:

ul li label input {
    opacity: 0\9;
    width: 0px\9;
    height: 0px\9;
    display: inline-block\9;
    padding: 0\9;
    margin: 0\9;
    border: 0\9;
}
Community
  • 1
  • 1
Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
1

Could you not position the element absolute, but set it's left property to something like -99999px?

TommyBs
  • 9,354
  • 4
  • 34
  • 65
0

different browsers interpret display:none differently. display:none actually means the element should disappear, making the jquery difficult to find in the DOM.

a better way is to use visibility:hidden and then use click method

saad arshad
  • 259
  • 1
  • 10
0

Your code is pretty much incorrect..

  • input inside label ?
  • Events are suppose to bubble up and not downwards
  • and its so simple.. if you want to know when li was clicked attach an handler to that and not to input

in your updated 4 you could do an event.stopPropagation for 'input` click and that would solve infinity problem

Gaurav Shah
  • 5,223
  • 7
  • 43
  • 71
  • Ah, thanks for the solution of solving the infinity thing. `input` inside the `label` is **the** right way. See http://stackoverflow.com/questions/774054/should-i-put-input-tag-inside-label-tag :) – Praveen Kumar Purushothaman Dec 10 '12 at 09:45
  • 1
    though valid just doesn't sound right to most of the people even at that page. Didn't know its valid . thanks – Gaurav Shah Dec 10 '12 at 11:36
0

Never been hit by this as I do things slightly differently anyway - click on the label does input.checked = !input.checked; return false;, then have a "change" event on the input (rather than a click event).

Rycochet
  • 2,860
  • 1
  • 22
  • 39