Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pointer-events:none but capture click

Tags:

javascript

css

is it possible to allow only click and disable all other pointer-events

top-layer has a search bar

bottom-layer has a word cloud

I have set pointer-events:none on top-layer, so all words in the word cloud can be hovered over even if they are below the search bar.

but I want the click event on the input text to be enabled, so that when the user wants to type in something, he can.

enter image description here

Here is a related fiddle

The text is behind the input, but it should be hoverable, the input is above the text, but it should be focusable using mouse, to allow the user to type in.

Note: it looks like a placeholder thing, but it is not. please see the original image to see what i am trying to achieve.

like image 970
gaurav5430 Avatar asked Dec 02 '15 08:12

gaurav5430


People also ask

Is click a pointer event?

The answer is no. As to the question: Does a pointer press dispatch a click event? Answering that may take some testing. So it seems that at least on an iPhone, a click event is dispatched with a finger press.

What does pointer events none mean?

none prevents all click, state and cursor options on the specified HTML element. auto restores the default functionality (useful for use on child elements of an element with pointer-events: none; specified. inherit will use the pointer-events value of the element's parent.

What is the default pointer events?

Default Pointer Events on an element corresponds to the CSS pointer events property. It controls whether or not an element will "pass through" clicks to elements that are underneath it (that is, elements that have a smaller z-index).


2 Answers

Because pointer-events is blocking interactieve events(click, hover, mouseenter etc.) it would be only accessible with javascript (through focus for example).

It's maybe not the best solution but it will do I guess in your case?

(function($) {
  var focus = false;
  $(document).on('click', function(e) {
    console.log(focus);
    e.preventDefault();
    if (focus) {
      focus = false;
      $('.cl1').trigger('blur');
    } else {
      focus = true;
      $('.cl1').focus();
    }
  });
})(jQuery);

a fiddle with this working solution: https://jsfiddle.net/cob02bpv/1/

Edit: you could check on which element was clicked, only elements under the input will be tricky.

If its not the solution the only one would be to calculate the coordinates from the input box and check where the click event was triggered. But still you would have problems for your elements under the input box.

like image 74
Yoram de Langen Avatar answered Sep 30 '22 03:09

Yoram de Langen


I think this should work. Listening to the click event on the parent container, getting the event.clientX and event.clientY values to check if they are within the bounds of the input element. If so, you can then set the focus to the input element. You can still determine if one of the random words underneath the input element has been clicked.

var d = document,
    c = d.getElementsByClassName('container').item(0),
    inp = d.createElement('input'),
    a = 50,
    i = 0;


/*
 | get the clientBoundingRect of the input element
 | and if the mouse x and mouse y positions are within
 | the bounds set the focus on to the input element.
------------------------------------------------------------- */
function inpClickHndl (evt) {
  var inpRect = inp.getBoundingClientRect(),
      x = evt.clientX,
      y = evt.clientY,
      l = inpRect.left,
      w = l + inpRect.width,
      t = inpRect.top,
      h = t + inpRect.height;

  if (x >= l && x <= w && y >= t && y <= h) {
    inp.focus();
  }
}

/* 
 | ignore this, it's just to create the random words.
------------------------------------------------------------- */
function wordClickHndl (evt) {
  this.style.color = "yellow";
}

for (i; i < a; i++) {
  var p = d.createElement('p'),
      t = d.createTextNode('Random Word');
  p.appendChild(t);
  p.addEventListener('click', wordClickHndl, false);
  p.style.position = 'absolute';
  p.style.top = Math.floor(Math.random() * (window.innerHeight - 80)) + -40 + 'px';
  p.style.left = Math.floor(Math.random() * (window.innerWidth - 80)) + -40 + 'px';
  p.style.fontSize = Math.floor(Math.random() * (38 - 8)) + 8 + 'px';
  p.style.fontWeight = 'bold';
  c.appendChild(p);
}

inp.setAttribute('type', 'text');
c.appendChild(inp);

/*------------------------------------------------------------- */

// add a click handler to your parent element.
c.addEventListener('click', inpClickHndl, false);
body {
  margin: 0;
  font-family: sans-serif;
}

.container {
  position: relative;
  height: 100vh; width: 100vw;
  background-color: #1a1a1a;
}

.container p {
  color: green;
}

.container p:hover {
  color: red;
  cursor: pointer;
}

.container input {
  position: absolute;
  top: 50%; left: calc(50% - 85px);
  pointer-events:none;
  opacity: .75;
}
<div class="container"></div>
like image 31
DavidDomain Avatar answered Sep 30 '22 05:09

DavidDomain