javascript - Text Fade Effect with Animate.css - unexplained behavior -


the goal display text (html) in div tag fade in/ fade out effect on mouse over/ out events triggered element(s). used animate.css solution , came across multitude of problems, when elements hovered in rapid succession. when tried build simpler model, without resorting jquery, unlike original solution, 1 part of code behavior inexplicable me - please see below example. works expected, if following line document.getelementbyid("info").innerhtml="animate.css has ended; triggered "+e.target.id+" on "+e.type+" event."; omitted, events triggered animation function not recognized , text hides on mouseover. changing innerhtml of element understanding has nothing animationend event, hope can explain code behavior.

// (e), event used differentiate between mouseover , mouseout  function animate(e){  	// start mesage  	document.getelementbyid("info").innerhtml=e.target.id+" fired "+e.type+"; animate.css starting...";  	// setting animation type based on triggering event  	var animation = "animated fadein";  	if (e.type=="mouseout"){  	animation = "animated fadeout";  	}  	// triggering animation applying animation classes  	document.getelementbyid("info").setattribute("class", animation);  	// setting animation end callback  	this.addeventlistener("animationend", function(){  	// end message. if line below commented, message deleted regardless of event fired (it expected deleted on mouseout only)  	document.getelementbyid("info").innerhtml="animate.css has ended; triggered "+e.target.id+" on "+e.type+" event.";  	// removing (regenerating) animation classes		  	document.getelementbyid("info").removeattribute("class");  	// deletes message on mouseout	  	if (e.type=="mouseout"){  	document.getelementbyid("info").innerhtml="null";  	}  	});  }	    // svg path elements trigger animate(event) function on mouseover , mouseout  var petals = document.queryselectorall("path");  for(i=0;i<petals.length; i++){  //changes default mouse cursor hand  petals[i].style="cursor: pointer;";  //mouseover  petals[i].addeventlistener("mouseover", function (event){  animate(event);  });  //mouseout  petals[i].addeventlistener("mouseout", function (event){  animate(event);  });  }
<style>  html, body {  	height: 100%;  	margin: 0px;  }  #info {  	height: 15%;  	/*	background-color: darkgreen;  	color: gainsboro;*/  	font-family: monospace;  	font-size: 5.5vh;  	padding: 2%;  }  /* animate.css: */  .animated {  	animation-duration: 2s;  	animation-fill-mode: both;  }  .animated.fadeout {  	animation-duration: 3s;  }   @keyframes fadeout {   {   opacity: 1;  }   {   opacity: 0;  }  }  .fadeout {  	animation-name: fadeout;  }   @keyframes fadein {   {   opacity: 0;  }   {   opacity: 1;  }  }  .fadein {  	animation-name: fadein;  }  </style>
<div id="info"> info </div>  <div style="height: 70%; background-color:papayawhip; padding: 1.5%;">  	<svg width="100%" height="100%" version="1.1" id="layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"  	 viewbox="0 0 318.3 258.1" style="enable-background:new 0 0 318.3 258.1;" xml:space="preserve">  		<style type="text/css">  .darkred{  fill: darkred;  stroke-width: 1;  }  .darkred:hover{  fill: red;  stroke: black;  }  .red{  fill: red;  }  .red:hover {  fill: orange;  stroke: black;  }  .orange{  fill: orange;  }  .orange:hover {  fill: yellow;  stroke: black;  }    </style>  		<path id="petal-1" class="darkred" d="m159.1,1c53.3,42.7,53.3,85.3,0,128v1z"/>  		<path id="petal-2" class="orange" d="m213.8,8.8c31.9,54.7,13.6,94.8-54.7,120.3l213.8,8.8z"/>  		<path id="petal-3" class="red" d="m262,31c6.6,60.1-27.7,92.8-102.8,98.1l262,31z"/>  		<path id="petal-4" class="darkred" d="m297.7,65c-19.5,58.3-65.7,79.6-138.6,64l297.7,65z"/>  		<path id="petal-5" class="orange" d="m316.7,106.8c-43.3,49.4-95.8,56.8-157.6,22.2l316.7,106.8z"/>  		<path id="petal-6" class="red" d="m316.7,151.3c-61.8,34.6-114.3,27.2-157.6-22.2l316.7,151.3z"/>  		<path id="petal-7" class="darkred" d="m297.7,193c-72.9,15.6-119-5.7-138.6-64l297.7,193z"/>  		<path id="petal-8" class="orange" d="m262,227.1c-75.1-5.3-109.4-37.9-102.8-98.1l262,227.1z"/>  		<path id="petal-9" class="red" d="m213.8,249.3c-68.4-25.5-86.6-65.6-54.7-120.3l213.8,249.3z"/>  		<path id="petal-10" class="darkred" d="m159.1,257c-53.3-42.7-53.3-85.3,0-128v257z"/>  		<path id="petal-11" class="orange" d="m104.4,249.3c-31.9-54.7-13.6-94.8,54.7-120.3l104.4,249.3z"/>  		<path id="petal-12" class="red" d="m56.3,227.1c49.7,167,84,134.3,159.1,129l56.3,227.1z"/>  		<path id="petal-13" class="darkred" d="m20.5,193c19.5-58.3,65.7-79.6,138.6-64l20.5,193z"/>  		<path id="petal-14" class="orange" d="m1.5,151.3c43.3-49.4,95.8-56.8,157.6-22.2l1.5,151.3z"/>  		<path id="petal-15" class="red" d="m1.5,106.8c63.3,72.2,115.8,79.6,159.1,129l1.5,106.8z"/>  		<path id="petal-16" class="darkred" d="m20.5,65c72.9-15.6,119,5.7,138.6,64l20.5,65z"/>  		<path id="petal-17" class="orange" d="m56.3,31c75.1,5.3,109.4,37.9,102.8,98.1l56.3,31z"/>  		<path id="petal-18" class="red" d="m104.4,8.8c172.7,34.3,191,74.4,159.1,129l104.4,8.8z"/>  	</svg>  </div>

the behavior observing not caused events not being recognized, rather because of order in callback functions being executed.

let me try explain this...

when comment out line document.getelementbyid("info").innerhtml="animate.css has ended; triggered "+e.target.id+" on "+e.type+" event.";, get:

the setup

for every mouseover , mouseout event, calling two functions:

  1. animate(e), displays text in div, , starts animation.
  2. anonymous function() executed on animationend, check if e.type == 'mouseout'. if is, change text in div 'null', otherwise, not change text @ all. (if comment out line mentioned above.)

however, , important, first function called event triggered, , second 1 callback function called after animation has ended.

hovering on elements in rapid succession

when hover on petal a, , jump petal b, may not have realize, there three events happening:

  1. there mouseover event on petal a
  2. there mouseout event on petal a
  3. there mouseovoer event on petal b

each of these events, end calling 2 functions, however, since second function called once animation complete, functions executed in following order:

  1. mouseover(petal a) calls animate(e)
  2. mouseout(petal a) calls aminate(e)
  3. mouseover(petal b) calls animate(e)
  4. animationend mouseover(petal a) calls anonymous function()
  5. animationend mouseout(petal a) calls anonymous function()
  6. animationend mouseover(petal b) calls anonymous function()

let's examine how effects text in div:

  • at step 1-3 div display event target id, event type, , 'animate.css starting...'.

  • at step 4 nothing in div change, since event type mouseover. div continue display event target id, event type, , 'animate.css starting...', expected.

  • at step 5 text in div change 'null', because animation triggered mouseout event.

  • at step 6, again, nothing in div change, since event type mouseover. div continue display 'null'...

proof of concept

to prove this, can either add event target id text, , see previous petal caused 'null' displayed, , not petal hovering over. or, use if {} else {}, change text in div on animationend if e.type not equal mouseout, , you'll see there no confusion here on event was.

if (e.type=="mouseout"){     document.getelementbyid("info").innerhtml="null " + e.target.id; } else {     document.getelementbyid("info").innerhtml="this animationend of " + e.type + " event"; }  

important note:

an event listener added dom not removed, unless explicitly remove it, or add once: true option.

since adding event listener listen animationend on every mouseover , mouseout event, without ever removing it, end dozens of event listeners triggering same callback function on animationend.

this can fixed adding once: true option argument addeventlistener(). automatically remove listener callback function invoked.

function animate(e){      document.getelementbyid("info").innerhtml=e.target.id+" fired "+e.type+"; animate.css starting...";      var animation = "animated fadein";     if (e.type=="mouseout"){         animation = "animated fadeout";     }            document.getelementbyid("info").setattribute("class", animation);      this.addeventlistener("animationend", function() {                           document.getelementbyid("info").removeattribute("class");          if (e.type=="mouseout"){             document.getelementbyid("info").innerhtml="null ";         }      }, {once: true}); // add option automatically remove event listener once invoked } 

Comments

Popular posts from this blog

python Tkinter Capturing keyboard events save as one single string -

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

javascript - VueJS2 and the Window Object - how to use? -