【问题标题】:Is it possible to change the class of an element if the class of another elements equals to sth?如果另一个元素的类等于某物,是否可以更改元素的类?
【发布时间】:2021-09-24 15:43:21
【问题描述】:

如果另一个元素的classList 等于“某事”,我想删除/添加某个元素的classList。但是有一个小问题,它只运行一次命令,我的意思是条件不会每秒检查第一个元素的classList,所以它运行它没有任何问题。如果 if 为真,则它运行 if 条件,然后它不会检查 else if 并因此反向。

这是我的代码:

const dToggle = () => {
  const firstElm = document.querySelector('.firstElm');
  
  firstElm.classList.toggle('red-border');
};

document.querySelector('button').addEventListener('click', dToggle);

const orangeOrRed = () => {
    const firstElm = document.querySelector('.firstElm');
    const secondElm = document.querySelector('.secondElm');

    firstElm.classList === 'red-border' ? secondElm.classList.add('red') : secondElm.classList.add('orange');
    
    // if (firstElm.classList === 'red-border') {
    //        secondElm.classList.remove('orange');
    //        secondElm.classList.add('red');
    // } else if (firstElm.classList === 'orange-border' {
    //        secondElm.classList.remove('red');
    //        secondElm.classList.add('orange');
    // };
};

// Maybe the exact problem is right here.
window.addEventListener('load', orangeOrRed);

console.log(document.querySelector('.secondElm').classList.value);
.d-none {
  display: none !important;
}

.firstElm {
  margin-top: 10px;
  width: 200px;
  height: 100px;
  background-color: blue;
 }
 
.orange-border {
  border: orange 3px solid;
}
 
.red-border {
  border: red 3px solid;
}
 
.secondElm {
  margin-top: 10px;
  width: 200px;
  height: 100px;
  background-color: green;
}

.orange {
  background-color: orange !important;
}

.red {
  background-color: red !important;
}
<button type="button" style="cursor: pointer;">Click here.</button>
<p>It should run the conditional statement whenever I click on the button to apply the border.</p>
<p> First Elm Border Color (MUST BE) Second Elm Background Color</p>
<div class='firstElm orange-border'></div>
<div class='secondElm'></div>
<p style="padding-bottom: 10px;">Remember that I only want to do this with(conditioal statements), It's possible either with classList.toggle() but I don't want to.</p>

【问题讨论】:

  • 还是有点难以理解。 there is a little problem that it only runs the command once, I mean the condition doesn't check the classList of the first element every second so it runs it without any problem. 也许你可以改写一下。还有你的 if else 代码相关还是条件运算符与代码更相关?
  • 值得指出的是,您的按钮事件侦听器都没有 if 条件,并且始终运行相同。并且您的窗口加载侦听器将始终运行一次。我希望这是你想要的。
  • 如果您希望代码在类更改时运行,请在您更改类的代码中调用该函数。或者使用MutationObserver,知道它可能会降低您的网站速度。同样classListDOMTokenList,而不是字符串,所以firstElm.classList 永远不会等于'red-border'。你应该使用classList.contains('red-border')
  • If you want your code to run when the class changes, call the function in your code where you change the class. 是什么意思? @HereticMonkey
  • 我的意思是,如果您的代码更改了这些元素的 classList,请在该函数中调用 orangeOrRed()

标签: javascript html css if-statement conditional-statements


【解决方案1】:

这里有三个问题:

1.检查错误的条件

classList 是一个 DOMTokenList,它有一个 contains 方法,如果元素具有所需的 className,则返回 true,反之亦然

2.多次添加相同的 className 而不会删除旧的

如果要添加 red 类名,则需要删除 orange 类名,反之亦然

3. orangeOrRed 函数只运行一次

orangeOrRed 函数只在窗口的加载事件中运行一次

你需要为按钮的点击事件添加相同的事件监听器

const dToggle = () => {
  const firstElm = document.querySelector('.firstElm');
  firstElm.classList.toggle('red-border');
};

document.querySelector('button').addEventListener('click', dToggle);

const orangeOrRed = () => {
    const firstElm = document.querySelector('.firstElm');
    const secondElm = document.querySelector('.secondElm');

    if (firstElm.classList.contains('red-border')) {
            secondElm.classList.remove('orange');
            secondElm.classList.add('red');
    } else if (firstElm.classList.contains('orange-border')) {
            secondElm.classList.remove('red');
            secondElm.classList.add('orange');
    };
};

// You're right, the exact problem is right here.
window.addEventListener('load', orangeOrRed);
document.querySelector('button').addEventListener('click', orangeOrRed);

console.log(document.querySelector('.secondElm').classList.value);
.d-none {
  display: none !important;
}

.firstElm {
  margin-top: 10px;
  width: 200px;
  height: 100px;
  background-color: blue;
 }
 
.orange-border {
  border: orange 3px solid;
}
 
.red-border {
  border: red 3px solid;
}
 
.secondElm {
  margin-top: 10px;
  width: 200px;
  height: 100px;
  background-color: green;
}

.orange {
  background-color: orange !important;
}

.red {
  background-color: red !important;
}
<button type="button" style="cursor: pointer;">Click here.</button>
<p>It should run the conditional statement whenever I click on the button to apply the border.</p>
<p> First Elm Border Color (MUST BE) Second Elm Background Color</p>
<div class='firstElm orange-border'></div>
<div class='secondElm'></div>
<p style="padding-bottom: 10px;">Remember that I only want to do this with(conditioal statements), It's possible either with classList.toggle() but I don't want to.</p>

使用MutationObserver API 获得相同的结果。

当您没有切换按钮或无法控制元素的类名何时更改时,它很有用。

const firstElm = document.querySelector('.firstElm');
const secondElm = document.querySelector('.secondElm');

const orangeOrRed = () => {
    if (firstElm.classList.contains('red-border')) {
            secondElm.classList.remove('orange');
            secondElm.classList.add('red');
    } else if (firstElm.classList.contains('orange-border')) {
            secondElm.classList.remove('red');
            secondElm.classList.add('orange');
    };
}

// Callback function to execute when mutations are observed
const callback = (mutationsList) => {  
  // check to see if the changed attribute that caused the mutationObserver callback to be called is the class attribute and run the desired code
  if (mutationsList[0].attributeName === 'class') orangeOrRed();
};

// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);

// Options for the observer (which mutations to observe)
// Here the MutationObserver will call the specified callback just if attributes of the target node have changed
const config = { attributes: true, childList: false, subtree: false };

// Start observing the target node (firstElm) for configured mutations
observer.observe(firstElm, config);

const dToggle = () => {
  firstElm.classList.toggle('red-border');
};

document.querySelector('button').addEventListener('click', dToggle);

// You're right, the exact problem is right here.
window.addEventListener('load', orangeOrRed);
.d-none {
  display: none !important;
}

.firstElm {
  margin-top: 10px;
  width: 200px;
  height: 100px;
  background-color: blue;
 }
 
.orange-border {
  border: orange 3px solid;
}
 
.red-border {
  border: red 3px solid;
}
 
.secondElm {
  margin-top: 10px;
  width: 200px;
  height: 100px;
  background-color: green;
}

.orange {
  background-color: orange !important;
}

.red {
  background-color: red !important;
}
<button type="button" style="cursor: pointer;">Click here.</button>
<div class='firstElm orange-border'></div>
<div class='secondElm'></div>
<p style="padding-bottom: 10px;">Remember that I only want to do this with(conditioal statements), It's possible either with classList.toggle() but I don't want to.</p>

【讨论】:

  • 这是它唯一需要正常工作的东西。 document.querySelector('button').addEventListener('click', orangeOrRed); merci ;) 但是如果我没有任何按钮可以使用 addEventListener 我的意思是你将无法点击 sth 来运行 func,然后呢?
  • 不客气。我很高兴能帮上忙。如果您没有可以点击的按钮,那么您可以使用MutationObserver。我明天将使用MutationObserver API 发布答案。
【解决方案2】:

您误解了这里的问题;不是条件没有运行,而是它检查了错误的东西。

您正在查看 DOM 元素是否为 classList === 'orange-border',但这永远不会是真的; classList 不是一个简单的字符串。你想要的是看看 classList includes orange-border.

const dToggle = () => {
  const firstElm = document.querySelector('.firstElm');

  firstElm.classList.toggle('red-border');
};

document.querySelector('button').addEventListener('click', dToggle);

const orangeOrRed = () => {
    const firstElm = document.querySelector('.firstElm');
    const secondElm = document.querySelector('.secondElm');

    // I'm not sure why you have both this ternary and the similar if:else below, but I've fixed both to at least be checking the classList correctly:
    firstElm.classList.contains('red-border') ? secondElm.classList.add('red') : secondElm.classList.add('orange');


    if (firstElm.classList.contains('red-border')) {
      secondElm.classList.remove('orange');
      secondElm.classList.add('red');
    } else if (firstElm.classList.contains('orange-border')) {
        secondElm.classList.remove('red');
        secondElm.classList.add('orange');
      };
    };

    window.addEventListener('load', orangeOrRed);

console.log(document.querySelector('.secondElm').classList.value);
.d-none {
  display: none !important;
}

.firstElm {
  margin-top: 10px;
  width: 200px;
  height: 100px;
  background-color: blue;
}

.orange-border {
  border: orange 3px solid;
}

.red-border {
  border: red 3px solid;
}

.secondElm {
  margin-top: 10px;
  width: 200px;
  height: 100px;
  background-color: green;
}

.orange {
  background-color: orange !important;
}

.red {
  background-color: red !important;
}
<button type="button" style="cursor: pointer;">Click here.</button>
<p>It should run the conditional statement whenever I click on the button to apply the border.</p>
<p> First Elm Border Color (MUST BE) Second Elm Background Color</p>
<div class='firstElm orange-border'></div>
<div class='secondElm'></div>
<p style="padding-bottom: 10px;">Remember that I only want to do this with(conditioal statements), It's possible either with classList.toggle() but I don't want to.</p>

【讨论】:

    猜你喜欢
    • 2021-08-10
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 2017-04-04
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    • 2017-03-15
    相关资源
    最近更新 更多