Supuestamente mi explicación fue demasiado complicada, así que intentaré simplificar lo que quiero:

EDITADO:

Solo intento entender cómo funciona exactamente on () . ¿Por qué los eventos off () desvincular 'mouseover mouseout' de la segunda LI se mencionan a continuación?

$('.li').on('mouseover mouseout',changeBorder);
$('.li:nth-child(2)').off('mouseover mouseout',changeBorder);

Mientras que no se menciona abajo () no desvincula eventos 'mouseover mouseout' para el segundo LI ??

$('#container').on('mouseover mouseout', '.li',changeBorder);
$('.li:nth-child(2)').off('mouseover mouseout',changeBorder);

Quiero usar el primer método porque tengo la intención de agregar otro LI dinámicamente en el futuro, por lo que el segundo método no vinculará eventos para LI futuros, solo para los existentes. Por supuesto, puedo vincular eventos para cada nuevo LI agregado dinámicamente mientras creo y agrego eso, pero estoy buscando una forma más elegante de hacerlo :) Entonces, de acuerdo con el ejemplo a continuación, quiero que el segundo LI no reaccione mouseover, pero reacciona como puede ver a pesar de que lo desactivé () '.

$('#container').on('mouseover mouseout', '.li',changeBorder);
$('.li:nth-child(2)').off('mouseover mouseout',changeBorder);

//$('.li').on('mouseover mouseout',changeBorder);
//$('.li:nth-child(2)').off('mouseover mouseout',changeBorder);

function changeBorder(event){
  if(event.type==='mouseover'){
    	$(event.target).css('border','dotted 2px #33aaff');
  	} else {
  		$(event.target).css('border','none');
  	}
}
.li {
  width:200px;
  list-style-type:none;
  background-color:#efefef;
  padding:6px;
  margin:3px;
  border-radius:3px;
  cursor:pointer;
  color:#aaa;
  font-size:20px;
  outline:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="container">
  <li class="li" contenteditable>sample A</li>
  <li class="li" contenteditable>sample B</li>
  <li class="li" contenteditable>sample C</li>
  <li class="li" contenteditable>sample D</li>
</ul>
0
Paweł 13 dic. 2016 a las 06:53

2 respuestas

La mejor respuesta

Si te entendí correctamente, esto podría funcionar para ti ... y es mucho menos complicado que tu código. No hay necesidad de vincular / desvincular controladores de eventos repetidamente.

https://developer.mozilla.org/de/docs/Web/API/Document/activeElement

$(document).on('mouseenter', '.everyFutureItem', function(e){
  // ad border only if elmt is not the activeElement 
  if (e.target != document.activeElement) {
    $(e.target).css('border','dotted 2px #33aaff');
  }
});

$(document).on('mouseleave click', '.everyFutureItem', function(e){ 
  $(e.target).css('border','none');
});
.everyFutureItem {
  width:200px;
  list-style-type:none;
  background-color:#efefef;
  padding:6px;
  margin:3px;
  border-radius:3px;
  cursor:pointer;
  color:#aaa;
  font-size:20px;
  outline:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="container">
  <li class="everyFutureItem" contenteditable>sample A</li>
  <li class="everyFutureItem" contenteditable>sample B</li>
  <li class="everyFutureItem" contenteditable>sample C</li>
  <li class="everyFutureItem" contenteditable>sample D</li>
</ul>
1
Flyer53 13 dic. 2016 a las 09:30

La explicación de OP del comportamiento deseado no está clara, para acelerar las cosas, aquí hay un resumen de lo que interpreté:

  1. El usuario señala el segundo <li> [mouseover]

  2. Se invoca al controlador (es decir, changeBorder()), se crea un borde en el segundo <li>

  3. El usuario hace clic con el mouse en el segundo <li> [focus]

  4. El usuario mueve el mouse fuera del segundo <li> [mouseout]

  5. El borde del segundo <li> todavía está allí porque los eventos mouseout y mouseover se desvincularon del segundo <li> antes de que ocurriera el paso 4.

  6. Al regresar el mouse a la segunda <li>, ya no se activan eventos mouseout o mouseover.

  7. Al salir del segundo <li> y hacer clic fuera del segundo <li>, ocurrió un evento de blur.

  8. El segundo <li> rebota a los eventos mouseover y mouseout.

En la documentación de la API de jQuery - .on()

Agregar o eliminar controladores de eventos en el elemento actual no tendrá efecto hasta la próxima vez que se maneje el evento.

Tenga en cuenta la secuencia de eventos y sepa que agregar / eliminar eventos delegados no se aplica hasta el siguiente momento en que se maneja el evento. Entonces, en un escenario donde:

  1. El usuario señala el segundo <li> [mouseover]

  2. Se invoca al controlador (es decir, changeBorder()), se crea un borde en el segundo <li>

  3. El usuario hace clic con el mouse en el segundo <li> [focus]

  4. El usuario mueve el mouse fuera del segundo <li> [mouseout]

  5. Los segundos bordes <li> se han ido.

  6. El controlador no está vinculado, pero no parece que haya funcionado porque el borde todavía se está haciendo como si changeBorder() todavía funciona, lo que implica que el segundo { {X1}} todavía está vinculado a eventos de mouseover y mouseout.

  7. Para detener este comportamiento, debe activar otro evento focus en el segundo <li>. [focus] .

/* Using the direct selector to the <li> */
$('.edit').on({
  /* Mapping events */
  mouseover: activate,
  mouseout: activate,
  focus: function(e) {
    console.log(e.type);
    $(this).off('mouseover mouseout', activate);
  },
  blur: function(e) {
    console.log(e.type);
    $(this).on('mouseover mouseout', activate);
  }

});

/* Checks to see if event target has class .off... */
/* ...and removes .off and adds .on class... */
/* ...otherwise remove .on and add .off class */
function activate(e) {
  console.log(e.type);
  var tgt = $(e.target);
  tgt.hasClass('off') ? tgt.addClass('on').removeClass('off') : tgt.addClass('off').removeClass('on');
}
.edit {
  width: 200px;
  list-style-type: none;
  background-color: #efefef;
  padding: 6px;
  margin: 3px;
  border-radius: 3px;
  cursor: pointer;
  color: #aaa;
  font-size: 20px;
  outline: none;
}
/* Two state classes */

.on {
  border: 2px dotted #33aaff;
}
.off {
  border: 0 none transparent;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="list1">
  <li class="edit off" contenteditable>sample A</li>
  <li class="edit off" contenteditable>sample B</li>
  <li class="edit off" contenteditable>sample C</li>
  <li class="edit off" contenteditable>sample D</li>
</ul>
1
zer00ne 13 dic. 2016 a las 09:29