I've got a script from AWeber, for a popup form, and I want to customize it a little bit..
It currently opens the popup when the page loads. I want it to run as a click event for a button.
The problem is: it uses an immediately-invoked function. And since I'm a newbie and not familiar with this kind of pattern yet, I can't figure it out. I've read about it, but I'm still not completely understanding it.
So, I've tried to rewrite the script to a simple pattern, but it doesn't work!
So, would you please help figuring out what the problem is with my new function?
And/or simplify/explain the other function for me?
The first Function:
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//forms.aweber.com/form/id.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, "script", "aweber-wjs-formid")
My attempt (jQuery) :
function createAweberScript() {
var script=document.createElement('script');
script.type='text/javascript';
script.id='aweber-wjs-formid';
script.src='//forms.aweber.com/form/id.js';
jQuery('body').append(script);
}
jQuery(document).ready(function () {
jQuery( 'a.button' ).click(createAweberScript);
});
Just wrap the immediately-invoked function in a regular function, and call that function in the click handler:
function createAweberScript() {
// start Aweber script
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//forms.aweber.com/form/id.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, "script", "aweber-wjs-formid"));
// end Aweber script
}
jQuery(document).ready(function () {
jQuery('a.button').click(createAweberScript);
});
You could pick this apart and write your own function, yes, but this is easier to understand and maintain: if the Aweber function ever changes, you just have to replace everything inside your createAweberScript() function to update it.
Note: I got a 404 for http://forms.aweber.com/form/id.js; I'm assuming that's not really the URL you are trying to use. If so, you might want to check it.
Related
I want to add a element into the existing DOM to have the javascript code run.
I did this with YUI:
var scriptNode = Y.Node.create('<script type="text/javascript" charset="utf-8">alert("Hello world!");<\/script>');
var headNode = Y.one('head');
headNode.append(scriptNode);
It's successfully added to the DOM but it doesn't give me an alert.
Someone knows what the problem is?
I have no idea how YUI's Node.create() function works, so no comment on that. But a simple cross-browser script is:
window.onload = function() {
var s = document.createElement('script');
s.type = 'text/javascript';
var code = 'alert("hello world!");';
try {
s.appendChild(document.createTextNode(code));
document.body.appendChild(s);
} catch (e) {
s.text = code;
document.body.appendChild(s);
}
}
The try..catch block is necessary as most browsers like the first method but some don't and throw an error. The second method covers those. You can also simply eval the code, which is more or less equivalent and what some libraries do.
I found this function in the JQuery source, which seems to do what you want and feels a bit cleaner than the other approaches to me. But then again I am a JS beginner and probably don't see the details. Anyways, somebody might take something useful away from this.
function DOMEval( code, doc ) {
doc = doc || document;
var script = doc.createElement( "script" );
script.text = code;
doc.head.appendChild( script ).parentNode.removeChild( script );
}
I am trying to load a js script dynamically in index.html file using appendChild DOM method. And I am trying to use some functions from that dynamically loaded js in next line itself but I am getting error that the specified function is undefined. I understand that this error is because of async behavior of loading scripts in browser. I also used async flag as false but no use. Below are sample code.
<script>
var head = document.getElementsByTagName('head')[0];
var js = document.createElement("script");
js.type = "text/javascript";
js.async = false;
js.src = "https://example.com/test.js"; // There are two variants of test.js is there. Will be changing it dynamically based on conditional check.
head.appendChild(js);
</script>
<script>
test(); // Method inside test.js
</script>
I want test.js to be loaded immediately after executing appendChild code part. Please help me on this. Please suggest if there is any other way for my purpose.
Synchronized XHRs are deprecated. You need to add an event listener so you can call your code as soon as the script is loaded. Example below:
var head = document.getElementsByTagName('head')[0];
var js = document.createElement("script");
head.appendChild(js);
js.onload = function() {
console.log("yes", window.$)
};
js.src = "//code.jquery.com/jquery-3.3.1.min.js";
console.log("nope", window.$)
I added js code dynamically:
var head = document.getElementsByTagName("head")[0];
var js = document.createElement("script");
js.type = "text/javascript";
js.id ="jsChange";
js.src = "myRoute.js";
head.appendChild(js);
It works fine, the problem is when I try to remove, I can get the way.
$('#jsChange').remove() //Doesnt work
I also try to add a div in head and put the js inside:
$('#divToJS').append(js);
and:
$('#divToJS').empty(); // doesnt work
How can I do it?
Your empty and remove both need () on the call.
E.G.
$('#jsChange').remove to $('#jsChange').remove();
$('#divToJS').empty to $('#divToJS').empty();
Unless i've misread the question, this should solve your issue.
I have narrowed down the error I am having with my Twitter widget usage to the binding of the event.
twttr.events.bind('tweet', function (event) { addShared(); });
or
twttr.events.bind('tweet', addShared);
seem to produce the same error: Uncaught TypeError: undefined is not a function.
They both ultimately work but the button acts funny from time to time and I'm wondering if this error has anything to do with the problem.
Note, the error shows up in Chrome when inspecting the webpage before the button is ever clicked but the button works and the tweets work but the resulting bound function does not work anymore. This is a problem that I recently noticed without having changed the twitter code at all and the event binding was previously functional.
Any advice or even acknowledgement of having seen the same problem would be nice, thanks.
The issue ended up being solved on Twitter's discussions by #indianburger.
The problem was how the code was being loaded and called. The solution came in the form of a jsfiddle: #indianburer's jsfiddle.
If that is broken, the simplest example of what is needed for event binding is:
Tweet
<script>
window.twttr = (function (d,s,id) {
var t, js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return; js=d.createElement(s); js.id=id;
js.src="https://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
return window.twttr || (t = { _e: [], ready: function(f){ t._e.push(f) } });
}(document, "script", "twitter-wjs"));
</script>
<script>
twttr.ready(function (twttr) {
twttr.events.bind('click', function (event) { alert('yes'); });
});
</script>
For reference, this is the Twitter discussion link.
I don't get some of the syntax in this block of code taken from the facebook developers site.
Are the first variables 'js' and 'id' bound in some way? What exactly is being returned in the first if statement?
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
This is the link to the page: http://developers.facebook.com/docs/guides/web/#personalization
What do you mean by "bound"?
They're function-local; js is a variable set in the 3rd and 4th lines, id is set to a string immediately.
The function itself is executed immediately after definition, with d set to document inside the function.
Nothing is returned by the first (and only explicit) return statement. And if this is the only code, a return value would be meaningless, because nothing captures the return value.
Nothing exiting here, just stolen whitespaces :)
(function(d){
var js, // variable (empty)
id = 'facebook-jssdk'; // variable with string 'facebook-jssdk'
if (d.getElementById(id)) { // is there an element with id 'facebook-jssdk'
return; // yes, so we have nothing to do and get out of here
}
js = d.createElement('script'); // create 'script' element
js.id = id; // assign id 'facebook-jssdk'
js.async = true; // load in "background" (if supported)
js.src = "//connect.facebook.net/en_US/all.js"; // set source (with the appropriate protocol; https if called via https, http otherwise)
d.getElementByTagNam('head')[0].appendChild(js); // append to first head element on page
}(document)) // immediately call the anonymous function and hand in the 'document'