Home > front end >  Javascript Help: Clicking an element affects that element AND other elements
Javascript Help: Clicking an element affects that element AND other elements

Time:06-03

I haven't really got experience using javascript, so I'm currently trying out the basic first steps of getting the hang of it.


The setup:

I've got these four div boxes in parent-container with the flex-property, each box with 25% width.

<section>
    <div ></div>

    <div ></div>

    <div ></div>

    <div ></div>
</section>

When hovering over one of the boxes, that particular box gets 40% in width, and the remaining boxes gets reduced to 20%.

When you then click one of the boxes, that box gets 85% width, and the remaining boxes gets reduced to 5%.

If you then click another box, that box gets 85% width, and remaining boxes gets reduced to 5%.

To get back to the all-25%-width-boxes, using a simple cross will do the job (haven't coded this yet, though).


Problem/Troubleshooting:

I started off by trying to do an all-CSS solution using input checkboxes, but quickly realized this would not work, as CSS do not have a selector that can have effect on previous siblings.

Therefore, I need two javascript functions.

(1) When clicking one of the boxes, that element gets a certain width, as well as the remaining boxes getting a smaller width.

(2) If you have already clicked one of the boxes, which now is 85% width, if you click one of the other boxes, that particular box is now "the selected one", and will be 85% in width.

I have a feeling it's two simple functions. I just do not have experience using javascript, so I'm uncertain of what to write.

CodePudding user response:

As said CherryDT it can be done by flex-basis

Or if can be done with css e.g. radio group and checked

section {
  position: relative;
  display: flex;
    width: 100%;
    height: 100px;
}

input {
  appearance: none;
  display: block;
  padding: 0;
  margin: 0;
  width: 25%;
  height: 100%;
}

.box1 {
  background-color: rgba(0,0,0,.1)
}
.box2 {
  background-color: rgba(0,0,0,.2)
}
.box3 {
  background-color: rgba(0,0,0,.3)
}
.box4 {
  background-color: rgba(0,0,0,.4)
}

input:checked   section:hover input {
  width: 20%;
}

input:checked   section:hover input:hover {
  width: 40%;
}

input:not(:checked)   section input {
  width: 5%;
}

input:not(:checked)   section input:checked {
  width: 85%;
}

input:checked   section > label {
  display: none;
}

label {
  position: absolute;
}
<input id="hidden" hidden type="radio" name="group"   value="0" checked />
<section>
    <label for="hidden">
      X
    </label>
    <input type="radio" name="group"   value="1"/>
    <input type="radio" name="group"  value="2"/>
    <input type="radio" name="group"  value="3"/>
    <input type="radio" name="group" value="4"/>
</section>

CodePudding user response:

Here is one possible solution using jQuery:

$(".box").on({ 
    mouseenter: function(){
        if ($(".box.clicked").length) return false;

        $(this).siblings(".box").css("width","20%");
        $(this).css("width","40%");
    },
    mouseleave: function(){
        if ($(".box.clicked").length) return false;

        $(this).siblings(".box").css("width","25%");
        $(this).css("width","25%");
    }
})

$(".box").on("click", function(e){

    $(".box.clicked").css("width","5%");
    $(".box.clicked").removeClass("clicked");

    $(this).addClass("clicked");
    $(this).css("width","85%");
    $(this).siblings(".box").css("width","5%");

    if ($(e.target).hasClass("exit")) {
        $(this).removeClass("clicked");
        $(this).css("width","25%");
        $(this).siblings(".box").css("width","25%");
    }
    
})
* {
    margin: 0;
    padding: 0;
}
section {
    display: flex;
    justify-content: space-between;
    align-items: center;
    
    width: 100%;
    min-height: 250px;
}
.box {
    width: 25%;
    height: 250px;
    position: relative;
}
.box1 {
    background-color: red;
}
.box2 {
    background-color: blue;
}
.box3 {
    background-color: green;
}
.box4 {
    background-color: yellow;
}

.box .exit {
    position: absolute;
    cursor: pointer;
    top: 5px;
    right: 10px;
    display: none;
    font-weight: bold;
}
.box.clicked .exit {
    display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<meta charset="utf-8">

<section>
    <div >
        <p >×</p>
    </div>

    <div >
        <p >×</p>
    </div>

    <div >
        <p >×</p>
    </div>

    <div >
        <p >×</p>
    </div>
</section>

You could also asssign those properties to classes and then just add/remove classes on the events, but structure will be overall the same.

Next time, please try to code yourself first and provide examples of what you've tried.

  • Related