纯JavaScript替代切换CSS类的方法?

3

我的目标是在每次点击时将一个div旋转180度,而不用切换CSS类。

我可以通过第一次点击来实现一次旋转(.style.transform = "rotate(180deg)";),但是任何后续的点击都没有效果。

顺便问一下,为什么会这样呢?div的Id没有改变,所以理论上,相同的触发器(在这种情况下是点击)应该调用同一个函数,对吧?但是它没有。我想知道这里的逻辑是什么,有什么技术上的解释,另外,移动到实践,我如何进一步操作这个经过JavaScript处理的post-div(也就是原始div在其JavaScript处理之后)-- 同样,不用切换CSS类。

function rotate() {
    document.getElementById("container").style.transform = 
    "rotate(180deg)";
}
.container {
    width: 200px;
    height: 400px;
    border: 5px solid;
    border-bottom-color: blue;
    border-top-color: red;
}
<div class="container" id="container" onclick="rotate()"></div>

    


2
classListcontainerElement.classList.toggle("animate") - vsync
5
它只能使用一次,因为每次点击时变换不会增加。 - Paulie_D
4
切换HTML类(类属性不是CSS的一部分)是好的方法。它使关注点分离,并在DOM中提供有用的调试提示。 - Quentin
2
将旋转存储在数据属性中,在每次单击时增加它,并根据该值设置样式。 - Lain
6个回答

5
第一次将转换从""更改为"rotate(180deg)",这样它就会旋转。
后续更改从"rotate(180deg)""rotate(180deg)"...这根本不是更改,所以什么也不会发生。
如果你想要更改它,那么你需要实际分配一个不同的值。
例如:
const style = document.getElementById("container").style;
if (style.transform) {
    style.transform = "";
} else {
    style.transform = "rotate(180deg)";
}

切换类更简单,更清晰。

document.querySelector("#container").addEventListener("click", e => e.currentTarget.classList.toggle("rotated"));
.container {
  width: 200px;
  height: 400px;
  border: 5px solid;
  border-bottom-color: blue;
  border-top-color: red;
  transition: transform 0.25s;
}

.rotated {
  transform: rotate(180deg);
}
<div class="container" id="container"></div>


@Ruedi.Angehrn — 不,但问题中甚至没有暗示这是一个要求。我的陈述是关于目前存在的问题,而不是与之模糊相关的假设性问题。 - Quentin
你的评论有点像一个全局语句:“切换HTML类(类属性不是CSS的一部分)是一个好方法。它为你提供了关注点的分离和DOM中有用的调试提示。” - Ruedi.Angehrn
@Ruedi.Angehrn - 那个评论(在问题上,而不是这个答案上)再次是在这个问题的背景下给出的。 - Quentin

1
第一次调用函数后,div不旋转的原因是您将transform样式属性设置为固定值(180度)。在第一次调用之后,transform被执行并且所有后续调用都将transform设置为完全相同的值。为了使其工作,您必须每次调用函数时递增rotate属性。
例如:
let rotation = 0;

function rotate() {
    document.getElementById("container").style.transform =  `rotate(${rotation}deg)`;
    rotation = (rotation + 180) % 360;
}

我不喜欢这种方法,因为它只适用于我需要翻转一张图片的情况(由于只有一个未关联的变量包含旋转)。 - Lain

1
我制作了一个fiddle,但是基本上,你不能为相同的值旋转。当然这非常原始,但证明了这个概念,让你理解。你当然可以更加程序化地完成它。
document.getElementById('container').addEventListener('click', function () {
  this.style.transform = this.style.transform == "rotate(180deg)" ? "rotate(-90deg)" : "rotate(180deg)";
  }
);

你可以检查这个链接:tutorial

1
如果必须是this,为什么要分配obj - Lain
什么是问题?只是为了明确我们所引用的内容。它没有任何问题。 - Marco
1
这并不是错误,但完全没有必要。赋值和重新获取都是如此。在你的例子中,obj必须是this。因此,无需为其创建另一个getElementById()。此外,如果我将此侦听器分配给多个我想以相同方式旋转的元素,则您的逻辑将失败。 - Lain
Op要求只有一个div。就像我说的,这只是一个非常基本的例子,可以在编程上进行改进。但感谢您对优化代码的注意。 - Marco
为什么要点踩?这段代码完全符合 OP 提出的要求。有些人在这里尝试优化答案,但这并不是此网站的宗旨。 - Marco

1
你需要检查变换值,然后逆时针旋转它。
这里是代码:
HTML
<div class="container" id="container" onclick="rotate()"></div>

CSS (层叠样式表)
.container {
    width: 200px;
    height: 400px;
    border: 5px solid;
    border-bottom-color: blue;
    border-top-color: red;
}

JS

function rotate() {
    document.getElementById("container").style.transform = 
      document.getElementById("container").style.transform === 
    "rotate(180deg)" ? "rotate(0deg)" : "rotate(180deg)";
}

这里有一个例子在 codepen 上。


0
<script>
var degrees = 0;
function rotate() {
  if(degrees == 180){
    document.getElementById("container").style.transform = 
      "rotate(360deg)";
    degrees= 0;
  }else{
    document.getElementById("container").style.transform = 
      "rotate(180deg)";
    degrees= 180;
  }       
}
</script>

显然不是最优化的代码,但可以帮助你。

JSFiddle 这里


在这个例子中,使用变量 degrees 是没有意义的。而且它似乎并不能在第二次点击时切换回来(你的 fiddle 与这里的答案不符)。 - Lain
是的,我注意到了。 - Lain

0

其他人已经回答了你的问题,所以我将提供一个示例,使你的代码更加动态。

/**
* Rotate an <element> with a certain angle <rotateBy>
* 'this' is a reference to itself, which is passed by as an argument from the HTML.
* Change '180' in the method call to whatever to have it rotate differently.
*/

function rotate(element, rotateBy) {
  var currentRotation = element.rotation || 0;   // default to zero if not existing
      newRotation = rotateBy + currentRotation;

  element.rotation = newRotation;  // store the property in the element

  element.style.transform = "rotate(" + newRotation + "deg)";
}
.container {
    width: 200px;
    height: 400px;
    border: 5px solid;
    border-bottom-color: blue;
    border-top-color: red;

    transition: transform 400ms;
}
<div class="container" onclick="rotate(this, 180)"
></div>

    


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接