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

问题描述 投票:0回答:3

我有一些盒子,里面有很多信息。我一开始想要的信息较少,如果用户想阅读更多信息,他们会单击“查看更多”按钮。然后,如果他们单击该按钮,将显示名为“复制”的按钮,并且名为“查看更多”的按钮将通过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 Dont 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 events pseudo-class
3个回答
0
投票

Array forEach 可以提供帮助

[...a]
a

创建一个数组

.forEach((el, i)
为您提供相应
i
的索引 (
b
),您可以使用
el
代替
a[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
投票

您可以通过 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
投票

在您的原始帖子中,您的解决方案需要两部分:第一部分是使您的整体代码更短/简化,第二部分是利用 JQuery 来实现这一点。

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

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

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

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

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

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

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

编辑:要为每个框启用单独的功能,我们可以使用

const index
的值作为参考。例如,如果该值为 0,那么我们可以运行第一个函数。我们还可以使用该值来获取适当的内容。在下面的代码片段中,我们获取
boxContents
的值并将其传递给适当的复制方法。

完整示例如下所示:

// 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>

© www.soinside.com 2019 - 2024. All rights reserved.