0

The IntersectionObserver is designed to perform functions at certain scroll points. I give these functions in the data-options attribute under callbacks.

Now the question, how can I trigger the corresponding function? That would look like this:

modal ('default-modal');
notify ('subscribe-newsletter', 'bottomLeft');

My HTML node with the JSON string:

<section id="section-90" data-trigger="observer" data-options="{'root':null,'rootMargin':'0px','threshold':[0,0.1,0.2,0.3,0.4,0.7,1],'callbacks':{'modal':[{'id':'default-modal','position':'center'}],'notify':[{'id':'subscribe-newsletter','position':'bottomLeft'},{'id':'become-distributor','position':'bottomRight'}]}}">

Formatted JSON (Only here for a better overview:):

{
  "root": "null",
  "rootMargin": "0px",
  "threshold": [
    0,
    0.25,
    0.5,
    0.75,
    1
  ],
  "callback": {
    "modal": [
      {
        "id": "default-modal",
        "position": "center"
      }
    ],
    "notify": [
      {
        "id": "subscribe-newsletter",
        "position": "bottomLeft"
      },
      {
        "id": "become-distributor",
        "position": "bottomRight"
      }
    ]
  }
}

Parse String with options and filter callbacks

let str = target.dataset.options; // options from HTML node
let optStr = str.replace(/'/g, '"');
options = JSON.parse(optStr);
let callbacks = options.callbacks; // store only callbacks

for (const key of Object.keys(callbacks)) {
  console.log(key, callbacks[key]);

  /*
  Output:
  modal -> [{"id":"default-modal"}]
  notify -> [{"id":"subscribe-newsletter","position":"bottomLeft"},{"id":"become-distributor","position":"bottomRight"}]
  */
}

How can I call the function with arguments from the output?

modal('default-modal');
notify('subscribe-newsletter', bottomLeft)
0

2 Answers 2

1

You could do this a very hacky way by calling eval() but that is very strongly recommended against as it allows for all kinds of XSS attacks. It would be much better to whitelist functions and call them explicitly. See my example below.

//fake funciton calls
function modal(x) { console.log('fake modal() call', x); }
function notify(a, b) { console.log('fake notify() call', a, b); }

//parse the HTML string
var elem = document.getElementById('section-90');
var optionsStr = elem.getAttribute('data-options').replace(/'/g, '"');
var options = JSON.parse(optionsStr);

//Call the known functions
Object.keys(options.callbacks).forEach(key => {
  if (key === "modal") {
    modal(options.callbacks.modal[0].id)
  } else if (key === "notify") {
    notify(options.callbacks.notify[0].id, options.callbacks.notify[1].id)
  } else {
    throw Error("Unknown function attempted to be called!");
  }
});
<section id="section-90" data-trigger="observer" data-options="{'root':null,'rootMargin':'0px','threshold':[0,0.1,0.2,0.3,0.4,0.7,1],'callbacks':{'modal':[{'id':'default-modal','position':'center'}],'notify':[{'id':'subscribe-newsletter','position':'bottomLeft'},{'id':'become-distributor','position':'bottomRight'}]}}">

Sign up to request clarification or add additional context in comments.

Comments

0

You can create an object storing available callbacks:

const availableCallbacks = {
  modal: // function definition here
  notify: // function definition here
}

Then, inside your loop,

for (const key of Object.keys(callbacks)) {
  console.log(key, callbacks[key]); // we were here...
  const callbackFn = availableCallbacks[key];

  if(callbackFn) {
    callbacks[key].forEach(value => callbackFn(value));
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.