158

I have a drop down navigation menu in which some of the title should not navigate to other page when clicked(these title open a drop down menu when clicked on) while others should navigate (these dont have dropdown and navigate directly).However, both types have href defined to them

To solve this i added the following css for the former type of titles

pointer-events: none;

and it is working fine.But since this property is not supported by IE, i am looking for some work-around. The annoying thing is that i don't have access and privilege to change the HTML and JavaScript code completely.

Any ideas?

Anupam
  • 7,966
  • 3
  • 41
  • 63
  • 2
    Is there a way to gain access to the HTML and scripts? Try talking to whoever gave you the task. – Kyle May 02 '11 at 08:55
  • @Kyle Its not exactly a problem of privilege,there are some technical difficulties also to modify the html/javascript code – Anupam May 02 '11 at 08:57
  • 2
    Here is the answer http://stackoverflow.com/questions/3680429/click-through-a-div-to-underlying-elements – Sanket Sahu May 11 '12 at 08:49
  • http://stackoverflow.com/questions/3680429/click-through-a-div-to-underlying-elements – Sanket Sahu May 11 '12 at 08:50
  • 3
    Note that `pointer-events` is now in IE11+ – David Storey Sep 18 '14 at 07:33
  • @davidstorey - it's actually still not supported in IE11, I'm running some tests on IE9+ and none work, when I try to `getComputedStyle` I get a `visiblePainted`. – Roland Jan 08 '15 at 08:54
  • IE11 won't ever support pointer-events (especially because 11 is/should be its last version). However it supports a pretty easy **workaround** (no need to use _layers_ and/or JavaScript): http://stackoverflow.com/a/10276157/1207195 – Adriano Repetti May 14 '15 at 15:04

12 Answers12

89

Pointer-events is a Mozilla hack and where it has been implemented in Webkit browsers, you can't expect to see it in IE browsers for another million years.

There is however a solution I found:

Forwarding Mouse Events Through Layers

This uses a plugin that uses some not well known/understood properties of Javascript to take the mouse event and send it to another element.

There is also another Javascript solution here.

Update for October 2013: apparently it's coming to IE in v11. Source. Thanks Tim.

Kyle
  • 65,599
  • 28
  • 144
  • 152
  • 4
    Documentation of ie9 says it supports this property(i've not tried ie9 yet however).Anyway, i already had ideas in my mind which are given in the links but as i was looking for some css specific solution i cannot use them. I will try to modify the html/js code rather spending time on this problem.Thanks a lot for your time and help – Anupam May 02 '11 at 09:16
  • The page was down when I checked, but here's some code the author wrote for the ext.js library that accomplishes the same: http://code.google.com/p/ext-ux-datadrop/source/browse/trunk/src/Override.js – Sophie Alpert Sep 30 '11 at 15:39
  • While this workaround will forward the event, it will not forward the actual click. For example, an input field will fire a focus event without gaining focus. A button will fire a click event but not be clicked, etc... – user123444555621 Jan 23 '12 at 23:43
  • 11
    At W3C, this issue went [under debate due to click-hijacking](http://lists.w3.org/Archives/Public/www-style/2011Aug/0176.html). Rule of thumb: as soon as W3C publish the candidate recommendation, IE team will implement it & there's always a lesson in [haste makes waste](http://bit.ly/OifiM4). Besides, Mozilla [said it all](https://developer.mozilla.org/en-US/docs/CSS/pointer-events) "**Warning:** *The use of pointer-events in CSS for non-SVG elements is experimental. The feature used to be part of the CSS3 UI draft specification but, due to many open issues, has been postponed to CSS4.*" – vulcan raven Sep 28 '12 at 07:40
  • 8
    According to caniuse.com, CSS pointer events are coming to IE 11. http://caniuse.com/#feat=pointer-events – Tim Oct 03 '13 at 22:01
  • 1
    I made a simpler js version (not using css pointer events) - getting the element by using elementFromPoint http://jsfiddle.net/3NDaL/3/ - hope it will help – Marc Uberstein Dec 03 '13 at 10:00
  • yeah, you are right. i'll upvote this as soon as you edit your answer but i've managed to find a css-only solution for this problem. – eyurdakul Mar 25 '14 at 16:26
  • 14
    `"you can't expect to see it in IE browsers for another million years."` Took only 3 years... – ProblemsOfSumit Jun 17 '14 at 08:07
  • 1
    @eyurdakul why don't you share your solution then..? – ProblemsOfSumit Jun 17 '14 at 08:08
  • 1
    @Sumit: I guess I vastly underestimated Microsoft on this one. – Kyle Jun 17 '14 at 08:54
  • 2
    @KyleSevenoaks i guess everyone underestimated Microsoft. Current IE development is awesome, especially status.modern.ie. They only need to kill IE8 and 9 ASAP and we're good to go into sweet heaven of modern development! – ProblemsOfSumit Jun 17 '14 at 13:42
  • @KyleSevenoaks "you can't expect to see it in IE browsers for another million years." - IE 11 has it – Szymon Toda Sep 04 '14 at 08:16
  • 2
    Yes, yes we've covered this ground. This answer was constructed during the time when Microsoft were considered to be less than stellar at browser building. Times have changed, but the answer remains. – Kyle Sep 05 '14 at 06:38
20

Here is another solution that is very easy to implement with 5 lines of code:

  1. Capture the 'mousedown' event for the top element (the element you want to turn off pointer events).
  2. In the 'mousedown' hide the top element.
  3. Use 'document.elementFromPoint()' to get the underlying element.
  4. Unhide the top element.
  5. Execute the desired event for the underlying element.

Example:

//This is an IE fix because pointer-events does not work in IE
$(document).on('mousedown', '.TopElement', function (e) {

    $(this).hide();
    var BottomElement = document.elementFromPoint(e.clientX, e.clientY);
    $(this).show();
    $(BottomElement).mousedown(); //Manually fire the event for desired underlying element

    return false;

});
MarzSocks
  • 4,229
  • 3
  • 22
  • 35
  • 2
    This worked for me. I prefer small fixes that I can put into my js code instead adding a lot of polyfills ;) – dippas Dec 11 '14 at 11:48
  • This is a creative solution, I like it. The only problem is this adds unnecessary processing to browsers where the point-events _do_ work. It would be great to make this execute conditionally IE browsers only. – Trevor Jan 16 '15 at 19:04
  • I agree, its a quickly implementable to a perplexing issue, but in fact in my implementation of it, I only apply it if the browser is IE, you place it inside this check: if (navigator.appName == 'Microsoft Internet Explorer') { ... logic goes here .. } – MarzSocks Jan 17 '15 at 06:56
  • 3
    this works very well! since ie 11 supposedly started supporting pointer-events, I just wrap it inside this clause: if (navigator.userAgent.toLowerCase().indexOf('msie') > 0) THANKS! – Hank Aug 21 '15 at 16:40
17

There's a workaround for IE - use inline SVG and set pointer-events="none" in SVG. See my answer in How to make Internet Explorer emulate pointer-events:none?

Community
  • 1
  • 1
obiuquido144
  • 623
  • 7
  • 9
11

It's worth mentioning that specifically for IE, disabled=disabled works for anchor tags:

<a href="contact.html" onclick="unleashTheDragon();" disabled="disabled">Contact</a>

IE treats this as an disabled element and does not trigger click event. However, disabled is not a valid attribute on an anchor tag. Hence this won't work in other browsers. For them pointer-events:none is required in the styling.

UPDATE 1: So adding following rule feels like a cross-browser solution to me

UPDATE 2: For further compatibility, because IE will not form styles for anchor tags with disabled='disabled', so they will still look active. Thus, a:hover{} rule and styling is a good idea:

a[disabled="disabled"] {
        pointer-events: none; /* this is enough for non-IE browsers */
        color: darkgrey;      /* IE */
    }
        /* IE - disable hover effects */   
        a[disabled="disabled"]:hover {
            cursor:default;
            color: darkgrey;
            text-decoration:none;
        }

Working on Chrome, IE11, and IE8.
Of course, above CSS assumes anchor tags are rendered with disabled="disabled"

DonD
  • 339
  • 3
  • 17
Niks
  • 4,802
  • 4
  • 36
  • 55
6

Here's a small script implementing this feature (inspired by the Shea Frederick blog article that Kyle mentions):

Kent Mewhort
  • 1,158
  • 12
  • 11
4

I spent almost two days on finding the solution for this problem and I found this at last.

This uses javascript and jquery.

(GitHub) pointer_events_polyfill

This could use a javascript plug-in to be downloaded/copied. Just copy/download the codes from that site and save it as pointer_events_polyfill.js. Include that javascript to your site.

<script src="JS/pointer_events_polyfill.js></script>

Add this jquery scripts to your site

$(document).ready(function(){
    PointerEventsPolyfill.initialize({});
});

And don't forget to include your jquery plug-in.

It works! I can click elements under the transparent element. I'm using IE 10. I hope this can also work in IE 9 and below.

EDIT: Using this solution does not work when you click the textboxes below the transparent element. To solve this problem, I use focus when the user clicks on the textbox.

Javascript:

document.getElementById("theTextbox").focus();

JQuery:

$("#theTextbox").focus();

This lets you type the text into the textbox.

Mai
  • 363
  • 3
  • 16
4

Cover the offending elements with an invisible block, using a pseudo element: :before or :after

a:before {
//IE No click hack by covering the element.
  display:block;
  position:absolute;
  height:100%;
  width:100%;
  content:' ';
}

Thus you're click lands on the parent element. No good, if the parent is clickable, but works well otherwise.

Graham P Heath
  • 7,009
  • 3
  • 31
  • 45
  • 1
    I used a similar idea with the disabled attribute. In IE adding the disabled attribute prevents click events, but if there are children they will still trigger the click. covering the children so they are not clickable is a great solution to this. I had to use a background color with opacity 0 to have IE register there was an actual element there. – Blake Plumb Apr 27 '15 at 22:54
1

I've found another solution to solve this problem. I use jQuery to set the href-attribute to javascript:; (not ' ', or the browser will reload the page) if the browser window width is greater than 1'000px. You need to add an ID to your link. Here's what I'm doing:

// get current browser width
var width = $(window).width();
if (width >= 1001) {

    // refer link to nothing
    $("a#linkID").attr('href', 'javascript:;'); 
}

Maybe it's useful for you.

yves.beutler
  • 972
  • 1
  • 14
  • 32
0

Use OnClientClick = "return false;"

Thomas G
  • 9,886
  • 7
  • 28
  • 41
Medde
  • 11
  • 1
0

You can also just "not" add a url inside the <a> tag, i do this for menus that are <a> tag driven with drop downs as well. If there is not drop down then i add the url but if there are drop downs with a <ul> <li> list i just remove it.

Tasos K.
  • 7,979
  • 7
  • 39
  • 63
0

I faced similar issues:

  1. I faced this issue in a directive, i fixed it adding a as its parent element and making pointer-events:none for that

  2. The above fix did not work for select tag, then i added cursor:text (which was what i wanted) and it worked for me

If a normal cursor is needed you could add cursor:default

Z.T
  • 485
  • 1
  • 5
  • 8
-2

Best solution:

.disabled{filter: alpha(opacity=50);opacity: 0.5;z-index: 1;pointer-events: none;}

Runs perfectly on all browsers