首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何动态添加和删除元素JavaScript

如何动态添加和删除元素JavaScript
EN

Stack Overflow用户
提问于 2022-07-29 08:05:10
回答 6查看 158关注 0票数 4

我有这个,比方说小测验,我在这里做问题。看起来是这样的:

用户可以选择以4种不同的方式显示此评级系统:

  1. 1 2 3 4 5 -> 1-5 rating
  2. 1 2 3 5 6 7 8 10 -> 1-10 rating
  3. ⭐⭐⭐⭐⭐ -> 1-5 stars
  4. ⭐⭐ -> 1-10星

默认的评级系统是从1到5个数字。但用户可以选择从1到10,使用切换开关以及星星而不是数字。我的问题是,当开关打开时,我不知道如何再添加5个数字,然后当开关关闭时,再删除它们,或者在另一个开关打开时删除数字和添加星星。

我想我需要这样的东西:

代码语言:javascript
运行
复制
depending on the current state:
if (1-10_switch.isChanged){
   (addMore(stars || numbers) || remove ) 
}
else if (stars_switch.isChanged){
   (changeIconTo(stars || numbers)) 
}

我有代码来检查开关是否打开和关闭:

代码语言:javascript
运行
复制
oneToTenButtonCheckbox.addEventListener("change", function () {
    OneToTen = OneToTen ? false : true;
});

starsButtonCheckbox.addEventListener("change", function () {
    isStars = isStars ? false : true;
});

这是我加数字的代码:

代码语言:javascript
运行
复制
  var numbersDiv = document.createElement("div");  
  numbersDiv.className = "row";
  for (let i = 0; i < 5; i++) {
    var num = document.createElement("div");
    num.insertAdjacentText("beforeend", i + 1);
    if (i == 0) num.className = "col-1 offset-1 mb-2";
    else num.className = "col-1 mb-2";
    numbersDiv.appendChild(num);
  }

有人知道我能用什么方法解决这个问题吗?或者是有人做了这件事知道该怎么做?谢谢。

EN

Stack Overflow用户

发布于 2022-07-29 12:02:52

这是我的完全动态和通用的解决方案。我想出了一个动态解决方案,因为我假设您需要创建多个测试,因此需要多个评分选择器。

我们可以使用HTMLDivElement.函数创建一个评级选择器元素,并返回一个createRatingSelector

代码语言:javascript
运行
复制
const stateElement = document.getElementById("state");

const quizRatingSelector = createRatingSelector({
  altRatingScale: 10,
  defaultRatingScale: 5,
  altRatingType: "star",
  defaultRatingType: "number",
  altRatingTypeLabel: "Star",
  defaultRatingTypeLabel: "Number Scale",

  // listen to change event
  onChange: ({ratingScale, ratingType}) => {
    const stateString = `scale: ${ratingScale}, type: ${ratingType}`;
    stateElement.innerText = stateString;
  },
});

document.body.appendChild(quizRatingSelector);

// we can get the current state as
// console.log(quizRatingSelector.getState());

// ------------------------------------------

// returns a <div> element
// see the argument destructuring below to understand function API
function createRatingSelector(arg = {}) {
  const {
    altRatingType,
    altRatingScale,
    defaultRatingType,
    altRatingTypeLabel,
    defaultRatingScale,

    // this function will be called whenever the rating scale or type changes
    onChange = () => {},

    defaultRatingTypeLabel,
    NON_NUMBER_RATING_CHAR = "⭐",
    parentClassName = "rating-selector",
    typeSwitchClassName = "rating-type-switch",
    scaleSwitchClassName = "rating-scale-switch",
    outputElementClassName = "rating-selector-output",
  } = arg;

  const ratingSelector = document.createElement("div");
  ratingSelector.setAttribute("class", parentClassName);

  // we'll store the ratingType and ratingScale in the dataset of this selector
  // in case you need it.
  ratingSelector.dataset.ratingType = defaultRatingType;
  ratingSelector.dataset.ratingScale = defaultRatingScale;

  ratingSelector.getState = function () {
    return {
      ratingType: ratingSelector.dataset.ratingType,
      ratingScale: ratingSelector.dataset.ratingScale,
    };
  };

  const ratingOutput = document.createElement("div");
  ratingOutput.setAttribute("class", outputElementClassName);

  // this function is needed in the onClick function of switches
  const showResultLocal = () =>
    showResult({
      outputElement: ratingOutput,
      nonNumberValue: NON_NUMBER_RATING_CHAR,
      ratingType: ratingSelector.dataset.ratingType,
      ratingScale: ratingSelector.dataset.ratingScale,
    });

  const ratingScaleSwitch = createSwitch({
    name: "rating-scale",
    onValue: altRatingScale,
    offValue: defaultRatingScale,
    className: scaleSwitchClassName,
    onLabel: `Rating Scale: 1 - ${altRatingScale}`,
    offLabel: `Rating Scale: 1 - ${defaultRatingScale}`,

    onClick: ({ value }) => {
      ratingScale = value;
      ratingSelector.dataset.ratingScale = value;

      showResultLocal();
      onChange(ratingSelector.getState());
    },
  });

  const ratingTypeSwitch = createSwitch({
    name: "rating-type",
    className: typeSwitchClassName,

    onValue: altRatingType,
    offValue: defaultRatingType,

    onLabel: `Rating type: ${altRatingTypeLabel}`,
    offLabel: `Rating type: ${defaultRatingTypeLabel}`,

    onClick: ({ value }) => {
      ratingSelector.dataset.ratingType = value;
      showResultLocal();

      onChange(ratingSelector.getState());
    },
  });

  ratingSelector.appendChild(ratingScaleSwitch);
  ratingSelector.appendChild(ratingTypeSwitch);
  ratingSelector.appendChild(ratingOutput);

  showResultLocal();

  return ratingSelector;
}

/**
 * Creates a __input__ and __label__ element and wraps it with a <div>
 * e.g.,
 * <div>
 *  <label>The Label</label>
 *  <input type="checkbox" ...other attributes... />
 * </div>
 *
 * see the argument destructuring below to understand function API
 * */
function createSwitch(arg = {}) {
  const {
    onLabel,
    offLabel,

    onValue,
    offValue,

    id = "",
    name = "",
    className = "",

    onClick = () => {},
  } = arg;

  const switchName = name;
  const switchAttributes = {
    id,
    name: switchName,
    class: className,
    type: "checkbox",
  };

  const toggleSwitch = document.createElement("input");

  for (const [name, value] of Object.entries(switchAttributes))
    toggleSwitch.setAttribute(name, value);

  const switchLabel = document.createElement("label");
  switchLabel.setAttribute("for", switchName);
  switchLabel.innerText = offLabel;

  // click event handling
  toggleSwitch.addEventListener("click", () => {
    switchLabel.innerText = toggleSwitch.checked ? onLabel : offLabel;

    onClick({
      id,
      name: switchName,
      active: toggleSwitch.checked,
      value: toggleSwitch.checked ? onValue : offValue,
    });
  });

  const switchWrapper = document.createElement("div");
  switchWrapper.appendChild(toggleSwitch);
  switchWrapper.appendChild(switchLabel);

  return switchWrapper;
}


// see the argument destructuring below to understand function API
function showResult(arg = {}) {
  const { outputElement, ratingScale, ratingType, nonNumberValue } = arg;

  while (outputElement.childNodes.length > ratingScale)
    outputElement.removeChild(outputElement.childNodes[0]);
  while (outputElement.childNodes.length < ratingScale)
    outputElement.appendChild(document.createElement("span"));

  outputElement.childNodes.forEach((child, index) => {
    child.innerText = ratingType === "number" ? index + 1 : nonNumberValue;
  });
}
代码语言:javascript
运行
复制
.rating-selector-output > span {
  width: 2ch;
  text-align: center;
  display: inline-block;
}
代码语言:javascript
运行
复制
<body>
<p id="state">State...</p>
<hr>
</body>

如果你有任何问题,请随便问我。希望这能有所帮助。

票数 0
EN
查看全部 6 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73163500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档