0

Using the HTML below, how can I get a list of the functions in the <script> tag that is IN the #yesplease div. I don't want any other functions from other script tags. I don't want any global functions or native functions. What I'd like is an array with "wantthis1" and "wantthis2" only in it. I'm hoping not to have to use regex.

I am going to be emptying and filling the #yesplease div with different strings of html (including new script tags with new functions), and I need to make sure that I delete or "wantthis1 = undefined" each function in the script tag before filling it, programmatically, since I won't know every function name. (I don't want them to remain in memory)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script>
    function dontCare() {
      // don't care
     }
  </script>
</head>
<body>
  <div id="notthisone">
    <p>
    Hello
    </p>
    <script>
        function dontwantthis () {
        // nope
      }
    </script>
  </div>
  <div id="yesplease">
    <p>
    Hello again
    </p>
    <script>
        function wantthis1 () {
        // yes
      }
        function wantthis2 () {
        // yes
      }
    </script>
  </div>
  <script>
      // this function can be called by whatever, but this will look to
      // see if functions exist, then call them, otherwise do something
      // else
      function onSaveOrWhatever () {
          if (wantThis1 !== "undefined") {
              wantThis1();
          }
          else {
              // do something else (won't get called with above example)
          }
          if (wantThis3 !== "undefined") {
              wantThis3();
          }
          else {
              // do something else (will get called with above example)
          }
      }   
  </script>
  
</body>
</html>

2
  • Can you show where wantthis1 is referenced, in your real code? For example, inside yesplease, do you have <p onclick="wantthis()" or something of the sort, or what? Commented Mar 4, 2021 at 16:47
  • @CertainPerformance sure, I added another function in another script tag. I used wantThis3 as an example of a function that is missing currently, but if the page changes from user clicks, then wantThis3 might be there and wantThis1 would NOT be there. Commented Mar 4, 2021 at 17:08

2 Answers 2

1

The are a few ways to solve this problem

  1. Architect your application. Use react or vue (or even jquery) to add more control to your code/dom
  2. AST parsing, which would be overkill
  3. Hack it

If you hack it, the problem that you will face is that you are adding functions to global scope. This is shared by everyone, so you can't really monitor it in a nice way. You can however take advantage of javascript singlethreadedness, and know that things won't happen in the background while you are doing monitoring tasks.

<script>
    // take a cache of what is present before your script
    window.itemsPresentBeforeScript = {};
    foreach (var item in window) {
        window.itemsPresentBeforeScript[item] = window[item];    
    }
</script>

<script> .... your other script </script>

<script>
    // use your first cache to see what changed during the script execution
    window.whatWasAddedInTheLastScript = {};
    foreach (var item in window) {
        if (!window.itemsPresentBeforeScript[item]) {
            window.whatWasAddedInTheLastScript[item] = window[item];
        }
    }

    delete window.itemsPresentBeforeScript;

    // not you have a global list of what was added and you can clear it down when you need to 
</script>
Sign up to request clarification or add additional context in comments.

Comments

1
  1. Take innerHTML of all script tags you need
  2. Create an iframe
  3. Get a list of built-in functions of iframe.contentWindow object
  4. Write the content of the script to the iframe created
  5. Get a new list of the functions of iframe.contentWindow object
  6. Find new functions added to the new list

Somehow it doesn't work in stack snippets but it works in Codepen link

var code = document.querySelector("#target script").innerHTML;

var iframe = document.createElement("iframe");
document.body.appendChild(iframe);

var builtInFunctions = getFunctionsOfWindowObject();

var html = `<html><head><script>${code}</script></head><body /></html>`;
iframe.srcdoc = html;

var allFunctions = getFunctionsOfWindowObject();
var result = allFunctions.filter(function(n) {
  return builtInFunctions.indexOf(n) < 0;
});

console.log(result);

function getFunctionsOfWindowObject() {
  var functions = [];
  var targetWindow = iframe.contentWindow;
  for (var key in targetWindow) {
    if (
      targetWindow.hasOwnProperty(key) &&
      typeof targetWindow[key] === "function"
    ) {
      functions.push(key);
    }
  }
  return functions;
}
iframe {
  display: none;
}
<div id="target">
  <script>
    function wantthis1() {}

    function wantthis2() {}
  </script>
</div>

1 Comment

Hmm.. interesting use of an iframe. I'll give that a shot.

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.