切换按钮和文本:工作正常,但想简化代码,因为它太长太长了

toggle button and text : working fine, but want to simplified the code as its too long and lengthy

提问人:Be Always Mine 提问时间:8/2/2023 最后编辑:Alive to die - AnantBe Always Mine 更新时间:8/25/2023 访问量:93

问:

我有一些盒子,里面有很多信息。起初,我想要更少的信息,如果用户想阅读更多信息,他们会单击“查看更多”按钮。然后,如果他们单击该按钮,将显示名为“复制”的按钮,并且名为“查看更多”的按钮将通过innerHTML更改为“查看更少”。

下面的代码工作正常,但有很多代码。是否有可能使代码更短?



<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Page title</title>

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

</head>

<body>

    <div class="wrapper">

<div class="box">

    <div class="content">

<p>This Is a Content Example</p>

    </div>

    <div class="BTN">

<button class="SM">See More</button>

<button class="Copy">Copy</button>

    </div>

</div>

<div class="box">

    <div class="content">

<p>This Is a Content Example</p>

    </div>

    <div class="BTN">

<button class="SM">See More</button>

<button class="Copy">Copy</button>

    </div>

</div>

<div class="box">

    <div class="content">

<p>This Is a Content Example</p>

    </div>

    <div class="BTN">

<button class="SM">See More</button>

<button class="Copy">Copy</button>

    </div>

</div>

    </div>

</body>

</html>

<style>

*{

margin: 0;

padding: 0;

outline: none;

}

body{

    width: 100%;

    height: 100vh;

    display: flex;

    justify-content: center;

    align-items: center;

}

.wrapper{

    width: 90%;

    display: flex;

    flex-direction: column;

}

.box{    

    height: 180px;

    background: blue;

    width: 100%;

    margin-top: 10px;

}

.content{

    height: 100%;

    width: 100%;

    display: flex;

    justify-content: center;

    align-items: center;

}

.content p{

    font-size: 22px;

    color: white;

    font-weight: bold;

}

.BTN{

    position: relative;

    width: 90%;

    margin: auto;

    display: flex;

    justify-content: space-between;

    gap: 8px;

    height: 32px;

    margin-top: -37px;

}

.BTN button{

    height: 100%;

    width: 100%;

    font-size: 18px;

    background: yellow;

    color: red;

    font-weight: bold;

    border: none;

    border-radius: 5px;

}

.Copy{

    display: none;

}

@media(min-width: 600px){

.wrapper{

    flex-direction: row;

    gap: 10px;

}

}

</style>

<script>

var a = document.getElementsByClassName("SM");

var b = document.getElementsByClassName("Copy");

a[0].addEventListener("click", function(){

    if(a[0].innerHTML == "See Less"){

    a[0].innerHTML = "See More";

    b[0].style.display = "None";    

    }else{

    a[0].innerHTML = "See Less";

    b[0].style.display = "block";

    }

});

a[1].addEventListener("click", function(){

    if(a[1].innerHTML == "See Less"){

    a[1].innerHTML = "See More";

    b[1].style.display = "None";    

    }else{

    a[1].innerHTML = "See Less";

    b[1].style.display = "block";

    }

});

a[2].addEventListener("click", function(){

    if(a[2].innerHTML == "See Less"){

    a[2].innerHTML = "See More";

    b[2].style.display = "None";    

    }else{

    a[2].innerHTML = "See Less";

    b[2].style.display = "block";

    }

});

b[0].addEventListener("click", function(){

    alert("You Copied the First Info");

    /* Please Create a Code To Copy because I already know and this is a sample. But if there's a possibility to make this code shorter, please include this.*/

});

b[1].addEventListener("click", function(){

    alert("You Copied the Second Info");

});

b[2].addEventListener("click", function(){

    alert("You Copied the Third Info");

});

</script>

    

    


无论如何,如果有可能在 JQuery 中使代码更短,那么我想接受它。 先谢谢你

JavaScript jQuery 事件 伪类

评论

1赞 Jaromanda X 8/2/2023
使代码更短的最简单方法是不要将其加倍行距
0赞 Carsten Massmann 8/2/2023
您可以使用 和 元素实现无脚本的打开/关闭逻辑,请参阅此处: developer.mozilla.org/en-US/docs/Web/HTML/Element/details<details><summary>

答:

0赞 Jaromanda X 8/2/2023 #1

Array forEach 可以提供帮助

[...a]创建一个数组a

.forEach((el, i)给你一个适当的索引 (),你可以用它来代替 - 由你决定ibela[i]

const a = document.getElementsByClassName("SM");
const b = document.getElementsByClassName("Copy");
[...a].forEach((el, i) => a.addEventListener('click', function () {
    if (el.innerHTML == "See Less") {
        el.innerHTML = "See More";
        b[i].style.display = "None";
    } else {
        el.innerHTML = "See Less";
        b[i].style.display = "block";
    }
}));
[...b].forEach((el, i) => b.addEventListener("click", function () {
    alert(`You copied ${['First', 'Second', 'Third'][i]} Info`);
}));

评论

0赞 Be Always Mine 8/2/2023
非常感谢,但是在“警报”部分,如果您复制所有信息,那不是我的重点。确切的重点是在各自的信息中插入每个函数。例如,如果单击“复制到第一个”框,则插入的函数为“CopyInfoA();然后在第二个框中,函数将是“CopyInfoB();等等..
0赞 Jaromanda X 8/2/2023
对不起,@BeAlwaysMine,我的读心术失败了 - 重写了我看到的,而不是你想到的扑克牌......是红桃三吗?
0赞 Be Always Mine 8/2/2023
例如,此代码必须如下所示 [...b].forEach((el, i) => b.addEventListener(“click”, function () { ${['CopyInfoA()', 'CopyInfoB()', 'CopyInfoC()']} });
0赞 Jaromanda X 8/2/2023
但。。。你的问题中没有那个代码......是黑桃5吗?
0赞 Be Always Mine 8/2/2023
控制台日志在参数列表后显示 Uncaught SyntaxError: missing )
0赞 Death-is-the-real-truth 8/2/2023 #2

你可以通过jquery用非常简单的代码实现同样的目标。

工作示例:

$('.SM').click(function() {
  $(this).next('.Copy').toggle(); // hide show copy button
  //code to change button text
  $(this).text(function(i, text){
      return text === "See More" ? "See less" : "See More";
  })
});
* {
  margin: 0;
  padding: 0;
  outline: none;
}

body {
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.wrapper {
  width: 90%;
  display: flex;
  flex-direction: column;
}

.box {
  height: 180px;
  background: blue;
  width: 100%;
  margin-top: 10px;
}

.content {
  height: 100%;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.content p {
  font-size: 22px;
  color: white;
  font-weight: bold;
}

.BTN {
  position: relative;
  width: 90%;
  margin: auto;
  display: flex;
  justify-content: space-between;
  gap: 8px;
  height: 32px;
  margin-top: -37px;
}

.BTN button {
  height: 100%;
  width: 100%;
  font-size: 18px;
  background: yellow;
  color: red;
  font-weight: bold;
  border: none;
  border-radius: 5px;
}

.Copy {
  display: none;
}

@media(min-width: 600px) {
  .wrapper {
    flex-direction: row;
    gap: 10px;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>

<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Page title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<body>
  <div class="wrapper">
    <div class="box">
      <div class="content">
        <p>This Is a Content Example</p>
      </div>
      <div class="BTN">
        <button class="SM">See More</button>
        <button class="Copy">Copy</button>
      </div>
    </div>
    <div class="box">
      <div class="content">
        <p>This Is a Content Example</p>
      </div>
      <div class="BTN">
        <button class="SM">See More</button>
        <button class="Copy">Copy</button>
      </div>
    </div>
    <div class="box">
      <div class="content">
        <p>This Is a Content Example</p>
      </div>
      <div class="BTN">
        <button class="SM">See More</button>
        <button class="Copy">Copy</button>
      </div>
    </div>
  </div>
</body>

</html>

注意:请确保页面上包含jQuery库,否则此代码将不起作用。

0赞 TheDxh 8/2/2023 #3

在你原来的文章中,你的解决方案需要两部分:第一部分是使你的整体代码更短/更简单,第二部分是利用JQuery的使用来做到这一点。

我们可以跳过使用直接功能来编辑和读取 DOM(即 innerHTML 和 getElementsByClassName),因为我们可以使用 jQuery 来处理点击事件并动态更新每个框的内容。

首先,我们将压缩标记和样式。请注意,我们只有带有“wrapper”类的 div。我们将以此为起点来生成盒子内容。

接下来,我们将更新脚本以使用 jQuery 生成内容,并启用所有必要的功能。请注意,请确保包含最新版本的 jQuery 库。

由于原始帖子包含三个框,因此我们创建了一个名为 boxContents 的常量,其中包含每个框的值。当您单击“查看更多”按钮时,将出现此值。当文档第一次加载时,jQuery将触发函数generateBoxes,该函数将通过boxContents提供的数组运行。这将为我们生成必要的 HTML,而不需要为每个单独的框手动添加它。

现在我们有了盒子,我们需要为按钮创建两个事件。这也可以在jQuery中完成。请注意,在脚本中,我们需要使用 .wrapper 作为引用的起点。这是因为我们在 DOM 加载后为框生成 html。如果我们尝试使.SM 和 .复制一个直接引用,如下所示:

$('.SM').on('click', function () {});

然后代码将不会运行。在这两个事件函数中,我们跟踪按钮的索引。此索引基于 boxContents 的相关值。对于“查看更多”按钮,它会触发 toggleContent 函数,该函数会将 boxContents 中的值添加到相关框中。

编辑:要为每个框启用单独的功能,我们可以使用值作为参考。例如,如果值为 0,那么我们可以运行第一个函数。我们还可以使用该值来获取适当的内容。在下面的代码片段中,我们获取 的值并将其传递给相应的复制方法。const indexboxContents

完整示例如下所示:

// Array containing the content for each box
const boxContents = [
   'This is the first box content',
   'This is the second box content',
   'This is the third box content'
];

// Function to toggle content visibility and button text
function toggleContent(index) {
   const boxContent = $('.content p').eq(index);
   const seeMoreBtn = $('.SM').eq(index);
   const copyBtn = $('.Copy').eq(index);

   if (seeMoreBtn.text() === 'See More') {
       boxContent.text(boxContents[index]);
       seeMoreBtn.text('See Less');
       copyBtn.show();
   } else {
       boxContent.text('This Is a Content Example');
       seeMoreBtn.text('See More');
       copyBtn.hide();
   }
}

// Click event for "See More" buttons
$('.wrapper').on('click', '.SM', function () {
   const index = $('.SM').index(this);
   toggleContent(index);
});

// Click event for "Copy" buttons
$('.wrapper').on('click', '.Copy', function () {
   const index = $('.Copy').index(this);
   const copyValueFromBox = boxContents[index];
   if(index == 0) {
       copyA(copyValueFromBox);
   } else if(index == 1) {
       copyB(copyValueFromBox);
   } else if(index == 2) {
       copyC(copyValueFromBox);
   }
});

// Function to generate the dynamic markup for boxes
function generateBoxes() {
   const wrapper = $('.wrapper');

   // Iterate through boxContents array and create the markup for each box
   for (let i = 0; i < boxContents.length; i++) {
       const boxMarkup = `
           <div class="box">
               <div class="content">
                   <p>This Is a Content Example<\/p>
               <\/div>
               <div class="BTN">
                   <button class="SM">See More<\/button>
                   <button class="Copy">Copy<\/button>
               <\/div>
           <\/div>
       `;
       wrapper.append(boxMarkup);
   }
}

function copyA(boxValue) {
   alert('You clicked copyA, the value you are copying is: ' + boxValue);
}

function copyB(boxValue) {
   alert('You clicked copyB, the value you are copying is: ' + boxValue);
}

function copyC(boxValue) {
   alert('You clicked copyC, the value you are copying is: ' + boxValue);
}

// When the document is ready, generate the boxes and enable the functionality
$(document).ready(function () {
   generateBoxes();
});
*{
    margin: 0;
    padding: 0;
    outline: none;
}
body{
    width: 100%;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}
.wrapper{
    width: 90%;
    display: flex;
    flex-direction: column;
}
.box{
    height: 180px;
    background: blue;
    width: 100%;
    margin-top: 10px;
}
.content{
    height: 100%;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
}
.content p{
    font-size: 22px;
    color: white;
    font-weight: bold;
}
.BTN{
    position: relative;
    width: 90%;
    margin: auto;
    display: flex;
    justify-content: space-between;
    gap: 8px;
    height: 32px;
    margin-top: -37px;
}
.BTN button{
    height: 100%;
    width: 100%;
    font-size: 18px;
    background: yellow;
    color: red;
    font-weight: bold;
    border: none;
    border-radius: 5px;
}
.Copy{
    display: none;
}
@media(min-width: 600px){
    .wrapper{
        flex-direction: row;
        gap: 10px;
   }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Page title</title>
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
</head>
<body>
    <div class="wrapper"></div>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js">
    </script> 
</body>
</html>

评论

0赞 Be Always Mine 8/2/2023
谢谢你,我感谢你的努力,即使是无价的。
0赞 Be Always Mine 8/3/2023
你好迪伦·埃尔南德斯,我可以再请一个忙吗?在单击事件复制按钮中,如果我要在第一个框中创建一个类似 CopyA() 的函数,然后在第二个框中创建 CopyB() 而不是警报,该怎么办?因为该代码上的警报是示例,因此如果单击复制,它将在每个框中分别显示任何功能。因此,如果用户在第三个框中选择副本,则函数 CopyC() 将激活。反正如果你不明白,我会给你一个代码.
0赞 TheDxh 8/4/2023
@BeAlwaysMine,在复制函数中,可以使用索引作为参考来确定要运行的复制函数。例如,如果 index 为 0(第一个框),则可以运行 CopyA(),如果 index 为 1(第二个框),则可以运行 CopyB(),依此类推。您还可以使用索引直接在事件函数中拉取框的值。在上面的示例中,如果您编写 boxContents(index) 并且 index 为 0,则值将为 'This is the first box content'。如果有帮助,请告诉我。
0赞 Be Always Mine 8/4/2023
我不知道如何把代码放在那里。但是你能检查一下吗?stackoverflow.com/questions/76835160/......我发布它是为了看代码
0赞 TheDxh 8/5/2023
@BeAlwaysMine我已经用启用独立复制功能的代码更新了上面的帖子。例如,第一个框将运行 CopyA(),第二个框将运行 CopyB(),第三个框将运行 CopyC()。如果需要任何澄清,请告诉我。
0赞 poorly-written-code 8/6/2023 #4

您走在正确的轨道上,只需切换复制按钮的可见性即可。与其尝试改变另一个按钮的文本,不如让所有按钮都存在,在 css 中设置初始状态,然后让 .toggle() 方法处理有关状态的所有细节。

然后,您可以使用 jQuery .on() 方法,而不是为每个元素添加事件侦听器。如果将其附加到父元素,则可以在子元素事件冒泡到父元素时将第二个参数用作选择器。

此外,我建议通过命名事物来为成功做好准备,而不是像在大型项目中处理或处理起来不好玩的隐晦名称。BTNSM

$('.buttons')
  .on('click', 'button.see-more, button.see-less', function() {
    $(this).parents('.buttons').find('button').toggle();
  })
  .on('click', 'button.copy', function() {
    let $box = $(this).parents('.box');
    alert(`copied the ${['first','second','third'][$box.index()]} box:\n"${$box.find('.content').text().trim()}"`);
  });
*{
  margin: 0;
  outline: none;
  padding: 0;}

body{
  align-items: center;
  display: flex;
  height: 100vh;
  justify-content: center;
  width: 100%;}

.wrapper{
  display: flex;
  flex-direction: column;
  width: 90%;}

.box{
  background: blue;
  height: 100px;
  margin-top: 10px;
  width: 100%;}

.content{
  align-items: center;
  display: flex;
  height: 100%;
  justify-content: center;
  width: 100%;}

.content p{
  color: white;
  font-size: 22px;
  font-weight: bold;}

.buttons{
  display: flex;
  gap: 8px;
  height: 32px;
  margin-top: -37px;
  justify-content: space-between;
  margin: auto;
  position: relative;
  width: 90%;}

.buttons button{
  background: yellow;
  border: none;
  border-radius: 5px;
  color: red;
  font-size: 18px;
  font-weight: bold;
  height: 100%;
  width: 100%;}

.buttons button.copy,
.buttons button.see-less{
    display: none;}

@media(min-width: 600px){
  .wrapper{
    flex-direction: row;
    gap: 10px;
  }
}
<div class="wrapper">
  <div class="box">
    <div class="content">
      <p>This Is a Content Example One</p>
    </div>
    <div class="buttons">
      <button class="see-more">See More</button>
      <button class="see-less">See Less</button>
      <button class="copy">Copy</button>
    </div>
  </div>
  <div class="box">
    <div class="content">
      <p>This Is a Content Example Two</p>
    </div>
    <div class="buttons">
      <button class="see-more">See More</button>
      <button class="see-less">See Less</button>
      <button class="copy">Copy</button>
    </div>
  </div>
  <div class="box">
    <div class="content">
      <p>This Is a Content Example Three</p>
    </div>
    <div class="buttons">
      <button class="see-more">See More</button>
      <button class="see-less">See Less</button>
      <button class="copy">Copy</button>
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>