【问题标题】:Attempt to write jQuery fadeTo effect in Javascript尝试在 Javascript 中编写 jQuery fadeTo 效果
【发布时间】:2018-06-29 04:52:39
【问题描述】:

一个网站只使用一个 jQuery 函数,我们想用一个相等的纯 Javascript 函数替换它。但是我很难转换(翻译)该功能。 我知道 jQuery 非常适合该任务,但为几行 Javascript 下载所有 jQuery 代码的权衡可能值得付出努力——我没有成功。

脚本在做什么: 当悬停一个 sectionBox 时,所有其他 sectionBox(es) fadeTo 值为 0.4。 该脚本不使用分配给每个 SectionBox 的 ID。

问题是:如何在Javascript中处理children和siblings的等价物?

更新: 在做了一些功课之后,我想出了一些自己的功能代码,这与最终目标相去甚远,以实现相同的功能和平滑的过渡,但至少在功能上与 jQuery 代码中的现有功能相当。 我还改写了问题。

提供了一个非常棒的仅使用 CSS 的解决方案来解决该问题。但是我想了解是否以及如何用纯 Javascript 解决这个问题。

目前共有三列。左侧和中心列受我的作业代码影响,而右侧列使用原始 jQuery 代码。

我建议看看下面的例子来可视化预期的目标。

这里有几个问题

Q1:如何将函数组合成更少而更高效的函数? 这样悬停的元素就会包含三列中的所有元素。

在 Codepen 中运行代码可以观察到,当离开一列(左侧或中心)时,最后一个悬停的项目仍然具有低不透明度值。 Q2:如何控制这种行为?

/* --- code to convert ---*/
/*hover left column*/
/*$("#left").children().hover(function() {
  $(this).siblings().stop().fadeTo(300,0.4);
  $('#center > .sectionBox').stop().fadeTo(300,0.4);
  $('#right > .sectionBox').stop().fadeTo(300,0.4);
}, 
function() {
  $(this).siblings().stop().fadeTo(200,1);
  $('#center > .sectionBox').stop().fadeTo(200,1);
  $('#right > .sectionBox').stop().fadeTo(200,1);
});
*/

/* --- attempt to convert jQuery code from above ---*/
/* --- currently affecting left- and center-columns only --- */
/* --- How to combine functions into less and more efficient functions */
/*
var elem_IDLft = 'left'
var elem_IDCtr = 'center'
var elem_IDRgt = 'right'
*/
/* --- LEFT Column ---*/
var elemLft_ID = 'left'
var elemL_name = document.getElementById(elemLft_ID).children;
var elemL_length = elemL_name.length;

for (var i=0; i<elemL_length; i++) {
  elemL_name[i].addEventListener("mouseover", mouseOverL);
  elemL_name[i].addEventListener("mouseout", mouseOutL);
}
/*---mouse events---*/
/*---Don't use: style.display = "none"--*/
//function mouseOver() {this.style.opacity = "1.0";}
//function mouseOut() {this.style.opacity = "0.4";}

function mouseOverL() {
  for (var i=0; i<elemL_length; i++) {
    if (elemL_name[i] === this) {elemL_name[i].style.opacity = "1.0";} 
  else {elemL_name[i].style.opacity = "0.5";}
  }
  return;
}

function mouseOutL() {
  for (var i=0; i<elemL_length; i++) {
    if (elemL_name[i] !== this) {elemL_name[i].style.opacity = "1.0";} 
  else {elemL_name[i].style.opacity = "0.5";}
  }
  return;
}

// --- To-Do: smooth Transitions

/* --- CENTER Column ---*/
var elemCtr_ID = 'center'
var elem_name = document.getElementById(elemCtr_ID).children;
var elem_length = elem_name.length;

for (var i=0; i<elem_length; i++) {
  elem_name[i].addEventListener("mouseover", mouseOver);
  elem_name[i].addEventListener("mouseout", mouseOut);
}
/*---mouse events---*/
/*---Don't use: style.display = "none"--*/
//function mouseOver() {this.style.opacity = "1.0";}
//function mouseOut() {this.style.opacity = "0.4";}

function mouseOver() {
  for (var i=0; i<elem_length; i++) {
    if (elem_name[i] === this) {elem_name[i].style.opacity = "1.0";} 
  else {elem_name[i].style.opacity = "0.5";}
  }
  return;
}

function mouseOut() {
  for (var i=0; i<elem_length; i++) {
    if (elem_name[i] !== this) {elem_name[i].style.opacity = "1.0";} 
  else {elem_name[i].style.opacity = "0.5";}
  }
  return;
}

/* --- Question: How to properly get the inverse for the above 'this' ?---*/
/* --- So that the element 'this' (hovered) has style.opacity = 1 ---*/
/* --- and all others from elem_name get style.opacity = 0.4 --- */
/* --- At the moment it's really bumpy --- */
/* --- Possibly caused by many forced reflows while executing Javascript occur --- */
/* --- The goal is to obtain smooth transitions ---*/

/*-------------------------------------*/
/*--- more jQuery code for columns 'center' and 'right' ---*/
/*--- center column*/
/*
$("#center").children().hover(function() {
  $(this).siblings().stop().fadeTo(300,0.4);
  $('#left > .sectionBox').stop().fadeTo(300,0.4);
  $('#right > .sectionBox').stop().fadeTo(300,0.4);
}, 
function() {
  $(this).siblings().stop().fadeTo(200,1);
  $('#left > .sectionBox').stop().fadeTo(200,1);
  $('#right > .sectionBox').stop().fadeTo(200,1);
});
*/
/*--- right column*/
$("#right").children().hover(function() {
  $(this).siblings().stop().fadeTo(300,0.4);
  $('#center > .sectionBox').stop().fadeTo(300,0.4);
  $('#left > .sectionBox').stop().fadeTo(300,0.4);
}, 
function() {
  $(this).siblings().stop().fadeTo(200,1);
  $('#center > .sectionBox').stop().fadeTo(200,1);
  $('#left > .sectionBox').stop().fadeTo(200,1);
});
/*liquid display*/
body {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:62.5%;}
html {font-size:10px; color:#fff; background-color:#242424;}

#wrapper {width: 100%;font-size: 1.2rem; overflow: hidden}
.column {float: left; width: 31.0%; margin-right: 3.5%;} /* 100%-(3*31%)=7%/2=3.5%*/
.last {margin-right: 0;}

h1 {font-size: 1.2rem; text-align:center;padding:-1rem;}
@media screen and (max-width: 800px) {#left.column, #center.column, #right.column {width: 100%;}}

.sectionBox {
background-color: rgba(100,100,100,1.0);
box-shadow: 5px 5px 7px #111;
margin: 0 0 2.0rem 0;
padding: 0.1rem;
}

.sectionBox > p > code {background-color:#efefef; color:#111;}

#left {color:#fffaaa;}
#center {color:#fffccc;}
#right {color:#fffeee;}
<div id="wrapper">
  <div class="sectionBox"><h1>Flexbox - fadeTo - transition: from jQuery to pure Javascript</h1>
    <p><strong>An attempt to translate this jQuery 'fadeTo'-function to pure Javascript.</strong>
      <br />
      <code>
    /*hover left column*/<br>
$("#left").children().hover(function() {
  $(this).siblings().stop().fadeTo(300,0.4);
  $('#center > .sectionBox').stop().fadeTo(300,0.4);
  $('#right > .sectionBox').stop().fadeTo(300,0.4);
}, 
function() {
  $(this).siblings().stop().fadeTo(200,1);
  $('#center > .sectionBox').stop().fadeTo(200,1);
  $('#right > .sectionBox').stop().fadeTo(200,1);
});      
    </code>
    </p>
</div>
  
  <div id="left" class="column">id="left"
    <section class="sectionBox"><h1>id="newPictures"</h1>
		</section>
    <section class="sectionBox"><h1>id="oldPictures"</h1>
		</section>
		<section class="sectionBox"><h1>id="somePlace"</h1>
		</section>
		<section class="sectionBox"><h1>id="someOtherPlace"</h1>
		</section>
	</div>

  <div id="center" class="column">id="center"
		<section class="sectionBox"><h1>id="travelNews"</h1>
		</section>
		<section class="sectionBox"><h1>id="otherTravelNews"</h1>
		</section>
		<section class="sectionBox"><h1>id="impressum"</h1>
		</section>
	</div>

  <div id="right" class="column last">id="right"
		<section class="sectionBox"><h1>id="search"</h1>
		</section>
		<section class="sectionBox"><h1>id="toolsFaq"</h1>
		</section>
	</div>
</div>	<!--.wrapper-->

这是相关 jQuery 代码的工作示例。

/*hover left column*/
$("#left").children().hover(function() {
  $(this).siblings().stop().fadeTo(300,0.4);
  $('#center > .sectionBox').stop().fadeTo(300,0.4);
  $('#right > .sectionBox').stop().fadeTo(300,0.4);
}, 
function() {
  $(this).siblings().stop().fadeTo(200,1);
  $('#center > .sectionBox').stop().fadeTo(200,1);
  $('#right > .sectionBox').stop().fadeTo(200,1);
});

/*hover center column*/
/*same function for "#center" and "#right" columns*/

... 这是与 codepen 相同的代码。 Link to Codepen

【问题讨论】:

  • 从 jQuery 和 viola 中提取并复制粘贴相关代码 - 您可以在没有 jQuery 的情况下使用跨浏览器 fadeTo ...
  • 请注意,jQuery 是一个 JavaScript 库,所以是的,它应该是可能的。
  • @davidkonrad - 抱歉,我不明白。 “提取和复制粘贴”到底是什么意思。代码在这里,从哪里提取什么,然后复制到哪里?我很困惑。
  • @snahl 检查下面的答案,不需要为此使用任何 javascript ;)
  • @facundo-forradini - 该函数影响问题中指出的至少 2 个 DIV:当将一个 sectionBox 悬停时,所有其他 sectionBox(es) fadeTo 值为 0.4。

标签: javascript jquery html css onhover


【解决方案1】:

您可以使用Element.animate()

const div = document.getElementById("animate");

div.onclick = () => {
  div.animate({
      opacity: 0
    }, {
      duration: 1000,
      easing: "linear",
      iterations: 1,
      fill: "both"
    })
    .onfinish = function() {     
      console.log(div.style.opacity);         
    }
}
#animate {
  width: 50px;
  height: 50px;
  background: blue;
  color: gold;
}
&lt;div id="animate"&gt;click&lt;/div&gt;

【讨论】:

  • @AngelPolitis 使用 --enable-experimental-web-platform-features 标志启动 Chrome 时的结果是什么?
  • 通过启用--enable-experimental-web-platform-features 标志它可以工作,所以你赢得了我的支持!但是,恐怕它目前对 OP 或任何生产网站都没有用。
【解决方案2】:

你不需要 jQuery... 你甚至不需要 javascript。

纯 CSS 就可以了:

/*liquid display*/
body {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:62.5%;}
html {font-size:10px; color:#fff; background-color:#242424;}
#wrapper {overflow: hidden; width: 100%;}
.column {float: left; width: 31.0%; margin-right: 3.5%;} /* 100%-(3*31%)=7%/2=3.5%*/
.last {margin-right: 0;}
@media screen and (max-width: 800px) {#left.column, #center.column, #right.column {width: 100%;}}

.sectionBox {
font-size: 1.6rem;
background-color: rgba(100,100,100,1.0);
box-shadow: 5px 5px 7px #111;
margin: 0 0 1.5rem 0;
padding: 0.5rem 0.3rem 0.5rem 0.3rem;
opacity:1; /* set initial opacity and transition time*/
transition:opacity 200ms ease; /*for when hover-out*/
}

#left {color:#fffaaa;}
#center {color:#fffccc;}
#right {color:#fffeee;}


#wrapper{
  pointer-events: none; /*prevents the :hover from firing*/
}                       /*when not actually on an item */
.sectionBox{
  pointer-events:auto; /*resets the hover on the items */
}
#wrapper:hover .sectionBox{
  opacity:0.4; /*when hovering the container, all items becomes translucent*/
  transition: opacity 300ms ease;
}

#wrapper:hover .sectionBox:hover{
  opacity:1; /*prevents the specific hovered item opacity from changing*/
}
<div id="wrapper"> 
	<div id="left" class="column">
		<section class="sectionBox"> id="newPictures"
		</section>
		<section class="sectionBox"> id="oldPictures"
		</section>
		<section class="sectionBox"> id="somePlace"
		</section>
	</div>
	<div id="center" class="column">
		<section class="sectionBox"> id="travelNews"
		</section>
		<section class="sectionBox"> id="impressum"
		</section>
	</div>

	<div id="right" class="column last">
		<section class="sectionBox"> id="search"
		</section>
		<section class="sectionBox"> id="toolsFaq"
		</section>
	</div>
</div>

诀窍是使用容器上的悬停来调整所有孩子的不透明度,同时将指针事件设置为无,这样它就不会在实际上不在孩子上方时触发。 然后它只是使用悬停在特定子项上将不透明度重置为 1,并调整过渡。

100% 纯 CSS 魔法 FTW!

【讨论】:

  • 太好了,谢谢!这工作得很好。我在我的网站上对我的菜单使用相同的方法,但我不知道 CSS 指针事件:包含层次结构中更高的元素。这不是对我的问题的直接答案,但它是一个非常好的解决方案,可以达到目的并解决导致我的问题的问题。所以我给你投票。但是我做了很多功课,很想知道如何在纯 Javascript 中实现同样的目标。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多