Custom CSS feature to inject custom JavaScript
-
@julianlam actually no, this script executes only once, I did some testing on most of the pages I could think of, minus the /admin routes, which doesn't apply there.
@planner is you want it to execute for every page, use the
action:ajaxifying
oraction:ajaxifed
oraction:page.load
hook, not sure which lol<script> $(function(){ $('body').on('action:ajaxifying', function(e, data) { /// your script here }); }); </script>
-
@bentael said:
@julianlam actually no, this script executes only once, I did some testing on most of the pages I could think of, minus the /admin routes, which doesn't apply there.
Yeah, you're right, I meant adding scripts using the existing widget boxes. Your workaround does work as advertised
action:ajaxifying
,action:ajaxified
, andaction:page.load
all execute once, just at different parts of the "page loading" sequence of events -
@psychobunny please don't close that on us frowning it's not a security risk, unless the admin deliberately inject a malicious script
yeah, global widget areas coming soon. nice trick though
-
I put a GA tag in the code to give me something like this, but page load hangs at about 80%. What could be wrong?
<script> $(function(){ $('body').on('action:ajaxifying', function(e, data) { /// your script here <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- Forum Header --> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-8aa076493813069" data-ad-slot="8248656285" data-ad-format="auto"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> }); }); </script>
-
@planner your markup/syntax is invalid.
If I got this right, you want to inject a script into the header, and make a call every time a page is loaded, so I think here's how it should look like:Note this snippet is to be used on the Custom CSS page in the Admin console.,
/* at this point we're in a <style> tag. so let me close that tag for you */ </style> <!-- here you can place regular html, this is a comment, you can remove all the comments if you want --> <!-- so I am going to inject the googlesyndycation script only one time on the page --> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- and I am going to place the placeholder element for it, also one time on the page --> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-8aa076493813069" data-ad-slot="8248656285" data-ad-format="auto"></ins> <!-- then, on document.ready, I am going to attach an event listener to the body, so it would trigger the 'adsbygoogle.push()' call, everytime there is a page ajaxifying --> <script> $(function(){ $('body').on('action:ajaxifying', function(e, data) { (adsbygoogle = window.adsbygoogle || []).push({}); }); }); </script> <!-- then, I am going to reopen that <style> tag so the end result html injected by NodeBB would still be valid --> <style> /* now we're back inside of a style tag so we use a different syntax for commenting if you noticed .. */
However, please note that
action:axaxifying
may not be the correct event to listen to, I will let @julian correct that if it's not right.
I hope that answers your question -
also note that this tag,
<ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-8aa076493813069" data-ad-slot="8248656285" data-ad-format="auto"></ins>
doesn't have to be here, in fact, you most likely don't want it to be here, it could live in a widget or whereever... another template.. footer ..
-
Thanks, I'll take a closer look at that code. However, that's just one of the things I'm tying to do. The other is add analytics tag from Piwik and Quantcast to the footer, so that all user page actions, whether Ajaxified or not, register as unique page views.
For example, I have this Piwik tag that needs to go in a Global footer widget. The problem is it does not register all user activities:
<script type="text/javascript"> var _paq = _paq || []; _paq.push(["setDocumentTitle", document.domain + "/" + document.title]); _paq.push(["setCookieDomain", "*.linuxisi.com"]); _paq.push(["trackPageView"]); _paq.push(["enableLinkTracking"]); (function() { var u=(("https:" == document.location.protocol) ? "https" : "http") + "://linise.com/analyz/"; _paq.push(["setTrackerUrl", u+"piwik.php"]); _paq.push(["setSiteId", "1"]); var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript"; g.defer=true; g.async=true; g.src=u+"piwik.js"; s.parentNode.insertBefore(g,s); })(); </script>
Even when I enclose insert it in the code you gave some time ago, it still does not seem to trigger on all user activities.
This is the bit of code you provided. I know it's the same you used in your post, but when it comes to splitting JS tag like you did with the Google tag, I can very easily screw things up. I cam mess with HTML/CSS, but not JS. That should change by the end of the year, though
<script> $(function(){ $('body').on('action:ajaxifying', function(e, data) { /// your script here }); }); </script>
-
ok so, it turns out
$('body').on('action:ajaxifying')
no longer works, I think it got replaced byaction:ajaxify.end
and it's on thewindow
instead of thebody
.However, don't take my word for it yet, track that thread.Assuming, i am right, you should be able to do thatedit: @planner That should work
</style> <!-- gooogle ads --> <script async defer src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-8aa076493813069" data-ad-slot="8248656285" data-ad-format="auto"></ins> <script> // global _paq var _paq = _paq || []; _paq.push(["setCookieDomain", "*.linuxisi.com"]); _paq.push(["enableLinkTracking"]); _paq.push(["setTrackerUrl", ("https:" == document.location.protocol) ? "https" : "http") + "://linise.com/analyz/piwik.php"]); _paq.push(["setSiteId", "1"]); </script> <!-- then inject the piwic script, the old fashioned way, instead of writing the script tag --> <script async defer src="//linise.com/analyz/piwik.js"></script> <script> $(function() { $(window).on('action:ajaxify.end', function(e, data) { (adsbygoogle = window.adsbygoogle || []).push({}); // according to the piwik documentation, http://developer.piwik.org/api-reference/tracking-javascript, i should be to trigger page view like that _paq.push(["setDocumentTitle", document.domain + "/" + document.title]); // I set the document title every time, because it may have changed _paq.push(["trackPageView"]); }); }); </script> <style>
You do not have to have all of your javascript in the footer, it's true that it helps a teeny tiny bit with page performance, since scripts execution is usually synchronous, (but using the html5
async
anddefer
remedies that a bit for new browsers) anyways trust me, you will never feel the difference for small scripts like these. -
@DennisSun The widget is called "HTML", just add a javascript-tag
-
@frissdiegurke well , I tried to involve javascript code in the html widget. But it didn't work. I can't even see the whole homepage after that.
-
@DennisSun Any errors on console?
this example works fine for me:
<script type="text/javascript"> console.log('hello world!'); </script>
-
@frissdiegurke no error showed in log.
here is what I added:
<script type="text/javascript">
var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F0da233db09b6a0886cd3f9d1a52e64d8' type='text/javascript'%3E%3C/script%3E"));
</script>The analytics code form baidu.com
-
yes,
document.write
replaces the whole site use sth like<script src='https://hm.baidu.com/h.js?0da233db09b6a0886cd3f9d1a52e64d8' type='text/javascript'></script>
this seems to be what the script is supposed to do (or
http://
if you don't use TLS). -
@frissdiegurke when using
document.write
you can avoid replacing the whole site, but it cannot be loaded asynchronously aka injected (as it needs to execute immediately on DOM build), which is most likely the case on most NodeBB pages@DennisSun if you want to have a dynamic the protocol, or maybe that string at the end, use something like
<script type="text/javascript"> (function() { var something = '0da233db09b6a0886cd3f9d1a52e64d8'; // or could be dynamically generated, I don't know // build your script tag var script = document.createElement('script'); script.type = 'text/javascript'; // that's useless, browsers ignore it, but whateves script.async = true; script.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'hm.baidu.com/h.js?' + something; // google analytics does that, this will find this actually script (unless loaded asynchronously, in that case it would find the last script tag on the page) // it should work in either case // var thisScriptTag = document.getElementsByTagName('script')[0]; // thisScriptTag.parentNode.insertBefore(script, s); // or you can just append it to the head var head = document.getElementsByTagName('head')[0]; head.appendChild(script); })(); </script>