The disqus comments are loading here: http://www.oddprints.com/help
but not here: https://www.oddprints.com/help any ideas?
All resources appear to be secure (protocol relative urls) so I don't think it's that.
It because disqus was treating the two urls as different and therefore loading different threads. If you want both http and https urls to have the same comments thread on it, you need to supply a canonical url in the disqus config. This is how I did it:
<div id="disqus_thread"></div>
<script>
/**
* https://disqus.com/admin/universalcode/#configuration-variables
*/
var disqus_config = function () {
this.page.url = "http://www.oddprints.com/help";
//this.page.identifier = "oddprints"; // add a different id here if you want a fresh thread....
};
(function() {
var d = document, s = d.createElement('script');
s.src = '//oddprints.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the comments powered by Disqus.</noscript>
Note that in the config I passed the http url as the canonical url and I've not set the page.identifier. I've done this so that it continues to serve up the comments I already had from back when it was just http and using an older version of the disqus snippet.
Disqus comment are loaded but Disqus consider these two page as different.
Did you follow that : https://help.disqus.com/customer/portal/articles/542119-can-disqus-be-loaded-via-https- ?
Related
trying to add Tangle.js library to jsfiddle and it's not working.
Fiddle is here
Code is:
var tangle = new Tangle (document.getElementById("bedroomcostcalculator"), {
initialize: function () {
this.bedrooms = 2;
this.cost = 300000;
this.costperbedroom = 150000;
},
update: function () {
this.cost = this.bedrooms * this.costperbedroom;
}
});
URL for Tangle is: http://worrydream.com/Tangle/Tangle.js
We've added the URL to External Resources, but it's not picking it up. I've seen other posts about needing to link to CDN format - how would we do that?
As you said, the URL for the library is http://worrydream.com/Tangle/Tangle.js, but in your jsfiddle, you're using the URL https://worrydream.com/Tangle/Tangle.js (https instead of http).
That second link simply doesn't work.
Switch to loading your jsfiddle via HTTP instead of HTTPS (change the URL to http instead of https) and then fix the Tangle library URL to the HTTP version.
External resources need to be loaded over HTTPS. When adding the resource, you see this message:
You would need to find a secure CDN that offers Tangle.js.
Most javascript widget which can be embedded into a website use the following structure. First you embed a code snipped like this:
<script type="text/javascript">
window.$zopim||(function(d,s){var z=$zopim=function(c){
z._.push(c)},
$=z.s=d.createElement(s),
e=d.getElementsByTagName(s)[0];
z.set=function(o){
z.set._.push(o)
};
z._=[];
z.set._=[];
$.async=!0;
$.setAttribute('charset','utf-8');
$.src='//v2.zopim.com/?2342323423434234234';
z.t=+new Date;
$.type='text/javascript';
e.parentNode.insertBefore($,e)})(document,'script');
</script>
Then, when load your page this script creates a html structure like this:
<div class="widget-class">
<iframe src="about:blank">
// the content of the widget
</iframe>
</div
I see this same structure in many chat services like:
https://en.zopim.com/
http://banckle.com/
https://www.livechatinc.com/
All have in common that their iframe does not have a src, i.e., an URL attached.
Update: Here is the script I use to load my widget code into a third party website:
<script type="text/javascript">
(function(d){
var f = d.getElementsByTagName('SCRIPT')[0], p = d.createElement('SCRIPT');
window.WidgetId = "1234";
p.type = 'text/javascript';
p.setAttribute('charset','utf-8');
p.async = true;
p.src = "//www.example.com/assets/clientwidget/chatwidget.nocache.js";
f.parentNode.insertBefore(p, f);
}(document));
</script>
I want that the CSS of the site where the GWT widget is integrated should not influence the CSS of the GWT widget. I will prevent that the CSS of the host page influence the CSS of my GWT widget.
Note: I want to have access to tho host website from my GWT widget too.
The domain of the host page is www.example.com and the domain of the iframe is www.widget.com. I also want to set cookies of the host domain from the iframe.
What is the procedure of building a widget running on such a structure? How is the content of the iframe being set? Is there a pattern for that? How can I do that with GWT
I don't know GWT, but you can easily achieve this in plain JavaScript.
Let's assume you're creating an online-count widget. At first, create an iframe:
<script id="your-widget">
// Select the script tag used to load the widget.
var scriptElement = document.querySelector("your-widget");
// Create an iframe.
var iframe = document.createElement("iframe");
// Insert iframe before script's next sibling, i.e. after the script.
scriptElement.parentNode.insertBefore(iframe, scriptElement.nextSibling);
// rest of the code
</script>
Then fetch the online count using JSONP (see What is JSONP all about?), for example:
// The URL of your API, without JSONP callback parameter.
var url = "your-api-url";
// Callback function used for JSONP.
// Executed as soon as server response is received.
function callback(count) {
// rest of code
}
// Create a script.
var script = document.createElement("script");
// Set script's src attribute to API URL + JSONP callback parameter.
// It makes browser send HTTP request to the API.
script.src = url + "?callback=callback";
Then handle server response (inside the callback() function):
// Create a div element
var div = document.createElement("div");
// Insert online count to this element.
// I assume that server response is plain-text number, for example 5.
div.innerHTML = count;
// Append div to iframe's body.
iframe.contentWindow.document.body.appendChild(div);
That's all. Your whole code could look like this:
Snippet to insert into third party website:
<script type="text/javascript">
(function(d){
var f = d.getElementsByTagName('SCRIPT')[0], p = d.createElement('SCRIPT');
window.WidgetId = "1234";
p.type = 'text/javascript';
p.setAttribute('charset','utf-8');
p.async = true;
p.id = "your-widget";
p.src = "//www.example.com/assets/clientwidget/chatwidget.nocache.js";
f.parentNode.insertBefore(p, f);
}(document));
</script>
JavaScript file on your server:
// Select the script tag used to load the widget.
var scriptElement = document.querySelector("#your-widget");
// Create an iframe.
var iframe = document.createElement("iframe");
// Insert iframe before script's next sibling, i.e. after the script.
scriptElement.parentNode.insertBefore(iframe, scriptElement.nextSibling);
// The URL of your API, without JSONP callback parameter.
var url = "your-api-url";
// Callback function used for JSONP.
// Executed as soon as server response is received.
function callback(count) {
// Create a div element
var div = document.createElement("div");
// Insert online count to this element.
// I assume that server response is plain-text number, for example 5.
div.innerHTML = count;
// Append div to iframe's body.
iframe.contentWindow.document.body.appendChild(div);
}
// Create a script.
var script = document.createElement("script");
// Set script's src attribute to API URL + JSONP callback parameter.
// It makes browser send HTTP request to the API.
script.src = url + "?callback=callback";
EDIT:
if you want your widget to not be influenced by any css from the "outside" you have to load into an iframe.
code to add to your website to load any gwt project/widget:
<iframe id="1234" src="//www.example.com/assets/Chatwidget.html" style="border: 1px solid black;" tabindex="-1"></iframe>
notice: that im NOT loading the nocache.js but the yourwidget.html file.
like this all your clases insde the frame wont be affected by any class from the outside.
to access anything outside ofthis iframe you can use jsni methods. this will only work if the domain of your iframe and the thirdpartysite are the same. otherwise youve to use window.postMessage:
public native static void yourMethod() /*-{
$wnd.parent.someMethodFromOutsideTheIframe();
}-*/;
EDIT2:
by using the snippet from above you make sure that your widget is not influened by any css from the hostpage.
to get the hostpage url from inside the widget simply add this function:
private native static String getHostPageUrl() /*-{
return $wnd.parent.location.hostname;
}-*/;
EDIT3:
since you are on 2 different domains, you have to use window.postMessage.
here one little example to get you going:
besides the iframe you have to add a event listener to the window of your example.com, that listens for the messages from your iframe. you also check if the messages comes form the correct origin.
<script>
// Create IE + others compatible event handler
var eventMethod = window.addEventListener ? "addEventListener"
: "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage"
: "message";
// Listen to message from child window
eventer(messageEvent, function(e) {
//check for the correct origin, if wanted
//if ( e.origin !== "http://www.widget.com" )
// return
console.log('parent received message!: ', e.data);
//here you can set your cookie
document.cookie = 'cookie=widget; expires=Fri, 1 Feb 2016 18:00:00 UTC; path=/'
}, false);
</script>
From inside your widget you call this method:
public native static void postMessageToParent(String message) /*-{
//message to sent, the host that is supposed to receive it
$wnd.parent.postMessage(message, "http://www.example.com");
}-*/;
i put a working example on pastebin:
javascript to insert into your page: http://pastebin.com/Y0iDTntw
gwt class with onmoduleload: http://pastebin.com/QjDRuPmg
Here's a full functional simple widget expample project I wrote in cloud9 (online IDE) with javascript, please feel free to request an access if you want to edit it, viewing is publicly available (for registered users - registration is free).
sources:
https://ide.c9.io/nmlc/widget-example,
result:
https://widget-example-nmlc.c9users.io/index.html
As for the question about how do they do it:
It seems that zopim builds their widgets gradually on the client side, defining and requiring basic modules (like these __$$__meshim_widget_components_mobileChatWindow_MainScreen), which are consist from submodules and then process everything with __$$__jx_ui_HTMLElement builder which creates HTML elements and appends them to provided parent nodes. All that compiles to the resulting HTML of the chatbox. Btw, judging by the names of some components, it seems, they build their widgets with some "meshim" library, but I have never heard of this library.
this.dom.src='about:blank'
this.appendToParent(!0)
var H=this.iwin=this.dom.contentWindow
var I=this.idoc=r.extend(H.document)
I.write(G)
I.close()
This, I guess, is the place where zopim service creates an iframe for their widgets. I'm not sure why they are using document.write instead of appendChild (document.write drops event bindings), but I have implemented both versions - they are pretty much the same except setIframeContents and addHtmlElement functions.
Hope someone will find this useful :).
1) There are many different ways to load content to iframe. Iframe have isolated content. iframe that you put in host page, does not have src, because of browser secure politic, you can't simply load content from other domains. But you can load js from other domain.For this porpuse you need usw JSONP
2) to share cookies with host page and widget iframe, you need use postMessage api like in this post
I'm trying to figure out what's the best solution to the scenario below.
I'm showing my articles on the home page and also on the archive page. Home page Url structure is not the same as the archive page and I think that's where the confusion is coming from. When a visitor leaves a comment on an article on the home page, the comment does not show on the article in the archive page and vice versa.
This is the article Url structure on home page:
domain.com/portal/home/full-article/article-title/
and this is the Url structure on archive page:
domain.com/portal/archives/full-article/article-title/
and this the JavaScript code from Disqus:
<div id="disqus_thread"></div>
<script>
/*var disqus_config = function () {
this.page.url = PAGE_URL; // Replace PAGE_URL with your page's canonical URL variable
this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
};*/
(function() { // DON'T EDIT BELOW THIS LINE
var d = document, s = d.createElement('script');
s.src = '//short-name.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>Please enable JavaScript to view the comments powered by Disqus.</noscript>
I want the comments to sync and show on the home page and the archive page. As of now, the comments are showing differently depending on the page the visitor picked to leave a comment.
I read the documentation but I'm not sure if un-commenting this.page.url and this.page.identifier helps with this situation. If it does, what values should I use in Sitefinity?
The identifier sets the Disqus thread.
https://help.disqus.com/customer/portal/articles/472095-how-do-i-load-the-same-thread-of-comments-on-multiple-pages-
You need to make sure the identifier value is set to something that is unique, in your case the article.
If the identifier is missing, it uses the url
Read more here:
https://help.disqus.com/customer/portal/articles/472098-javascript-configuration-variables
Where is the JS file and is this Async the fastest way to call JS?
I guess they then have PHP calls in the .JS for updating the Ad stats??
The code:
<script type="text/javascript">
(function(){
var acc = "acc_230d269_pub";
var st = "nocss";
var or = "h";
var e = document.getElementsByTagName("script")[0];
var d = document.createElement("script");
d.src = ('https:' == document.location.protocol ?'https://' : 'http://')+"engine.influads.com/show/"+or+"/"+st+"/"+acc;
d.type = "text/javascript";
d.async = true;
d.defer = true;
e.parentNode.insertBefore(d,e);
})();
</script>
I've made your code more readable:
1 <script type="text/javascript">
2 (function () {
3 var acc = "acc_230d269_pub";
4 var st = "nocss";
5 var or = "h";
6 var e = document.getElementsByTagName("script")[0];
7 var d = document.createElement("script");
8 d.src = ('https:' == document.location.protocol ? 'https://' : 'http://') +
9 "engine.influads.com/show/" + or + "/" + st + "/" + acc;
10 d.type = "text/javascript";
11 d.async = true;
12 d.defer = true;
13 e.parentNode.insertBefore(d, e);
14 })();
15 </script>
2,14 An anonymous function wrapper is created, so that variables cannot be access from outside the function ("scope")
3 acc looks like the identifier of the advertiser
4,5 st = "nocss" and or = "h" looks like settings to adjust the appearance
7,10-12 A <script> tag is created. async = Loading the script will not block the execution of the document. defer=true prevents the script from not being executed (can be omitted)
6,13 The newly created script tag is inserted before (13) the first script tag in the document (6,13)
8,9 The URL is constructed:If the current page is transmitted over a secure connection, the injected script will also be transferred over the HTTPS protocol.
The extension of the requested file is omitted. This file could be served using the application/javascript MIME type by server configuration.
It inserts the script tag with a dynamically constructed file name and puts it in the document before the first script tag. The advantage of this approach is that it will run only when the document is loaded, so it will not block the document loading. This way, the user will experience no (or less) delay. It's a good practise to do this for analytical tools and such, because they don't add functionality for the user and you just want to track their actions. It doesn't matter if you miss one or two of those measurements.
There are a couple of ways to include js code into html, one is put the code directly into the tag, just like what you wondered about the code you posted, the other method is to use the following syntax:
<script type="text/javascript" src="path/to/external_file.js"></script>
As a side note, the code you posted uses a technique that prevents js name spacing conflicts by putting the code in the
(function() ...)(); block, which I find to be a very good practice.
Regarding the question about using async in tag, you might want to take a look at this:
http://davidwalsh.name/html5-async
Most of that code is for loading the JavaScript code asynchronously, in a way that works in different browsers. An explanation of how it works is here: http://friendlybit.com/js/lazy-loading-asyncronous-javascript/
Loading asynchronously means that the browser doesn't wait for it to finish. So the ad won't load faster, but the rest of the page will.
If you piece together the string, you'll find that the JavaScript file they're loading is: http://engine.influads.com/show/h/nocss/acc_230d269_pub
The benefits I see are:
Asynchronous loading that would help in faster rendering of the UI
The selective http or https used for the location of the js source following the protocol that current page is loaded with
I am wondering why the js source would not end with a .js extension though
I have heard and read a few articles about deferring JavaScript loading and am very interested. It seems to be very promising for web apps that may be useful on Mobile platforms where the amount of JavaScript that can be loaded and executed is limited.
Unfortunately, most of the articles talk about this at an extremely high level. How would one approach this?
EDIT
Normally, all JavaScript is loaded on page load, however, there may be functions that are not necessary until a certain action occurs, at which time, the JavaScript should be loaded. This helps ease the burden of the browser on page load.
Specifically, I have a page that very heavily uses JavaScript. When I load the page on my phone, it won't load properly. As I debugged the page, I eliminated some of the JS functions. Once enough was eliminated, the page suddenly worked.
I want to be able to load the JS as needed. And possibly even eliminate the functions simply used for start up.
The basics are simple - breaking up your JavaScript code into logically separate components and loading only what you need. Depending on what you are building you can use:
Loaders:
Modernizr.load (or yepnope.js by itself)
LABjs
Many, many, many other deferred loading libraries.
Dependency managers (which are also loaders):
Require.js
dojo.require
JavaScript MVC's steal.js
Several other dependency management libraries.
These tools make use of a wide variety of techniques to defer the loading of scripts, the execution of scripts, manage dependencies, etc. What you need depends on what you are building.
You may also want to read through this discussion to learn something more about the pros and cons of using such techniques.
Response to edit:
There isn't really a good way to unload JavaScript that you have already loaded - the closest approximation you can get is to keep all of your loading code namespaced inside your application's namespace and then "clean up" by setting that namespace, and all references to it to null.
I have used a simple script published on line with some modification done by me.
Assume that your COMPRESSED Javascript file is in the cache directory in your webserver and you want to defer the loading of this compressed js file.
Your compressed js file:
80aaad2a95e397a9f6f64ac79c4b452f.js
This is the code html code:
<script type="text/javascript" src="/resources/js/defer.js?cache=80aaad2a95e397a9f6f64ac79c4b452f.js"></script>
This is the defer.js file content:
(function() {
/*
* http://gtmetrix.com/
* In order to load a page, the browser must parse the contents of all <script> tags,
* which adds additional time to the page load. By minimizing the amount of JavaScript needed to render the page,
* and deferring parsing of unneeded JavaScript until it needs to be executed,
* you can reduce the initial load time of your page.
*/
// http://feather.elektrum.org/book/src.html
// Get the script tag from the html
var scripts = document.getElementsByTagName('script');
var myScript = scripts[ scripts.length - 1 ];
// Get the querystring
var queryString = myScript.src.replace(/^[^\?]+\??/,'');
// Parse the parameters
var params = parseQuery( queryString );
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = '/cache/' + params.cache; // Add the name of the js file
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
function parseQuery ( query ) {
var Params = new Object ();
if ( ! query ) return Params; // return empty object
var Pairs = query.split(/[;&]/);
for ( var i = 0; i < Pairs.length; i++ ) {
var KeyVal = Pairs[i].split('=');
if ( ! KeyVal || KeyVal.length != 2 ) continue;
var key = unescape( KeyVal[0] );
var val = unescape( KeyVal[1] );
val = val.replace(/\+/g, ' ');
Params[key] = val;
}
return Params;
}
})();
I would like to say thanks to http://feather.elektrum.org/book/src.html that helped me to understand how to get the parameters from the script tag.
bye
Deferring loading til when?
The reason typically why JS is loaded last, is so that the entire DOM has been loaded first.
An easy way is to just use
<body onload="doSomething();">
So you could easily have doSomething() function to load all your JS.
You can also add a function to window.onload, like
window.onload = function(){ };
Also, if you are using JS librarys, such as jQuery and Dojo, they each have their own onReady and addOnLoad methods in order to run some JS only after the document has already loaded.
Here's a useful article on the script element's defer and async attributes. Specifying these attributes will get the browser to defer loading in different ways. You can also load in an external script using JavaScript after page load.
It should also be noted that the position of your script elements within your HTML document will determine load and execution order if neither defer nor async have been specified.