Css on clickable element (*[onclick]:hover) - javascript

I want to use to style my clickable element (javascript function onclick), when they hovered.
So far I have this :
*[onclick]:hover{
background-color: red ;
color: blue;
}
It works fine for most of my elements as you can see :
document.getElementById('C').onclick = function(){alert('I am clickable too !')}
div {
background-color: green ;
margin : 2px
}
*[onclick]:hover{
background-color: red ;
color: blue;
}
<div id="A" onclick='alert("A")'>Click me ! A</div>
<div id="B" onclick='alert("B")'>Click me ! B</div>
<div id="notAclickableElement" >Don't click me :( Z</div>
<div id="C" >Click me ! C</div>
<div id="D" onclick='alert("D")'>Click me ! D</div>
But it only work for element where the onclick function is written in the Html page, and not added via Javascript.
Is there a way to properly select all clickable elements ?

The browser know a handful of elements that can be clicked by default, like the <a> and <button> elements. It is usually a good practice to use these elements if you want the user the click them, as they require little work to modify.
Other than that you could just add a class to the elements which to target them with as there is not a selector for an element that can be clicked.
However, it is a good practice to add a tabindex attribute to the elements that can be clicked as it makes them focusable. Users without a mouse (they exist) can use the Tab key to cycle through the clickable elements and click them with Enter or Spacebar. The elements mentioned in the first paragraph already incorporate this natively. With <div> elements you'll have to add this behavior manually.
The example below targets all clickable elements with a class and adds the :focus selector for the focussed styles.
document.getElementById('C').onclick = function() {
alert('I am clickable too !')
}
div {
background-color: green;
margin: 2px
}
.clickable:hover {
background-color: red;
color: blue;
}
.clickable:focus {
background-color: blue;
color: red;
}
<div id="A" class="clickable" onclick='alert("A")' tabindex="0">Click me ! A</div>
<div id="B" class="clickable" onclick='alert("B")' tabindex="0">Click me ! B</div>
<div id="notAclickableElement">Don't click me :( Z</div>
<div id="C" class="clickable" tabindex="0">Click me ! C</div>
<div id="D" class="clickable" onclick='alert("D")' tabindex="0">Click me ! D</div>

Sure. Just remove the [onclick] in the CSS.
document.getElementById('C').onclick = function(){alert('I am clickable too !')}
div {
background-color: green ;
margin : 2px
}
*:hover{
background-color: red ;
color: blue;
}
<div id="A" onclick='alert("A")'>Click me ! A</div>
<div id="B" onclick='alert("B")'>Click me ! B</div>
<div id="notAclickableElement" >Don't click me :( Z</div>
<div id="C" >Click me ! C</div>
<div id="D" onclick='alert("D")'>Click me ! D</div>
However, that also changed the background too, so we can designate a specific class to the divs like so:
document.getElementById('C').onclick = function(){alert('I am clickable too !')}
div {
background-color: green ;
margin : 2px
}
.hoverme:hover{
background-color: red ;
color: blue;
}
<div class="hoverme" id="A" onclick='alert("A")'>Click me ! A</div>
<div class="hoverme" id="B" onclick='alert("B")'>Click me ! B</div>
<div class="hoverme" id="notAclickableElement" >Don't click me :( Z</div>
<div class="hoverme" id="C" >Click me ! C</div>
<div class="hoverme" id="D" onclick='alert("D")'>Click me ! D</div>
Designating the hover to a single class is much more efficient, because you can define different hover effects for different things. All you have to do is add class="hoverme"

You can use .class in CSS.
document.getElementById('C').onclick = function(){alert('I am clickable too !')}
div {
background-color: green ;
margin : 2px
}
*[onclick]:hover{
background-color: red ;
color: blue;
}
.click {
background-color: green;
}
.click:hover {
background-color: red;
}
<div class="click" id="A" onclick='alert("A")'>Click me ! A</div>
<div id="B" onclick='alert("B")'>Click me ! B</div>
<div class="click" id="notAclickableElement" >Don't click me :( Z</div>
<div class="click" id="C" >Click me ! C</div>
<div class="click" id="D" onclick='alert("D")'>Click me ! D</div>

I hope I have been helpful
var x = document.querySelectorAll("div");
for (let i = 0; i < x.length; i++) {
if (x[i].id !== 'notAclickableElement') {
x[i].setAttribute('class', 'clickclass');
}
}
document.getElementById('C').addEventListener("click", hoverMe);
function hoverMe() {
alert('I am clickable too !')
}
div {
background-color: green;
margin: 2px
}
.clickclass:hover {
background-color: red;
color: blue;
}
<div id="A" onclick='alert("A")'>Click me ! A</div>
<div id="B" onclick='alert("B")'>Click me ! B</div>
<div id="notAclickableElement">Don't click me :( Z</div>
<div id="C">Click me ! C</div>
<div id="D" onclick='alert("D")'>Click me ! D</div>

Related

Javascript : finding a specific previous element on list and adding class

I have a list like this.
Inside each .list item there is a html button :
<div class="list">
<button>.list</button>
</div>
Also, each item can be inside a .bloc element
<div class="list"><button>.list</button></div>
<div class=bloc>
<div class="list"><button>.list</button></div>
</div>
When I click on the button, I would like the previous .list item to have the .active class like so :
Well it’s pretty easy with jquery and i've done that, it’s work pretty well :
$('.list button').on('click', function() {
$(this).closest('.list').prev('.list').addClass('active');
});
BUT i have some specific cases :
Sometimes the list items can be hidden and a list with hidden class can’t have .active class :
Or more complicated. You have to go up on each item one by one and put the active class to the first which does not have the hidden class :
I did the mechanics for items without class hidden, but I'm afraid I'm going in the wrong direction because the number of cases is getting bigger and bigger. Ain't there a smarter way ? :o
$('.list button').on('click', function() {
if ($(this).closest('.list').prev().length === 0) {
if ($(this).closest('.bloc').length) {
$(this).closest('.bloc').prev('.list').addClass('active');
$(this).closest('.bloc').prev('.bloc').find('.list:last-child').addClass('active');
} else {
$(this).closest('.list').next('.list').addClass('active');
}
}
if ($(this).closest('.list').prev('.bloc').length) {
$(this).closest('.list').prev('.bloc').find('.list:last-child').addClass('active');
}
$(this).closest('.list').prev('.list').addClass('active');
}
Rather than use .closest .prev and .next you can use the overload to .index which will give you the index within an existing collection.
var idx = collection.index(element);
select all your .list items into a jquery object/collection
when clicking get the index within that collection
subtract 1 to get the previous .list item within that collection
The basic scenarios are covered with $(".list") :
// collate the list first
var list = $(".list");
// add click handler
list.click(function() {
// confirm there are no duplicates
// comapred with $(this).index() which is the index within the parent
console.log(list.index(this), $(this).index())
$(".active").removeClass("active");
var idx = list.index(this);
if (idx > 0)
list.eq(idx-1).addClass("active");
});
.list { border:1px solid #CCC; height: 20px; }
.bloc { border:1px solid #444; padding: 5px; }
.active { border:1px solid red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='wrapper'>
<div class='bloc'>
<div class='list'></div>
<div class='list'></div>
</div>
<div class='list'></div>
<div class='list'></div>
</div>
All the other use-cases are then just a case of providing the correct selector up-front, with otherwise exactly the same code
var list = $(".wrapper>.bloc:not(.hidden)>.list:not(.hidden),.wrapper>.list:not(.hidden)");
I've tried to recreate some of your scenarios, but if there's one that's missing, please comment and I'll ensure it fits (within the remit of the question).
Giving:
var list = $(".wrapper>.bloc:not(.hidden)>.list:not(.hidden),.wrapper>.list:not(.hidden)")
list.click(function() {
$(".active").removeClass("active");
var idx = list.index(this);
if (idx > 0)
list.eq(idx-1).addClass("active");
});
.list { border:1px solid #CCC; height: 20px; }
.bloc { border:1px solid #444; padding: 5px; }
.active { border:1px solid red; }
.hidden { background-color: #ccc; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='wrapper'>
<div class='bloc'>
<div class='list'></div>
<div class='list'></div>
</div>
<div class='list hidden'></div>
<div class='bloc'>
<div class='list hidden'></div>
<div class='list hidden'></div>
</div>
<div class='list'></div>
<div class='bloc'>
<div class='list hidden'></div>
<div class='list'></div>
</div>
<div class='list'></div>
<div class='list'></div>
<div class='bloc hidden'>
<div class='list'></div>
<div class='list'></div>
</div>
<div class='list'></div>
<div class='list'></div>
</div>

How do I make one element appear without triggering other elements of the same class

I have to make a set of buttons that appear and disappear.
How it is supposed to work:
I click on link 1 (link 2 is invisible at this point).
link 2 should then appear.
the problem here is there can be multiple elements of the same type with the same classes and I can't figure out how to distinguish between just showing the "link2"
that corresponds to the clicked "link1" without triggering the other "link2".
there is some code showing the progress I have made.
thank you in advance!
<style>
.hideaction{
visibility: hidden;
}
.showaction{
visibility: visible;
}
</style>
<script>
$(document).ready(function(){
$(".elem_action_showing").click(function(){
$(".elem_action_hiding").removeClass("hideaction").addClass("showaction");
});
</script>
</head>
<body>
<div class="elem_card card_set_click" style=" border: 1px solid black">
<div class="elem_hidden">
<p class="hideaction elem_action_hiding">%link2%</p>
</div>
<div class="elem_showing ">
<p class="elem_action_showing set_click">%link1%</p>
</div>
</div>
<div class="elem_card card_set_click" style=" border: 1px solid black">
<div class="elem_hidden">
<p class="hideaction elem_action_hiding">%link2%</p>
</div>
<div class="elem_showing ">
<p class="elem_action_showing set_click">%link1%</p>
</div>
</div>
</body>
The solution should work irregardless of how many ".elem_card" and ".hideaction" elements are there.
The issue is because you're selecting all .elem_action_hiding elements. To fix this use DOM traversal to find only the one which is related to the .elem_action_showing which was clicked. Try this:
$(".elem_action_showing").click(function() {
$(this).closest('.elem_showing').prev().find(".elem_action_hiding").toggleClass("hideaction showaction");
});
.hideaction {
visibility: hidden;
}
.showaction {
visibility: visible;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="elem_card card_set_click" style=" border: 1px solid black">
<div class="elem_hidden">
<p class="hideaction elem_action_hiding">%link2%</p>
</div>
<div class="elem_showing">
<p class="elem_action_showing set_click">%link1%</p>
</div>
</div>
<div class="elem_card card_set_click" style=" border: 1px solid black">
<div class="elem_hidden">
<p class="hideaction elem_action_hiding">%link2%</p>
</div>
<div class="elem_showing ">
<p class="elem_action_showing set_click">%link1%</p>
</div>
</div>

Modify DOM based on amount of divs after specific class

Is there any way to modify DOM based on amount div after specific class?
For example, if I have a div with a class called row and after that I have 4 div elements. Is there a way to change these 4 div element class depending on how many div elements there are?
Code:
<div class="row">
<div class="col-1-of-4">
some content
</div>
<div class="col-1-of-4">
some content
</div>
<div class="col-1-of-4">
some content
</div>
<div class="col-1-of-4">
some content
</div>
</div>
Another example I have a div class row again, but this time I want 3 div elements after that, then I would want these div elements to have a class called col-1-of-3, not col-1-of-4. If I would have just 2 div elements after that then class col-1-of-2 and if just one div element then no class at all.:
Code:
<div class="row">
<div class="col-1-of-3">
some content
</div>
<div class="col-1-of-3">
some content
</div>
<div class="col-1-of-3">
some content
</div>
</div>
Also these div elements with classes called col-1-of-4, col-1-of-3 and col-1-of-2 have their own div elements inside them, but they should stay like they were.
Is it possible to achieve with JavaScript or PHP?
You would need to write conditional blocks to handle this if I'm understanding you correctly (wanting a JS or PHP solution).
Note: It goes without saying that a similar solution can be completed with a CSS-only approach, as outlined here: Can CSS detect the number of children an element has?
Here's an example (using jQuery) with 3 sets of row's, with varying children (2, 3, 4):
$(function() {
var $rows = $(".row");
$rows.each(function() {
$row = $(this);
var $children = $(">div", $row),
total = $children.size();
$children.addClass("col-1-of-" + total);
});
});
.row {
border: 1px solid #000;
margin: 10px;
}
.row > div {
margin: 10px;
}
.row .col-1-of-2 {
border: 1px solid #f00;
}
.row .col-1-of-3 {
border: 1px solid #0f0;
}
.row .col-1-of-4 {
border: 1px solid #00f;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div>
some content
</div>
<div>
some content
</div>
</div>
<div class="row">
<div>
some content
</div>
<div>
some content
</div>
<div>
some content
</div>
</div>
<div class="row">
<div>
some content
</div>
<div>
some content
</div>
<div>
some content
</div>
<div>
some content
</div>
</div>
When you run the snippet, you must inspect the elements. I've added borders so you can see the difference.
Theres a number of ways to achieve this. I'd maybe add another class name so you can easily identify groups of divs, and differentiate between parent and child divs. Does this help you get where you're going? Basically find the number of children in a row and then concatenate that number into the class name.
var x = document.getElementsByClassName('row')[0].childElementCount
var element = document.getElementsByClassName('row')[0];
element.classList.add(`col-1-of-${x}`);
.row {
width: 100%;
display:flex;
flex-grow: 1;
margin-bottom: 2px;
}
.col {
float:left;
background: rgba(255,0,0,.2);
text-align: center;
margin-right: 2px;
}
.col:first-child:nth-last-child(1),
.col:first-child:nth-last-child(1) ~ .col{
width: calc(100% / 1);
}
.col:first-child:nth-last-child(2),
.col:first-child:nth-last-child(2) ~ .col{
width: calc(100% / 2);
}
.col:first-child:nth-last-child(3),
.col:first-child:nth-last-child(3) ~ .col{
width: calc(100% / 3);
}
.col:first-child:nth-last-child(4),
.col:first-child:nth-last-child(4) ~ .col{
width: calc(100% / 4);
}
.col:first-child:nth-last-child(5),
.col:first-child:nth-last-child(5) ~ .col{
width: calc(100% / 5);
}
<div class="row">
<div class="col">1</div>
</div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
</div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="col">4</div>
</div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="col">4</div>
<div class="col">5</div>
</div>
so this is with float, can be used in a sass/scss mixin to create code automagically. there should be also a flex solution but i dont have it at hand at the moment

Allow text between 2 non contenteditable contents

I have a <div contenteditable> and 2 divs with contenteditable="false". When I set the cursor between them to add text, it does not let me. I want to be able to write text between them. I fix the poblem by adding a <span> </span>. But if I backspace, the <span> </span> can get deleted and get back to the same problem. If I do <span contenteditable="false"> </span> I won't be able to add texts.
How to fix that problem definitively?
Note: the codes inside the div#editable aren't static, they are dynamic. I(the user) can add a span, div, p, h1, any Html Element I want.
Code:
<div contenteditable>
<div contenteditable=false></div><div contenteditable=false></div>
</div>
Script:
this.divNew.children().each(function () {
var child = $(this);
if (!child.is("br")) {
child.after($("<span>").addClass("gvwb-span-empty-newline").append(" "));
}
});
$("#editable").children().each(function () {
var child = $(this);
if (!child.is("br")) {
child.after($("<span>").addClass("gvwb-span-empty-newline").append(" "));
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editable" contenteditable style="border: 1px solid black;">
Hello world<br>
<div contenteditable="false" style="height: 10px; background: blue"></div><div contenteditable="false" style="height: 10px; background: red"></div>
Hello world 2 <br>
</div>
I suggest you an empty <div> in between the two non-editable.
Just set its height to 1em with CSS.
/*
$("#editable").children().each(function () {
var child = $(this);
if (!child.is("br")) {
child.after($("<span>").addClass("gvwb-span-empty-newline").append(" "));
}
});
*/
#editable>div:nth-of-type(2){
height:1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="editable" contenteditable style="border: 1px solid black;">
Hello world<br>
<div contenteditable="false" style="height: 10px; background: blue"></div>
<div></div>
<div contenteditable="false" style="height: 10px; background: red"></div>
Hello world 2 <br>
</div>

jQuery trouble: add class /remove class nested inside show / hide

I'm a beginner and I have a problem.
Could you please help me?
I made to divs on top of each other.
I made two other divs ("buttons")with paragraphs and I use jQuery show / hide effect to switch the two divs.
This part is working very well.
Nevertheless I want to add a nother effect (add class/ remove class) inside of this effect to show witch one is active.
But It's not changing the outlook of the "buttons".
Could you please help me where I made the mistake?
Here is my Code:
$(document).ready(function(){
$( "#click2" ).click(function(){
$( "#two" ).show();
$("#click2").removeClass(".passive").addClass(".active");
});
$( "#click1" ).click(function(){
$( "#two" ).hide();
$("#click1").removeClass(".passive").addClass(".active");
});
});
.active, .passive{
cursor: pointer;
font-weight: bold;
}
.active{
border-bottom: 2px solid blue;
color: blue;
}
.passive{
border-bottom: 2px solid gray;
color: gray;
}
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<div class="row">
<div id="click1" class="col-xs-6 active">
<p class="text-center text-uppercase">referencies a</p>
</div>
<div id="click2" class="col-xs-6 passive">
<p class="text-center text-uppercase">referencies b</p>
</div>
</div>
So the show / hide is wirking but the add/ remove class isn'n.
Could you please help me where I made the mistake?
Remove '.' (dot) from the css class name. jQuery addClass and removeClass only takes the name of the css class.
addClass("className") -- correct
addClass(".className") -- wrong
In your case it will be like:
$("#click2").removeClass("passive").addClass("active");
you have to remove the dot from the class ,
and also add the changing calls for the other button as below code
$(document).ready(function() {
$("#click2").click(function() {
$("#two").show();
$("#click2").removeClass("passive").addClass("active");
$("#click1").removeClass("active").addClass("passive");
});
$("#click1").click(function() {
$("#two").hide();
$("#click1").removeClass("passive").addClass("active");
$("#click2").removeClass("active").addClass("passive");
});
});
.active,
.passive {
cursor: pointer;
font-weight: bold;
}
.active {
border-bottom: 2px solid blue;
color: blue;
}
.passive {
border-bottom: 2px solid gray;
color: gray;
}
`
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div id="click1" class="col-xs-6 passive">
<p class="text-center text-uppercase">referencies a</p>
</div>
<div id="click2" class="col-xs-6 active">
<p class="text-center text-uppercase">referencies b</p>
</div>
</div>
<div class="row">
<div id="two" class="col-xs-12 active">
<p class="text-center text-uppercase">Div content </p>
</div>
</div>
While using removeClass and addClass, you only need to provide classname, . is not needed.
$(document).ready(function() {
$("#click2").click(function() {
$("#two").show();
$(this).removeClass("passive").addClass("active");
$("#click1").removeClass("active").addClass("passive");
});
$("#click1").click(function() {
$("#two").hide();
$(this).removeClass("passive").addClass("active");
$("#click2").removeClass("active").addClass("passive");
});
});
.active,
.passive {
cursor: pointer;
font-weight: bold;
}
.active {
border-bottom: 2px solid blue;
color: blue;
}
.passive {
border-bottom: 2px solid gray;
color: gray;
}
`
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div id="click1" class="col-xs-6 active">
<p class="text-center text-uppercase">referencies a</p>
</div>
<div id="click2" class="col-xs-6 passive">
<p class="text-center text-uppercase">referencies b</p>
</div>
</div>
<div class="row">
<div id="two" class="col-xs-12 active">
<p class="text-center text-uppercase">Div content </p>
</div>
</div>
Here is the updated code:
<script type="text/javascript">
$(document).ready(function(){
$( "#click2" ).click(function(){
$( "#two" ).show();
$("#click2").removeClass("passive").addClass("active"); // Removed `.` from class names
});
$( "#click1" ).click(function(){
$( "#two" ).hide();
$("#click1").removeClass("passive").addClass("active"); // Removed `.` from class names
});
});
</script>
You don't need to use dot when use jQuery class methods, as already mentioned;
You could try to keep it simplier by using toggleClass instead of addClass and removeClass:
$( "#click3" ).click(function(){
$("#click3, #click4").toggleClass("active passive");
});
$( "#click4" ).click(function(){
$("#click3, #click4").toggleClass("active passive");
});
You could mention differencies in behavior (now active element become passive on click).
To simplify even more, we could add just one listener, but check what exactly we clicking:
$(document).on('click', '.passive', function() {
$('#click1, #click2').toggleClass("active passive");
});
https://jsfiddle.net/aakochar/u3c34b48/
As an alternative (or if you want to investigate the code), take a look at bootstrap tabs:
http://getbootstrap.com/javascript/#tabs

Categories