Re-render Tweet button via JS - javascript

I used to use this snippet to re-render a Tweet button.
var tweetButton = new twttr.TweetButton(twitterScript);
twttr.render();
But it looks like widgets.js (http://platform.twitter.com/widgets.js) has been modified so twttr.TweetButton is no longer a constructor.
Can anyone help with this issue?

I found the answer on the web. The idea is to re-request the Twitter javascript file. As it is cached, there is no download overhead.
$.ajax({ url: 'http://platform.twitter.com/widgets.js', dataType: 'script', cache:true});

For anyone stumbling onto this, there's a new, easier way to do it (as of 5/28/12 if not before). A quick glance didn't find it in the documentation, but you can do twttr.widgets.load(). That'll [re]load all the widgets on the page.
EDIT: It is documented, after all. Check out this page's "Optimization" section (which you can't link to directly)

you just need to call twttr.widgets.load() after your ajax call. no need to reload a script that is already loaded.

Looks like the twttr.TweetButton constructor was never supported, and now no longer works after the last API update:
http://groups.google.com/group/twitter-development-talk/browse_thread/thread/bcda486acdf4ab42/6a557050f850ccf2?lnk=gst&q=+twttr.TweetButton#6a557050f850ccf2
The supported method is to create an iframe-based Tweet button dynamically:
http://dev.twitter.com/pages/tweet_button#using-an-iframe
Although note #Runningskull’s answer for updated information.

First, make sure you have jQuery included in your document's head:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
Then create a link that has the same URL as the eventual tweet button, along with an empty div where your button will be rendered:
<div id="tbutton"></div>
At the bottom of your page, right above the /body tag, include the javascript from Twitter and the function that will render the button, as well as the listener that will activate the function when the desired event takes place:
<script type="text/javascript">
//async script, twitter button fashiolista.com style
(function() {
var s = document.createElement('SCRIPT');
var c = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.defer = "defer";
s.async = true;
s.src = 'http://platform.twitter.com/widgets.js';
c.parentNode.insertBefore(s, c);
})();
function renderTweetButton(tbutton,tlink){
var href = $("#"+tlink).attr('href'),
$target = $("#"+tbutton),
qstring = $.param({ url: href, count: "vertical" }),
toinsert = '<iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?'+qstring+'" style="width:57px; height:70px;"></iframe>';
$target.html(toinsert);
}
$("#hoverlink").mouseenter(function() {
renderTweetButton("tbutton","tlink");
});
</script>
Lastly, add a link to your page somewhere that will activate the function above based on some event:
Hover here to render a tweet button to div#tbutton.
That's it.
If you want the entire test HTML page to see how I've got it working, see here:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>jQuery Twitter Button Render Test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
</head>
<body>
<div id="tbutton"></div>
Hover here to render a tweet button to div#tbutton.
<script type="text/javascript">
//async script, twitter button fashiolista.com style
(function() {
var s = document.createElement('SCRIPT');
var c = document.getElementsByTagName('script')[0];
s.type = 'text/javascript';
s.defer = "defer";
s.async = true;
s.src = 'http://platform.twitter.com/widgets.js';
c.parentNode.insertBefore(s, c);
})();
function renderTweetButton(tbutton,tlink){
var href = $("#"+tlink).attr('href'),
$target = $("#"+tbutton),
qstring = $.param({ url: href, count: "vertical" }),
toinsert = '<iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?'+qstring+'" style="width:57px; height:70px;"></iframe>';
$target.html(toinsert);
}
$("#hoverlink").mouseenter(function() {
renderTweetButton("tbutton","tlink");
});
</script>
</body>
</html>

I just had the same problem, this works in JQuery:
$.getScript('http://platform.twitter.com/widgets.js');

Try the #Anywhere library. Sample js code:
twttr.anywhere(function (T) {
T("#tweetbox").tweetBox({
counter: false,
defaultContent: "Default text in a Tweet box...",
label: "Share this page on Twitter"
});

Related

How to load javascript files using event listeners

This question is not duplicate of
Conditionally load JavaScript file
and nor this
How to include an external javascript file conditionally?
I have gone through them, they are kind of similar to what I want to do but not exactly same. Here is how, in the above question the user just wants to load the script file once based on a condition. But in my case I want to load different js files based on click events.
So here in my case I have an HTML document:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Experiment</title>
<link href="s.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="navigation">
<nav>
<ul>
<li id="home_btn"> Home</li>
<li id="about_btn"> About </li>
</ul>
</nav>
</div>
<canvas id="myCanvas">
</canvas>
<div class="notePane">
<p> This is just a bunch of text not explanation</p>
</div>
</body>
<script src="./exp.js" type="text/javascript"></script>
</html>
and this h.html file is linked to an exp.js file. Now in the exp.js file :
var h_btn = document.getElementById("home_btn");
var a_btn = document.getElementById("about_btn");
var head = document.getElementsByTagName("head")[0];
var js = document.createElement("script");
js.type="module";
h_btn.addEventListener("click", showHome );
a_btn.addEventListener("click", showAbout);
function showHome() {
js.src="./j1.js";
head.appendChild(js);
}
function showAbout() {
js.src="./j2.js";
head.appendChild(js);
}
So things work fine when I click the h_btn on the web page. It loads j1.js. But then when I click on the a_btn on the web page I expect to see j2.js linked but I don't see it. I have to refresh the page and then click on a_btn to see j2.js linked. How do I link j1.js and j2.js such that I don't have to refresh the page again and again to load the correct script.
Update: OP has updated the question requirements such that he wants to "unload" a JS file when another is clicked. There is no way to undo all the runtime logic once a JS file is loaded: the only way is to reload the page. Removing the <script> tag or changing the src attribute will not magically unbind event listeners or "undeclare" variables.
Therefore, if OP wants to "start anew", the only way is to check if a custom script has been loaded before: if it has, we force reload the page. There are of course many ways to "inform" the next page which source to load, if available: in the example below, we use query strings:
var h_btn = document.getElementById("home_btn");
var a_btn = document.getElementById("about_btn");
var head = document.getElementsByTagName("head")[0];
var appendedScriptKey;
var scripts = {
'home': './j1.js',
'about': './j2.js'
}
h_btn.addEventListener("click", showHome);
a_btn.addEventListener("click", showAbout);
// Check query string if a specific script is set
var params = (new URL(document.location)).searchParams;
var scriptKey = params.get('scriptKey');
if (scriptKey && scriptKey in scripts) {
appendScript(scriptKey);
}
function appendScript(key) {
if (hasAppendedScript) {
location.href = location.href + (location.search ? '?' : '&') + 'script=' + key;
location.reload();
}
var js = document.createElement("script");
js.type="module";
js.src = scripts[key];
head.appendChild(js);
appendedScript = key;
}
function showHome() {
appendedScriptKey('home');
}
function showAbout() {
appendScript('about');
}
This is because of how Node.appendChild() works. The first click works because you're creating a new element and inserting it into your document. However, the second click will not work as you've expected because the node already exists:
The Node.appendChild() method adds a node to the end of the list of children of a specified parent node. If the given child is a reference to an existing node in the document, appendChild() moves it from its current position to the new position
This means that the second click will only mutate the src attribute of the already-injected <script> element instead of creating a new one, and that also means that the second script src will not be loaded.
A solution will be to use a function that will create a script tag every single time:
var h_btn = document.getElementById("home_btn");
var a_btn = document.getElementById("about_btn");
var head = document.getElementsByTagName("head")[0];
h_btn.addEventListener("click", showHome);
a_btn.addEventListener("click", showAbout);
function insertScript(src) {
var js = document.createElement("script");
js.type = "module";
js.src = src;
head.appendChild(js);
}
function showHome() {
insertScript('./j1.js');
}
function showAbout() {
insertScript('./j2.js');
}
But this will also mean that multiple clicks on the same button will cause the script to be injected multiple times. This does not affect browser performance much since the browser has the loaded script cached somewhere, but to guard against this, it might be a good idea to implement some kind of unique identifier per script, and check against that before injection. There are many ways to do this, and this is just one way:
var h_btn = document.getElementById("home_btn");
var a_btn = document.getElementById("about_btn");
var head = document.getElementsByTagName("head")[0];
h_btn.addEventListener("click", showHome);
a_btn.addEventListener("click", showAbout);
// Store scripts that you've injected
var scripts = [];
function insertScript(src) {
// If we have previously attempted injection, then do nothing
if (scripts.indexOf(src) !== -1) {
return;
}
var js = document.createElement("script");
js.type = "module";
js.src = src;
head.appendChild(js);
// Push script to array
scripts.push(src);
}
function showHome() {
insertScript('./j1.js');
}
function showAbout() {
insertScript('./j2.js');
}
Alternative unique script injection strategies and ideas:
Use ES6 Map() to track unique script sources being injected
Perhaps only store src to array/dict/map when the script has successfully loaded
You have to create the element twice, as there can only be one element with 1 src.
var h_btn = document.getElementById("home_btn");
var a_btn = document.getElementById("about_btn");
var js1 = document.createElement("script");
var js2 = document.createElement("script");
h_btn.addEventListener("click", showHome);
a_btn.addEventListener("click", showAbout);
function showHome() {
js1.src = "j1.js";
document.body.appendChild(js1);
}
function showAbout() {
js2.src = "j2.js";
document.body.appendChild(js2);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Experiment</title>
<link href="s.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="navigation">
<nav>
<ul>
<li id="home_btn"> Home</li>
<li id="about_btn"> About </li>
</ul>
</nav>
</div>
<canvas id="myCanvas">
</canvas>
<div class="notePane">
<p> This is just a bunch of text not explanation</p>
</div>
</body>
<script src="exp.js" type="text/javascript"></script>
</html>

Google plus share using dynamic content not working

I am working vehicle tracking website, here I have to share some dynamic content in google plus share that is as prefilled text. Issue is the content I am sharing in google plus is shared,when first time I click google plus share, after the content get refresh automatically one minute once through ajax, the prefill text content getting updated, but i click share button in google plus share window the content not getting posted to anyone.
Here is the sample code
<html>
<head>
<title>Share Demo: Deferred execution with language code</title>
<link rel="canonical" href="http://www.example.com" />
</head>
<body>
<script type="text/javascript" src="https://apis.google.com/js/client:plusone.js"></script>
<div id ="sharePost" action="share">Share</div>
<script>
function add(){
var options = {
contenturl: 'https://plus.google.com/pages/',
contentdeeplinkid: '/pages',
clientid: 'xxx',
cookiepolicy: 'single_host_origin',
prefilltext: 'Hai happy friday'+Math.random(),
calltoactionlabel: 'CREATE',
calltoactionurl: 'http://plus.google.com/pages/create',
calltoactiondeeplinkid: '/pages/create'
};
// Call the render method when appropriate within your app to display
// the button.
gapi.interactivepost.render('sharePost', options);
}
setInterval(function(){
add();
},2000);
add();
</script>
</body>
</html>
I can able to share interactive post using java script render method.The main point we need to noted is, we need to use same url for contenturl and calltoactionurl.
<html>
<head>
<title>Share Demo: Deferred execution with language code</title>
<link rel="canonical" href="http://www.example.com" />
</head>
<body>
<script>
window.___gcfg = {
lang: 'en-US',
parsetags: 'explicit'
};
</script>
<script type="text/javascript" src="http://apis.google.com/js/plusone.js"></script>
<div id ="sharePost">Share</div>
<script>
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'http://apis.google.com/js/client:plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
var options = {
contenturl: 'http://www.google.com',
contentdeeplinkid: '/pages',
clientid: 'xxxxxxxxxxx.apps.googleusercontent.com',
cookiepolicy: 'single_host_origin',
prefilltext: 'Hai happy friday',
calltoactionlabel: 'INVITE',
calltoactionurl: 'http://www.google.com'
};
// Call the render method when appropriate within your app to display
// the button.
gapi.interactivepost.render('sharePost', options);
</script>
</body>
</html>

Google+ Signin button not clickable

I'm following what is shown on the Google+ API documentation. For some reason, my button isn't clickable at all. Nothing shows up. Nothing happens. I'm running this from the url: file:///TestPage.html in Google Chrome.
<html>
<head>
<title>Test Page</title>
<script type="text/javascript">
function onSuccess() {
//called fine.
}
(function() {
var po = document.createElement('script');
po.type = 'text/javascript';
po.async = true;
po.src = 'https://apis.google.com/js/client:plusone.js?onload=onSuccess';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(po, s);
})();
function onSignInCallback(res) {
alert('callback'); //doesn't show up.
}
</script>
</head>
<!-- Not clickable -->
<button id='signInBtn' class="g-signin"
data-scope="https://www.googleapis.com/auth/plus.login"
data-clientid="1085488274737.apps.googleusercontent.com"
data-callback="onSignInCallback"
data-theme="dark"
data-approval-prompt="force"
data-cookiepolicy="single_host_origin"
data-requestvisibleactions="http://schemas.google.com/AddActivity"
data-width="wide">
</button>
</html>
Any ideas why nothing happens? Why is my button not even clickable?
As akonsu said, see the console of browser
Please access the page from a local web server, not a simple way like file:// URL.

How to dynamically load an iFrame source and autofill input forms with Javascript

I need to retrieve URL parameters (which I can do successfully) and based on one parameter, decide which iframe src to fill, then with other parameters auto fill the form that is created via the form src. First issue is that I can't keep the page from going into an infinite loop. It loads properly and shows the right iframe, but the infinite loop (load) needs to stop. Second, I can't get the other parameters to autofill the input values.
Here is the code. I hope you can help. Here is the code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2000/REC- xhtml1-200000126/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<!-- Keep your jQuery up to date -->
<script type="text/javascript">
var urlParams;
(window.onpopstate = function () {
var match,
pl = /\+/g, // Regex for replacing addition symbol with a space
search = /([^&=]+)=?([^&]*)/g,
decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
query = window.location.search.substring(1);
urlParams = {};
while (match = search.exec(query))
urlParams[decode(match[1])] = decode(match[2]);
})();
var test = urlParams["entry"];
var test2 = urlParams["test"];
function iframedirect(){
if (test=="sldk") {
document.getElementById("frame1").src = "http://na-sj09.marketo.com/lp/cochlearsandbox/UpgradeInterest_IFrameLandingPage.html";
var f1 = frames['frame1'].document.forms['mktForm_1108'];
f1.elements['FirstName'].value = test;
}else{
document.getElementById("frame1").src = "http://na-sj09.marketo.com/lp/cochlearsandbox/CAM-UpgradeInterestForm_iFrameLandingPage2ndOption.html";
}
}
</script>
</head>
<body id="bodyId" class="mktEditable" align="center" >
<iframe id="frame1" src="" onload="iframedirect()" height="750px" width="620px" scrolling="no" frameborder="0" marginwidth="0"></iframe>
</body>
</html>
The infinite loop is probably caused by the result of the function iframedirect().It changes the src of the iframe and triggers the onload event again and again.
You could use a variable to point out if the iframe has been loaded by iframedirect().
var test = urlParams["entry"];
var test2 = urlParams["test"];
var isLoadedByIFrameDirect = false;
function iframedirect() {
if(!isLoadedByIFrameDirect) {
if (test=="sldk") {
document.getElementById("frame1").src = "url1";
var f1 = frames['frame1'].document.forms['mktForm_1108'];
f1.elements['FirstName'].value = test;
}else{
document.getElementById("frame1").src = "url2";
}
isLoadedByIFrameDirect = true;
}
}
Okay, so the problem is that I created a sel-freferencing onload event. Bad idea. To solve the issue, I needed to remove the onload from the iframe element. I tried putting it in the Body before without luck. But I might have screwed it up, so don't ignore that option if you have a similar situation. I decided to do it with Javascript right after the function. If you are a novice, the difference between Javascript onload and HTML onload can be found here
W3Schools onload Event
I still have not solved the "autofilling iframe form from url parameter" portion of this problem. I will make an additional comment to this answer once I figure that out.
In any case, here is the code
function iframedirect() {
if(!isLoadedByIFrameDirect) {
if (test=="sldk") {
document.getElementById("frame1").src = "http://na- sj09.marketo.com/lp/cochlearsandbox/UpgradeInterest_IFrameLandingPage.html";
var f1 = frames['frame1'].document.forms['mktForm_1108'];
f1.elements['FirstName'].value = test;
}else{
document.getElementById("frame1").src = "http://na-sj09.marketo.com/lp/cochlearsandbox/CAM-UpgradeInterestForm_iFrameLandingPage2ndOption.html";
}
isLoadedByIFrameDirect = true;
}
}
window.onload = iframedirect;

how can you determine location of <script> tag from inside said tag?

I am trying to figure out the location of the script tag the current javascript is running in. What is really going on is that I need to determine from inside a src'd, dynamically inserted javascript file where it is located in the DOM. These are dynamically generated tags; code snippet:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>where am i?</title>
<script type="text/javascript" charset="utf-8">
function byId(id) {
return document.getElementById(id);
}
function create_script(el, code) {
var script = document.createElement("script");
script.type = "text/javascript";
script.text = code;
el.appendChild(script);
}
</script>
</head>
<body>
<div id="find_me_please"></div>
<script>
create_script(byId("find_me_please"), "alert('where is this code located?');");
</script>
</body>
</html>
You could give the script an id tag, like this dude does...
You can use document.write to create a dummy DOM object and use parentNode to escape out. For example:
<script>
(function(r) {
document.write('<span id="'+r+'"></span>');
window.setTimeout(function() {
var here_i_am = document.getElementById(r).parentNode;
... continue processing here ...
});
})('id_' + (Math.random()+'').replace('.','_'));
</script>
This assumes you don't actually have control of the <script> tag itself, such as when it's inside a <script src="where_am_i.js"></script> - if you do have control of the <script> tag, simply put an ID on it, as in:
<script id="here_i_am">...</script>
If you are just running this on page load, this works
<script>
var allScripts = document.getElementsByTagName('script');
var thisScript = allScripts[allScripts.length];
alert(thisScript);
</script>

Categories