.forEach 验证每个元素而不是整个输入? JS

问题描述

我正在尝试使用多个主题标签验证表单输入。我绝对必须拆分输入并将其转换为小写。 例如)#sun #sea #summer #salt #sand

当我输入未通过验证的主题标签时,会弹出气泡消息并告诉我这是错误的。 但是如果我正确输入下一个标签,之前的气泡消息会清除,整个验证失败(可以发送表单)。

我假设它与 .forEach 有关 - 可能有我尚未意识到的更好的解决方案。 我是 JS 新手,非常感谢您的回答。

// conditions for validation

const hashtagInput = document.querySelector('.text__hashtags');
const commentInput = document.querySelector('.text__description');

const testStartWith = (hashtag) => {
  if (!hashtag.startsWith('#')) {
    return 'hashtag should start with #';
  }
  return undefined;
};

const testShortValueLength = (hashtag) => {
  if (hashtag.length === 1) {
    return 'hashtag should have something after #';
  }
  return undefined;
};

const testValidity = (hashtag) => {
  const regex = /^[A-Za-z0-9]+$/;
  const isValid = regex.test(hashtag.split('#')[1]);
  if (!isValid) {
    return 'hashtag can't have spaces,symbols like #,@,$,etc,or punctuation marks';
  }
  return undefined;
};

const testLongValueLength = (hashtag) => {
  if (hashtag.length > 20) {
    return 'maximum hashtag length is 20 symbols';
  }
  return undefined;
};

const testUniqueName = (hashtagArray,index) => {
  if (hashtagArray[index - 1] === hashtagArray[index]) {
    return 'the same hashtag can't be used twice';
  }
  return undefined;
};

const testHashtagQuantity = (hashtagArray) => {
  if (hashtagArray.length > 5) {
    return 'only 5 hashtags for each photo';
  }
  return undefined;
};

const testCommentLength = (commentInput) => {
  if (commentInput.value.length >= 140) {
    return 'maximum comment length is 140 symbols';
  }
  return undefined;
};

const HighlighterrorBackground = (element) => {
  element.style.backgroundColor = '#FfdbDB';
};

const whitenBackground = (element) => {
  element.style.backgroundColor = 'white';
};

这是工作中的验证

const testHashtagInput = () => {
  const hashtagArray = hashtagInput.value.toLowerCase().split(' ');

  hashtagArray.forEach((hashtag,index) => {
    let error = testStartWith(hashtag)
    || testShortValueLength(hashtag)
    || testValidity(hashtag)
    || testLongValueLength(hashtag)
    || testUniqueName(hashtagArray,index)
    || testHashtagQuantity(hashtagArray);

    if (error) {
      HighlighterrorBackground(hashtagInput);
      hashtagInput.setCustomValidity(error);
    } else {
      whitenBackground(hashtagInput);
      hashtagInput.setCustomValidity('');
    }
    hashtagInput.reportValidity();
  });

  if (hashtagInput.value === '') {
    whitenBackground(hashtagInput);
    hashtagInput.setCustomValidity('');
  }
  hashtagInput.reportValidity();
};

const testCommentInput = () => {
  let error = testCommentLength(commentInput);
  if (error) {
    HighlighterrorBackground(commentInput);
    commentInput.setCustomValidity(error);
  } else {
    whitenBackground(commentInput);
    commentInput.setCustomValidity('');
  }
  commentInput.reportValidity();
};

hashtagInput.addEventListener('input',testHashtagInput);

解决方法

是的,您的 forEach 会根据单个项目重新评估输入的整个有效性,但实际上只有最后一个保留在最后,因为它是最后一个被评估的。 您可以将您的评估更改为 array-reducer 函数;最适合您的意图的是减速器“一些”(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)。

它遍历项目列表并返回是否有任何一个(或多个)项目满足您在回调函数中制定的标准。

我现在没有机会测试它,但我想这应该可以:

let error = hashtagArray.some((hashtag,index) => {
    return (testStartWith(hashtag)
            || testShortValueLength(hashtag)
            || testValidity(hashtag)
            || testLongValueLength(hashtag)
            || testUniqueName(hashtagArray,index)
            || testHashtagQuantity(hashtagArray));
});
if (error) {
  highlightErrorBackground(hashtagInput);
  hashtagInput.setCustomValidity(error);
} else {
  whitenBackground(hashtagInput);
  hashtagInput.setCustomValidity('');
}
hashtagInput.reportValidity();

HTH,干杯