38

I have a bookmarklet that I've made and it loads a script from my server onto the users current page. However I have an if check in my script that if a condition is not met then no action is taken. However if the user then meets that condition then the code is run, but has caused there to be two sets of scripts inserted into their page. Can i prevent this?

 <a href="javascript: (function () {
    var jsCode = document.createElement('script');
    jsCode.setAttribute('src', 'http://xxx.co.uk/xxx/script.js');
  document.body.appendChild(jsCode);
 }());">Bookmarklet</a>

7 Answers 7

52

You can check whether your script is loaded like this:

function isMyScriptLoaded(url) {
    if (!url) url = "http://xxx.co.uk/xxx/script.js";
    var scripts = document.getElementsByTagName('script');
    for (var i = scripts.length; i--;) {
        if (scripts[i].src == url) return true;
    }
    return false;
}

Alternatively, you could do something like this:

<a href="javascript:
    if (!jsCode) {
        var jsCode = document.createElement('script');
        jsCode.setAttribute('src', 'http://xxx.co.uk/xxx/script.js');
        document.body.appendChild(jsCode);
    }
 ">Bookmarklet</a>

This "pollutes" the global namespace with the jsCode variable, but that might be a necessary evil. You could rename it to something that is unlikely to appear in the document where the bookmarklet is run.


Please note that while the javascript URI scheme is okay for bookmarklets as in this case, it's not considered to be a good practice for normal use.

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

4 Comments

Oh ok, what's the modern way to create bookmarklets now-a-days?
This is fine, I was missing the fact that it was a bookmarklet earlier... let me re-add that in a way that makes sense
Some scripts maybe add with a random query string at the end of the URL so an even better solution is to use the includes function instead of '==' operator.
There is some danger in checking scripts[i].src if you reference internal sources. At least Chrome prepends "localhost" in case that a relative path was used, e.g. test.js. I now use scripts[i].getAttribute('src')
16

Just check the selector length. Here's an example using jQuery:

if ($('script[src="http://xxx.co.uk/xxx/script.js"]').length > 0) {
    //script exists
}

Comments

13

You can place id attributes on your script tags and use document.getElementById('your-id') to identify whether the script is on the page before adding.

if (!document.getElementById('your-id')) {
    // append your script to the document here, ensure it has its id attribute set to 'your-id'
}

Comments

13

Solution with ES6, no jQuery:

const url = 'http://xxx.co.uk/xxx/script.js';

function scriptExists(url) {
  return document.querySelectorAll(`script[src="${url}"]`).length > 0;
}

if(scriptExists(url)) {
  ...
}

It's not recommended to inline JS into HTML. Instead add event listeners:

 function bookmark() {
   if(scriptExists(url)) {
     ...
   }
 }

 const button = document.querySelectorAll('a.bookmark');
 button.addEventListener('click', bookmark, false);

Comments

2

In case working with local and live alternatively.

The exact URL may change. I think the ID method is better.

This is a combination of Two StackOverflow answers.

if (!document.getElementById('your-id')) {
        addScript("your_script_src"); //adding script dynamically
        addCSSFile("your_css_src"); // adding css files
}

function addScript(path) {
        var head = document.getElementsByTagName("head")[0];
        var s = document.createElement("script");
        s.type = "text/javascript";
        s.src = path;
        s.id = "your-id";
        head.appendChild(s);
}

function addCSSFile(path) {
    var head = document.getElementsByTagName("head")[0];
    var s = document.createElement("style");
    s.type = "text/css";
    s.src = path;
    head.appendChild(s);
}

Comments

0

if you create a variable in the global scope (window.yourVariable) and check if that exists already then you can decide if you want to add your jsCode snippet code or run whatever you are running in script.js

Comments

0
if (document.getElementById('element-id')) {
// if exist must do something 
}

hi, this is worked for me, please try it if you still need it

1 Comment

Please fix your formatting error (the } is outside of the code block) and your typo (plesea)

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.