Reputation: 13917
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.
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.
Upvotes: 25
Views: 43712
Reputation: 127
Wouldn't it be easiest to set input's z-index
to a higher value than the element with pointer-events: 'none'
?
Upvotes: 0
Reputation: 890
I had the same problem in the past. I managed to solve it in a bit tricky way, just added parent division with button
inside and applied click event
on parent element and pointer-events: none
to child button element.
Upvotes: 0
Reputation: 1263
If layout permits it you could use the adjacent sibling combinator, given that you re-order the elements:
Tested on FireFox and Chrome.
.backText:hover {
color : red;
}
.cl1 {
opacity : 0.7;
position : absolute;
}
/* adjacent sibling combinator */
.wrap-input:hover + div {
color : red;
}
.cl1:focus {
opacity : 1;
}
<div>
<div class="wrap-input">
<input type="text" class="cl1" value="aa" />
</div>
<div class="backText">
Some text to be hovered even if input is above
</div>
</div>
The following only works on FireFox. Tested on Chrome and it flickers when pointer is moved, - but could perhaps give some ideas.
Instead of setting pointer-events
on the input-element directly, set it using the :hover
pseudo-class.
Example, based on your fiddle:
.cl1 {
position : absolute;
top : 0px;
opacity : 0.7;
height : 30px;
}
/* Move pointer-events here */
.cl1:hover {
pointer-events : none;
}
.cl1:focus {
opacity : 1;
}
.backText:hover {
color : red;
}
<div>
<div class="backText">
Some text to be hovered even if input is above
</div>
<div>
<input type="text" class="cl1" />
</div>
</div>
Upvotes: 0
Reputation: 15303
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>
Upvotes: 3
Reputation: 5509
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.
Upvotes: 3
Reputation:
Just add the pointer-events
CSS3 property, setting as initial
to the text box. Using !important
is recommended also, so because another property can pass that added.
In CSS3:
pointer-events:initial !important
In JavaScript:
document.querySelector('input[type=text]').style.pointerEvents="initial"
Upvotes: 1