5

My issue is that i have this box aka container. Inside that container there are boxes that the user can click.

To visually help the user I made overlay boxes with a gray faded out color that tells them they can use the boxes here.

But my issue is that the click event is on the boxes behind the overlay box.

So is there any way of ignoring a element's .click() and use next target?

enter image description here

Zoltan Toth
  • 46,981
  • 12
  • 120
  • 134
danniehansenweb
  • 465
  • 4
  • 14
  • 1
    Can't you just use selectors to target the little boxes? – Cranio Aug 11 '12 at 10:59
  • I'm not understanding the need for your overlay boxes when you could assign a 'disabled' class to the actual box to style it as a disabled element. That way your click function would be unimpeded. – David Barker Aug 11 '12 at 11:05

3 Answers3

8

You can use the CSS pointer-events property:

The CSS property pointer-events allows authors to control under what circumstances (if any) a particular graphic element can become the target of mouse events.

#element {
  pointer-events: none;
}

Or you can trigger the click event:

$('#box').click(function(){
   $('#target').trigger('click')
})
Ram
  • 143,282
  • 16
  • 168
  • 197
  • 3
    Caution! I think you will find that that `pointer-events` is not supported in IE - [see](http://stackoverflow.com/questions/5855135/css-pointer-events-property-alternative-for-ie) here for example. – Beetroot-Beetroot Aug 11 '12 at 11:23
  • @Beetroot-Beetroot yes, ie8 doesn't support `pointer-events` property. – Ram Aug 11 '12 at 12:34
  • Second post [here](http://social.msdn.microsoft.com/Forums/pl-PL/winappswithhtml5/thread/9f2d8727-ec9d-4f68-b4a0-bb50dbd86663) suggests that `pointer-events` is currently unreliable for all non-SVG elements, even in moz browsers. I, for one, can't see myself using it any time soon except maybe for SVG work. – Beetroot-Beetroot Aug 11 '12 at 12:49
1

Avoiding CSS pointer-events ...

Firstly, make sure the contained boxes all have the class name box (or similar).

Secondly, make boxes inactive with .addClass('inactive'), (with corresponding CSS directives in the stylesheet to look after the background color and border). To re-activate boxes, simply .removeClass('inactive').

Thirdly, delegate the handling of clicks on boxes to the container as follows:

$('#container').on('click', '.box', function() {
    //common behaviour (pre)
    if($(this).hasClass("inactive")) {
        //inactive box behaviour
    }
    else {
        //active box behaviour
    }
    //common behaviour (post)
});
Beetroot-Beetroot
  • 18,022
  • 3
  • 37
  • 44
  • The issue i was having is that I'm using the fullcalendar plugin for JavaScript(jQuery). So i made a custom even that makes the box's width be 100% rather than a smaller percentage of the box's original width. Even tho i been digging for a way of redirecting the click event from my box element to the element behind it to trigger the click on a time i found nothing. So right now i guess pointer-events is my only option until i get lucky and find the piece that i need in the fullcalendar source. But thanks anyways :) – danniehansenweb Aug 18 '12 at 22:11
  • @danniehansenweb, you appear to be describing "event bubbling", which is exactly what is exploited by a jQuery statement of the form `$('#container').on('click', '.box', function() {...});`, as above. I'm sure this, or something similar, is the way ahead but can't advise more without seeing your HTML. – Beetroot-Beetroot Aug 19 '12 at 18:23
  • Can you elaborate on why one should avoid `pointer-events`? The support for it seems pretty well-established. – Charles Stover Jul 02 '18 at 18:00
0

You can use an Immediately Invoked Function Expression (IIFE) developed by Ivan Castellanos that will detect where your mouse pointer is (x,y) and evaluate to true or false on the element of your choice if, in fact, the mouse was over that element.

By utilizing Ivan's code, I was able to generate this proof of concept that will produce the same results as pointer-events: none; but is slightly more compatible across browsers. It uses the jQuery .offset() method. In the jsFiddle, there is a page with 3 elements, two <button>'s and one <div> that is overlayed on top of the buttons with 50% opacity. Under normal conditions you would not be able to click those elements without tweaking the z-index.

jsFiddle Example

//CSS Hitbox Solution 08-26-2015
//StackOverflow - https://stackoverflow.com/questions/32233084/show-an-element-without-hitbox-does-not-take-mouse-touch-input
//Detect MouseOver https://stackoverflow.com/questions/1273566/how-do-i-check-if-the-mouse-is-over-an-element-in-jquery
//Source: https://stackoverflow.com/questions/3942776/using-jquery-to-find-an-element-at-a-particular-position
//https://css-tricks.com/snippets/jquery/get-x-y-mouse-coordinates/
(function($) {
  $.mlp = {
    x: 0,
    y: 0
  }; // Mouse Last Position
  function documentHandler() {
    var $current = this === document ? $(this) : $(this).contents();
    $current.mousemove(function(e) {
      jQuery.mlp = {
        x: e.pageX,
        y: e.pageY
      };
    });
    $current.find("iframe").load(documentHandler);
  }
  $(documentHandler);
  $.fn.ismouseover = function(overThis) {
    var result = false;
    this.eq(0).each(function() {
      var $current = $(this).is("iframe") ? $(this).contents().find("body") : $(this);
      var offset = $current.offset();
      result = offset.left <= $.mlp.x && offset.left + $current.outerWidth() > $.mlp.x && offset.top <= $.mlp.y && offset.top + $current.outerHeight() > $.mlp.y;
    });
    return result;
  };
})(jQuery);
$('.notification-box').on("click", function() {
  $("button").each(function(i) {
    var iteratedButton = $('button:eq(' + i + ')');
    var buttonID = iteratedButton.attr("id");
    if (iteratedButton.ismouseover()) {
      iteratedButton.toggleClass(buttonID);
    }
  });
});
.notification-box {
  position: absolute;
  height: 100vw;
  width: 100vw;
  background-color: black;
  opacity: 0.5;
  /*pointer-events: none;*/
  z-index: -10;
  overflow: visible;
}
button {
  position: absolute;
  top: absolute;
  width: 50px;
  z-index: -10;
}
button#no {
  margin-top: 25px;
}
.yes {
  color: red;
  font-weight: bold;
}
.no {
  color: blue;
  font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<button id='yes'>Yes</button>
<button id='no'>No</button>
<div id='no' class="notification-box" />
Community
  • 1
  • 1
Alexander Dixon
  • 837
  • 1
  • 9
  • 24