Как проверить, есть ли у объекта ключ, который содержит данную строку в JavaScript? - PullRequest
0 голосов
/ 21 февраля 2019

Я пытаюсь написать скрипт, который проверяет DOM на наличие элементов с определенными атрибутами;Если они существуют, утешите атрибут и значение;В частности, атрибуты role и aria.

<body aria-live="assertive" aria-checked="true">
  <form role="search">
    <input type="search" name="q" placeholder="Search query" aria-label="Search through site content">
    <input type="submit" value="Go!">
  </form>
</body>

Приведенная выше разметка должна давать:

Body aria-live: "assertive", aria-checked:"true"

Form role: "search"

Input aria-label: "Search through site content"

И это скрипт:

  document.addEventListener('DOMContentLoaded', function (event) {
      var jsUcFirst = (str) => str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();

      document.querySelectorAll('*').forEach(function (node) {
        if (node.hasAttribute('role') || checkForAriaFunc(node)) {
          console.dir(document.body.attributes)
          console.log(
            `${jsUcFirst(node.tagName)} role: ${node.getAttribute('role')}, aria: ${checkForAriaFunc(node)}`
          )
        }
      });
    })

Как вы можете видеть в операторе if, я застрял в том, как проверить aria-* с checkForAriaFunc в качестве функции-заполнителя / псевдокода.

Я утешил dir'ed document.body и обнаружил, что есть свойство attributes с именем NamedNodeMap, которое содержит следующее:

enter image description here

Итак, как лучше всего использовать метод, чтобы я мог проверить, есть ли у элемента какие-либо теги arias и, если да, распечатать их все?Заранее спасибо!

Обновление По предложению Маркуса я попробовал это:

  function ariaChecker(el) {
    Object.keys(el.attributes).map((property) => {
      if (property.includes('aria')) {
        console.log(property);
      }
    })
  }

Но возвращаюсь неопределенным!

Обновление Итак, принимая то, что рекомендовал guest271314, я попытался написать свою собственную функцию, используя filter:

 function ariaChecker(el) {
   return Object.entries(el.attributes).filter((property) => {
     var newarr = []
       if (property.includes('aria')) newarr.push(property.toString())
         return newarr
       }).join(' ')
   }

Но я получаю:

enter image description here

Ответы [ 3 ]

0 голосов
/ 21 февраля 2019

Вы можете создать функцию для .map() свойства name NamedNodeMap с использованием методов RegExp или String, вернуть Array объектов, в которых элемент имеет .some() соответствующих атрибутов сЭлемент DOM tagName устанавливается как свойство, а значение устанавливается как массив объектов с name, value совпадающих значений, передаваемых в качестве параметров функции, .filter() false значения элемента массива с использованием Boolean

// `selector`: CSS selector string
// `attrs`: one or more strings or `Array` of attribute `name`s to match
const getAttributes = (selector, ...attrs) =>
// convert `NodeList` to `Array`
[...document.querySelectorAll(selector)] 
// `.filter()` `attributes` property of DOM element
.map(({attributes, tagName
     , _r = RegExp(`${ attrs.flat().join("|")}`)
     , _f = (all = false) => 
         [...attributes].map(({name, value}) => 
         all ? ({name, value}) : name)}) => 
  _r.test(_f().join(" ")) 
  ? ({[tagName.toLowerCase()]: _f(true).filter(({name}) => _r.test(name))}) 
  : false) 
.filter(Boolean);
          
let {selector, attributes} = {selector:"body, body *"
                             , attributes: ["aria", "role"]};
// or `getAttributes("*", "aria" , "role")`
const attrs = getAttributes(selector, attributes); 
console.log(attrs);
<body aria-live="assertive" aria-checked="true">
  <form role="search">
    <input type="search" name="q" placeholder="Search query" aria-label="Search through site content">
    <input type="submit" value="Go!">
  </form>
</body>
0 голосов
/ 21 февраля 2019

Я сделал эту функцию для вас.Он ищет любой атрибут, который вы хотите, и возвращает его значение и значение false, когда он не существует:

function searchNodeAttr(node, search){
  var attrs = node.attributes; 
  if(attrs && attrs.length){
    for( var a in attrs){
      var attr = attrs[a];
      if(attr.nodeType == 2){
        if((new RegExp(search)).test(attr.name)) return attr.value;
         } else break;
     };
     }

  return false;
}

Использование в вашем случае:

var ariaAttr = searchNodeAttr(node, 'aria-');
if (node.hasAttribute('role') || ariaAttr !== false){
console.log(ariaAttr)
}
0 голосов
/ 21 февраля 2019

Предположительно, вы можете просто использовать Object.keys () как в:

Object.keys(document.body.attributes).forEach((property) => { ...})

См. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...