Apply effect only on target element

Asked

Viewed 68 times

2

I have this html of registered cards:

.lista-cartoneira h1 {
    font-size: 1.2rem;
    margin: 12px 0 12px 0;
    font-weight: 500;
}

.lista-cartoneira h2 {
    font-size: 1rem;
    margin: 12px 0 12px 0;
}

.lista-cartoneira img {
    width: 80px;
    height: 80px;
    max-width: 80px;
    margin: 12px;
}

.card-panel {
    padding: 0 !important;
}

.col.s9.lista-cartoneira {
    width: 75%;
    margin-left: 12px;
}

.botoes-cartoneira.row {
    height: 56px; 
    margin: 24px 0 24px 0;
}

.botoes-cartoneira.col {
    height: 56px; 
    text-align: center;
}

.atalhos-cartoneira.col i {
    margin-top: 43px;
}

.atalhos-cartoneira.col {
    height: 110px; text-align: center; color: white;
}

.item-total {
    width: 200%;
}

@media only screen and (min-width: 340px) {
    .col.s9.lista-cartoneira {
        width: 75%;
        margin-left: 0;
    }
}

@media only screen and (min-width: 600px) {
    .col.s9.lista-cartoneira {
        width: 220%;
        margin-left: 0;
    }
    .lista-cartoneira h1 {
        font-size: 1.8rem;
    }
    .lista-cartoneira h2 {
        font-size: 1.6rem;
    }
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div style="width: 100%; overflow-x: hidden;">
                <div class="item-total">
                    <div class="col s12 m8 offset-m2 l6 offset-l3" style="width: 50%;">
                        <div class="card-panel grey lighten-5 z-depth-1">
                            <div class="row valign-wrapper">
                                <div class="col s3 lista-cartoneira" style="padding-left: 0px;">
                                    <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrSKKu7oCCmPKDSTU6aSsZMfnUxrVImzv42-DDnAgVBmG54Szz" alt="" class="circle responsive-img">  
                                </div>
                                <div class="col s9 lista-cartoneira">
                                    <h1>TESTE1</h1>
                                    <h2>TESTE1</h2>
                                </div>
                            </div>
                        </div>
                    </div>
            </div>
            
            <div class="col s12 m8 offset-m2 l6 offset-l3" style="width: 50%; float: right; margin-top: -136px;">
                    <div class="card-panel grey lighten-5 z-depth-1">
                        <div class="row valign-wrapper botoes">
                            <div class="atalhos-cartoneira col s3" style="background-color: #00b0ff;">
                                <i class="material-icons">phone</i>
                            </div>
                            <div class="atalhos-cartoneira col s3" style="background-color: #ffb74d;">
                                <i class="material-icons">email</i>
                            </div>
                            <div class="atalhos-cartoneira col s3" style="background-color: #757575;">
                                <i class="material-icons">place</i>
                            </div>
                             <div class="atalhos-cartoneira col s3" style="background-color: #00BFA5;">
                                <i class="material-icons">open_in_new</i>
                            </div>
                        </div>
                    </div>
                </div> 
            </div>
            
            <div style="width: 100%; overflow-x: hidden;">
                <div class="item-total">
                    <div class="col s12 m8 offset-m2 l6 offset-l3" style="width: 50%;">
                        <div class="card-panel grey lighten-5 z-depth-1">
                            <div class="row valign-wrapper">
                                <div class="col s3 lista-cartoneira" style="padding-left: 0px;">
                                    <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrSKKu7oCCmPKDSTU6aSsZMfnUxrVImzv42-DDnAgVBmG54Szz" alt="" class="circle responsive-img">  
                                </div>
                                <div class="col s9 lista-cartoneira">
                                    <h1>TESTE2</h1>
                                    <h2>TESTE2</h2>
                                </div>
                            </div>
                        </div>
                    </div>
            </div>
            
            <div class="col s12 m8 offset-m2 l6 offset-l3" style="width: 50%; float: right; margin-top: -136px;">
                    <div class="card-panel grey lighten-5 z-depth-1">
                        <div class="row valign-wrapper botoes">
                            <div class="atalhos-cartoneira col s3" style="background-color: #00b0ff;">
                                <i class="material-icons">phone</i>
                            </div>
                            <div class="atalhos-cartoneira col s3" style="background-color: #ffb74d;">
                                <i class="material-icons">email</i>
                            </div>
                            <div class="atalhos-cartoneira col s3" style="background-color: #757575;">
                                <i class="material-icons">place</i>
                            </div>
                             <div class="atalhos-cartoneira col s3" style="background-color: #00BFA5;">
                                <i class="material-icons">open_in_new</i>
                            </div>
                        </div>
                    </div>
                </div> 
            </div>
            
            <script type="text/javascript">
                $('.botoes').hide();
                // DESLIZA 
                var inicialX;
                addEventListener('touchstart', function(e) {
                    var toqueobj = e.changedTouches[0];
                    inicialX = toqueobj.pageX;
                }, false);
                //
                addEventListener('touchmove', function(e){
                    e.preventDefault();
                }, false)
                //
                addEventListener('touchend', function(e){
                    var toqueobj = e.changedTouches[0];
                    var distancia = toqueobj.pageX - inicialX;
                    if(distancia < 0){
                        $('.botoes').show(100);
                        $('.botoes').css('position', 'relative');
                    }
                    if(distancia > 0){
                       $('.botoes').hide(100);

                    }
                }, false)
            </script>
        </div>
    </div>

These cards are not me who insert, have a card registration screen and the user register as many as you want, I put here just to give an example. When I slide my fingers to the left, the buttons appear:

inserir a descrição da imagem aqui

They can test in the code I put above, it works if you have touch or if you want to test in the browser.

The problem is that if the user creates 5 cards for example, and slides, ALL the cards will suffer this effect and the buttons will appear.

How do I only make the target element suffer the action? They contain the same class, but not the same id.. I just can’t add an event to an id, I don’t know what to do..

Remembering that as they are inserted by the append, I have to search for the elements like this:

$(document).on('touchstart', 'AQUI É O PROBLEMA.. Queria aplicar o evento no alvo, no cartão que foi deslizado', function (){

    });
  • It wasn’t very clear who that would be target. Could you explain better so we can help?

  • @Taciiobrito would be the card that the user 'swipe his fingers' to appear the buttons.

  • I get it, I’m sorry, it’s just that here in my test it presents just the first card.

  • @Silent silent.

2 answers

1


You don’t need id in this case, just use e.target (element that triggered the event) and use the methods .closest() (meets the ancestor) and .find() (seeking a descendant).

But for this to work better, put each pair of div (the one with the text icon and the one with the buttons) inside a div-parent and give a class name (put .cartoes).

Remove the false events because it is not necessary and will error in jQuery. Also remove the event touchmove that I don’t see any function for it, besides giving jQuery error with preventDefault(); because there is no way to call and cancel these events.

Another suggestion, put the class .botoes in CSS with None display in instead of hiding in JS with $('.botoes').hide();:

.valign-wrapper.botoes{
   display: none;
}

See (use browser devtools in mobile device mode):

// DESLIZA 
var inicialX;
$(document).on('touchstart', function(e){
   var toqueobj = e.changedTouches[0];
   inicialX = toqueobj.pageX;
});
//
//                $(document).on('touchmove', function(e){
//                    e.preventDefault();
//                })
//
$(document).on('touchend', function(e){
   var toqueobj = e.changedTouches[0];
   var distancia = toqueobj.pageX - inicialX;
   var botoes = $(e.target).closest(".cartoes").find(".botoes");
   if(distancia < 0){
      botoes
      .show(100)
      .css('position', 'relative');
   }
   if(distancia > 0){
      botoes.hide(100);
   }
})
.valign-wrapper.botoes{
   display: none;
}

.lista-cartoneira h1 {
    font-size: 1.2rem;
    margin: 12px 0 12px 0;
    font-weight: 500;
}

.lista-cartoneira h2 {
    font-size: 1rem;
    margin: 12px 0 12px 0;
}

.lista-cartoneira img {
    width: 80px;
    height: 80px;
    max-width: 80px;
    margin: 12px;
}

.card-panel {
    padding: 0 !important;
}

.col.s9.lista-cartoneira {
    width: 75%;
    margin-left: 12px;
}

.botoes-cartoneira.row {
    height: 56px; 
    margin: 24px 0 24px 0;
}

.botoes-cartoneira.col {
    height: 56px; 
    text-align: center;
}

.atalhos-cartoneira.col i {
    margin-top: 43px;
}

.atalhos-cartoneira.col {
    height: 110px; text-align: center; color: white;
}

.item-total {
    width: 200%;
}

@media only screen and (min-width: 340px) {
    .col.s9.lista-cartoneira {
        width: 75%;
        margin-left: 0;
    }
}

@media only screen and (min-width: 600px) {
    .col.s9.lista-cartoneira {
        width: 220%;
        margin-left: 0;
    }
    .lista-cartoneira h1 {
        font-size: 1.8rem;
    }
    .lista-cartoneira h2 {
        font-size: 1.6rem;
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<div style="width: 100%; overflow-x: hidden;">
   <div class="cartoes">
      <div class="item-total">
         <div class="col s12 m8 offset-m2 l6 offset-l3" style="width: 50%;">
            <div class="card-panel grey lighten-5 z-depth-1">
               <div class="row valign-wrapper">
                  <div class="col s3 lista-cartoneira" style="padding-left: 0px;">
                     <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrSKKu7oCCmPKDSTU6aSsZMfnUxrVImzv42-DDnAgVBmG54Szz" alt="" class="circle responsive-img">  
                  </div>
                  <div class="col s9 lista-cartoneira">
                     <h1>TESTE1</h1>
                     <h2>TESTE1</h2>
                  </div>
               </div>
            </div>
         </div>
      </div>

      <div class="col s12 m8 offset-m2 l6 offset-l3" style="width: 50%; float: right; margin-top: -136px;">
         <div class="card-panel grey lighten-5 z-depth-1">
            <div class="row valign-wrapper botoes">
               <div class="atalhos-cartoneira col s3" style="background-color: #00b0ff;">
                  <i class="material-icons">phone</i>
               </div>
               <div class="atalhos-cartoneira col s3" style="background-color: #ffb74d;">
                  <i class="material-icons">email</i>
               </div>
               <div class="atalhos-cartoneira col s3" style="background-color: #757575;">
                  <i class="material-icons">place</i>
               </div>
               <div class="atalhos-cartoneira col s3" style="background-color: #00BFA5;">
                  <i class="material-icons">open_in_new</i>
               </div>
            </div>
         </div>
      </div> 
   </div>

   <div class="cartoes">
      <div style="width: 100%; overflow-x: hidden;">
         <div class="item-total">
            <div class="col s12 m8 offset-m2 l6 offset-l3" style="width: 50%;">
               <div class="card-panel grey lighten-5 z-depth-1">
                  <div class="row valign-wrapper">
                     <div class="col s3 lista-cartoneira" style="padding-left: 0px;">
                        <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQrSKKu7oCCmPKDSTU6aSsZMfnUxrVImzv42-DDnAgVBmG54Szz" alt="" class="circle responsive-img">  
                     </div>
                     <div class="col s9 lista-cartoneira">
                        <h1>TESTE2</h1>
                        <h2>TESTE2</h2>
                     </div>
                  </div>
               </div>
            </div>
         </div>

         <div class="col s12 m8 offset-m2 l6 offset-l3" style="width: 50%; float: right; margin-top: -136px;">
            <div class="card-panel grey lighten-5 z-depth-1">
               <div class="row valign-wrapper botoes">
                  <div class="atalhos-cartoneira col s3" style="background-color: #00b0ff;">
                     <i class="material-icons">phone</i>
                  </div>
                  <div class="atalhos-cartoneira col s3" style="background-color: #ffb74d;">
                     <i class="material-icons">email</i>
                  </div>
                  <div class="atalhos-cartoneira col s3" style="background-color: #757575;">
                     <i class="material-icons">place</i>
                  </div>
                  <div class="atalhos-cartoneira col s3" style="background-color: #00BFA5;">
                     <i class="material-icons">open_in_new</i>
                  </div>
               </div>
            </div>
         </div> 
      </div>
   </div>
</div>

0

add a id for each element (in the case how to make a listing, make dynamic):

<div class="col s12 m8 offset-m2 l6 offset-l3" style="width: 50%; float: right; margin-top: -136px;">
                    <div class="card-panel grey lighten-5 z-depth-1">
                        <div class="row valign-wrapper botoes">
                            <div class="atalhos-cartoneira col s3" id="botao1" style="background-color: #00b0ff;">
                                <i class="material-icons">phone</i>
                            </div>
                            <div class="atalhos-cartoneira col s3" id="botao2" style="background-color: #ffb74d;">
                                <i class="material-icons">email</i>
                            </div>
                            <div class="atalhos-cartoneira col s3" id="botao3" style="background-color: #757575;">
                                <i class="material-icons">place</i>
                            </div>
                             <div class="atalhos-cartoneira col s3" id="botao4" style="background-color: #00BFA5;">
                                <i class="material-icons">open_in_new</i>
                            </div>
                        </div>
                    </div>
                </div> 
            </div>

and below the javascript

// faça um foreach na classe que todos os botões possui
$(".atalhos-cartoneira").each(function(index, el) {

  // aqui você atribui a variável botão o id do elemento
  var botao = document.getElementById(el.id);

  botao.addEventListener('touchstart', function(e) {
        var toqueobj = e.changedTouches[0];
        inicialX = toqueobj.pageX;
  }, false);

});

========== Below is the previous answer =============

Taking into account that remark you made:

$(document).on('touchstart', 'AQUI É O PROBLEMA.. Queria aplicar o evento no alvo, no cartão que foi deslizado', function (){

    });

It is possible from there to select the target element, passing as second parameter the element you want, for example, as you are working with classes, then you would pass the class you placed to the buttons, and you can recover which button was dragged by this, and from there you can play at will, execute this code below and test what I did, from there I believe I can do what you want:

$(document).on('touchstart', '.botoes .atalhos-cartoneira', function (e){
    // acompoanhar no cosole o elemento alvo
    console.log(this)
    // aqui usei o toggleClass para trocar a classe s3 pela s9, ficando o elemento maior
    $(this).toggleClass('s3 s9')
    // aqui adiciono o classe lista-cartoneira
    $(this).addClass('lista-cartoneira')
    // aqui oculto os botões dos cartões, atacando o elememento i do fontawsome
    $('.botoes .atalhos-cartoneira i').hide(100);
    // aqui procuro pelo i do elemento alvo e exibo ele
    $(this).find('i').show(100);
    // aqui uso o position que fez
    $(this).css('position', 'relative');
});

I hope it helps, otherwise comment here.

  • My idea was to take the id and apply the events to that id, but it didn’t work: For example: var initilX; id.addeventlistener('touchstart', Function(e) { var toqueobj = e.changedTouches[0]; startX = toqueobj.pageX; }, false); //and so on..

  • then what you can do is create an id for each element added dynamically when listing them and use an equal class for them all to catch the id. I will edit my answer to better understand

  • as I enter through the append it does not recognize this $(". shortcuts-carton"). each(Function(index, el) { how could do?

  • It is because with the append the element is loaded later, so javascript does not recognize it. In this case, try this: $(". buttons"). find(". shortcuts-carton"). each(Function(index, el) {

Browser other questions tagged

You are not signed in. Login or sign up in order to post.