1

The goal is to map data- attributes from one element to another, but while ignoring certain attributes such as class, id, etc.

Here is a block:

    let ignoreList = ['class', 'id', 'name', 'value', 'type', 'src'];
    $(".some-class").on("click",function(event) {
        let attrMap = new Map();
        let attrs = event.target.attributes;
        $.each(attrs, function(e){
            console.log(`"${this.name}" is in ignoreList: ` + (ignoreList.indexOf(this.name) == 0).toString());
            ignoreList.indexOf(this.name) == 0 ? attrMap.set(this.name, this.value) : null;
        });
        console.log(attrs);
        console.log(attrMap);
    });

What I would have expected in the console would be:

"class" is in ignoreList: true
"data-one" is in ignoreList: false
"data-two" is in ignoreList: false
"data-three" is in ignoreList: false
"data-four" is in ignoreList: false
"data-five" is in ignoreList: false
"data-six" is in ignoreList: false

NamedNodeMap {0: class, 1: data-one, 2: data-two, 3: data-three, 4: data-four, 5: data-five, 6: data-six, class: class, data-one: data-one, data-two: data-two, data-three: data-three, data-four: data-four, …}

Map(6) {'data-one' => 'Lorem ipsum', 'data-two' => 'dolor sit amet', 'data-three' => 'purto ludus', 'data-four' => 'indoctum sit', …}

What I am getting in the console:
(repeated values ignored for brevity)

Map(1) {'class' => 'some-class'}

I have tried various logics in the conditional, such as < 0, == -1, != 0

brian-welch
  • 441
  • 1
  • 7
  • 19
  • why not iterate directly over `dataset`? – Nina Scholz Jan 21 '23 at 09:38
  • That's a confusing way to use ternary operator, use a simple `if` instead. Don't minify your development code. – Teemu Jan 21 '23 at 09:38
  • @NinaScholz - I thought about it, but I wasn't sure how to get around the keys being different ergo: "data-this-data" in the element -> "thisData" in the dataset – brian-welch Jan 21 '23 at 09:54
  • `.indexOf(this.name) == 0` is only true when `this.name` is `class`. Use `includes` or a `Set` instead. – gog Jan 21 '23 at 09:55
  • oh my gosh - @gog, either too much coffee or not enough. You hit the nail on the head, I was using the reverse logic. `.indexOf(this.name) == -1` solves this. me – brian-welch Jan 21 '23 at 09:58
  • @brian-welch, better take `includes` instad of `indexOf` by not using index values. – Nina Scholz Jan 21 '23 at 10:05

1 Answers1

0

If you do console.log(ignoreList.indexOf(this.name)) you'll get always -1 in your case, but you're forcefully trying to match the result of Array.prototype.indexOf with an index of == 0.

Instead, to check if an array includes a value, use Array.prototype.includes() and save the Boolean result into a variable say isIgnored. Then you could use if (!isIgnored) /*set*/ or simply: !isIgnored && /*set*/, no ternary needed:

const ignoreList = ['class', 'id', 'name', 'value', 'type', 'src'];

const mapAttrs = (event) => {

  const attrMap = new Map();
  const attrs = event.currentTarget.attributes;

  [...attrs].forEach((attr) => {
    const isIgnored = ignoreList.includes(attr.name);
    console.log(`"${attr.name}" is in ignoreList: ${isIgnored}`);
    !isIgnored && attrMap.set(attr.name, attr.value);
  });
  
  console.log(attrs);
  console.log(attrMap);
};


document.querySelectorAll(".some-class").forEach(el => {
  el.addEventListener("click", mapAttrs);
});
                                                 
<div
    class="some-class"
    data-one="one"
    data-two="two"
    data-three="three"
    data-four="four"
    data-five="five"
    data-six="six"
>Open Dev tools Console (F12) and - Click me</div>
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313