I'm having some trouble running some JS inside a html5 body.
Here's what's happening, whenever I remove all instances of the arrays from the JS file I am using, the script loads fine in the index file, however, when I add src to the attribute and/or mention an array name from said file, it breaks. simple as that.
since I'm planning on making a pretty big site, I have already begun organizing my root.
here's a little demo:
rootFolder/
index.htm
js/targetJS.js
here's the code
<script src="js/targetJS.js" type="text/javascript">
document.writeln("<table id='services' class='services' name='services'>");
document.writeln("<tr>");
document.writeln("<th> Preview: </th>");
document.writeln("<th> Description: </th>");
document.writeln("<th> Cost: </th>");
document.writeln("</tr>");
var i = 0;
//for ( i = 0; i < servicePrev.length; i++)
{
if (i % 2 == 0){
document.writeln("<tr class='even' id='even'>");
}
else{
document.writeln("<tr class='odd' id='odd'>");
}
//document.writeln("<td> " + servicePrev[i] + " </td>");
//document.writeln("<td> " + serviceDesc[i] + " </td>");
//document.writeln("<td> " + serviceCost[i] + " </td>");
document.writeln("</tr>");
}
document.writeln("</table>");
</script>
Whenever i add the src in the attribute and the lines that are commented out, the code does not work, however, when I omit the src and the lines that are currently commented out, the code works fine. even JSfiddle reports it working fine.
The contents of the JS file are 3 arrays with 5 indexes.
You need to seperate your tags
<script type="text/javascript" src="awesomescript.js"></script>
and
<script>
// some awesome code here
</script>
Since html5, you are free to name <script type="text/javascript"> or just use <script> for javascript, as text/javascript is default.
Quoted from http://javascript.crockford.com/script.html
The script tag has two purposes:
It identifies a block of script in the page. It loads a script file.
Which it does depends on the presence of the src attribute. A
close tag is required in either case.
The src attribute is optional. If it is present, then its value is a
url which identifies a .js file. The loading and processing of the
page pauses while the browser fetches, compiles, and executes the
file. The content between the and the
should be blank.
So, the script file should be loaded by dedicated script tag without content, the script content should be inserted into another script tag, after all if you have other errors you can check in the console of your broswer
<script src="js/targetJS.js" type="text/javascript"></script>
<script type="text/javascript">
document.writeln("<table id='services' class='services' name='services'>");
document.writeln("<tr>");
document.writeln("<th> Preview: </th>");
document.writeln("<th> Description: </th>");
document.writeln("<th> Cost: </th>");
document.writeln("</tr>");
var i = 0;
//for ( i = 0; i < servicePrev.length; i++)
{
if (i % 2 == 0){
document.writeln("<tr class='even' id='even'>");
}
else{
document.writeln("<tr class='odd' id='odd'>");
}
//document.writeln("<td> " + servicePrev[i] + " </td>");
//document.writeln("<td> " + serviceDesc[i] + " </td>");
//document.writeln("<td> " + serviceCost[i] + " </td>");
document.writeln("</tr>");
}
document.writeln("</table>");
</script>
The following function only replaces the first "<br />" it finds, not the following ones. Does anyone know how to fix that problem?
I want the function to replace all the strings in the whole document.
<script language="javascript" type="text/javascript">
window.onload = function umtauschen()
{
document.body.innerHTML = document.body.innerHTML.replace('<br />', '<br />');
document.body.innerHTML = document.body.innerHTML.replace('<b>', '<b>');
document.body.innerHTML = document.body.innerHTML.replace('</b>', '</b>');
}
</script>
Thanks
Use regular expressions, and the g (global) flag:
document.body.innerHTML = document.body.innerHTML
.replace(/<br \/>/g, '<br />')
.replace(/<b>/g, '<b>')
.replace(/<\/b>/g, '</b>');
Another option is to use the .split(find).join(replace) idiom:
document.body.innerHTML = document.body.innerHTML
.split('<br />').join('<br />')
.split('<b>').join('<b>')
.split('</b>').join('</b>');
following code should solve your problem:
document.body.innerHTML = document.body.innerHTML.replace(/</g, '<').
replace(/>/g, '>') ;
If the document is dynamic, as in generated by a script, PHP or otherwise, it's better idea to replace the tags in the DB or while printing the data. If it's a static HTML page, it's a better idea to edit code in the original file.
Dynamically replacing the entire body after page load is going to perform slowly.
buildIMG = (src, resize) ->
html = '<div class="left"><div class="foods_image">'
html += '<a onclick="popitup("http://somewhere.com/test" href="javascript:void(0)">'
html += ' <img src="'+src+'" '+resize+' />'
html += '</a>'
html += '</div></div>'
html
popitup = (url) ->
newwindow=window.open(url,'name','height=640,width=640')
newwindow.focus() if window.focus
false
I currently have a bookmarklet that inserts javascript code(the one above) into a website. I wrote the above coffeescript and it generates this:
(function() {
var buildIMG, popitup;
buildIMG = function(src, resize) {
var html, nbsp;
html = '<div class="left"><div class="foods_image">';
html += '<a onclick="popitup(\'http://somewhere.com/test\');" href="javascript:void(0)">';
html += ' <img src="' + src + '" ' + resize + ' />';
html += '</a>';
html += '</div></div>';
return html;
};
popitup = function(url) {
var newwindow;
newwindow = window.open(url, 'name', 'height=640,width=640');
return newwindow.focus()(window.focus ? false : void 0);
};
}).call(this);
I snipped the functions that uses buildIMG. That function creates an overlay over the site and displays all images in that overlay. buildIMG is called for each image to create the html.
The problem is that the onclick="popitup("http://somewhere.com/test" portion doesn't work. It is undefined.
A solution I did was to remove this which was generated by CoffeeScript:
(function() {
}).call(this);
It was fixed as soon as I removed that. How do I not have CoffeeScript put in those lines in my generated javascript?
CoffeeScript allows to compile JavaScript without this safety wrapper by --bare option.
Although suppressed within this documentation for clarity, all
CoffeeScript output is wrapped in an anonymous function: (function(){
... })(); This safety wrapper, combined with the automatic generation
of the var keyword, make it exceedingly difficult to pollute the
global namespace by accident.
It's from CoffeScript site.
If you want to create a global method or variable you need to
root = this
localProperty = "111"
root.property = localProperty
And then you'll get a property in global scope.
I'm trying to create and manipulate the Pin It button after page load. When i change the button properties with js, it should be rerendered to get the functionality of pinning dynamically loaded images. So, does Pinterest have any method like Facebook's B.XFBML.parse() function?
Thanks...
Just add data-pin-build attribute to the SCRIPT tag:
<script defer
src="//assets.pinterest.com/js/pinit.js"
data-pin-build="parsePinBtns"></script>
That causes pinit.js to expose its internal build function to the global window object as parsePinBtns function.
Then, you can use it to parse links in the implicit element or all of the links on the page:
// parse the whole page
window.parsePinBtns();
// parse links in #pin-it-buttons element only
window.parsePinBtns(document.getElementById('pin-it-buttons'));
Hint: to show zero count just add data-pin-zero="1" to SCRIPT tag.
The best way to do this:
Remove the iframe of the Pin It button you want to manipulate
Append the html for the new button manipulating it as you wish
Realod their script - i.e. using jQuery:
$.ajax({ url: 'http://assets.pinterest.com/js/pinit.js', dataType: 'script', cache:true});
To render a pin-it button after a page has loaded you can use:
<a href="..pin it link.." id="mybutton" class="pin-it-button" count-layout="none">
<img border="0" src="//assets.pinterest.com/images/PinExt.png" width="43" height="21" title="Pin It" />
</a>
<script>
var element = document.getElementById('mybutton');
(function(x){ for (var n in x) if (n.indexOf('PIN_')==0) return x[n]; return null; })(window).f.render.buttonPin(element);
</script>
Assuming of course the assets.pinterest.com/js/pinit.js is already loaded on the page. The render object has some other useful methods like buttonBookmark, buttonFollow, ebmedBoard, embedPin, embedUser.
I built on Derrek's solution (and fixed undeclared variable issue) to make it possible to dynamically load the pinterest button, so it can't possibly slow down load times. Only tangentially related to the original question but I thought I'd share anyway.
at end of document:
<script type="text/javascript">
addPinterestButton = function (url, media, description) {
var js, href, html, pinJs;
pinJs = '//assets.pinterest.com/js/pinit.js';
//url = escape(url);
url = encodeURIComponent(url);
media = encodeURIComponent(media);
description = encodeURIComponent(description);
href = 'http://pinterest.com/pin/create/button/?url=' + url + '&media=' + media + '&description=' + description;
html = '<img border="0" src="http://assets.pinterest.com/images/PinExt.png" title="Pin It" />';
$('#pinterestOption').html(html);
//add pinterest js
js = document.createElement('script');
js.src = pinJs;
js.type = 'text/javascript';
document.body.appendChild(js);
}
</script>
in document ready function:
addPinterestButton('pageURL', 'img', 'description');//replace with actual data
in your document where you want the pinterest button to appear, just add an element with the id pinterestOption, i.e.
<div id="pinterestOption"></div>
hope that helps someone!
Here's what I did.
First I looked at pinit.js, and determined that it replaces specially-marked anchor tags with IFRAMEs. I figured that I could write javascript logic to get the hostname used by the src attribute on the generated iframes.
So, I inserted markup according to the normal recommendations by pinterest, but I put the anchor tag into an invisible div.
<div id='dummy' style='display:none;'>
<a href="http://pinterest.com/pin/create/button/?
url=http%3A%2F%2Fpage%2Furl
&media=http%3A%2F%2Fimage%2Furl"
class="pin-it-button" count-layout="horizontal"></a>
</div>
<script type="text/javascript" src="//assets.pinterest.com/js/pinit.js">
</script>
Then, immediately after that, I inserted a script to slurp up the hostname for the pinterest CDN, from the injected iframe.
//
// pint-reverse.js
//
// logic to reverse-engineer pinterest buttons.
//
// The standard javascript module from pinterest replaces links to
// http://pinterest.com/create/button with links to some odd-looking
// url based at cloudfront.net. It also normalizes the URLs.
//
// Not sure why they went through all the trouble. It does not work for
// a dynamic page where new links get inserted. The pint.js code
// assumes a static page, and is designed to run "once" at page creation
// time.
//
// This module spelunks the changes made by that script and
// attempts to replicate it for dynamically-generated buttons.
//
pinterestOptions = {};
(function(obj){
function spelunkPinterestIframe() {
var iframes = document.getElementsByTagName('iframe'),
k = [], iframe, i, L1 = iframes.length, src, split, L2;
for (i=0; i<L1; i++) {
k.push(iframes[i]);
}
do {
iframe = k.pop();
src = iframe.attributes.getNamedItem('src');
if (src !== null) {
split = src.value.split('/');
L2 = split.length;
obj.host = split[L2 - 2];
obj.script = split[L2 - 1].split('?')[0];
//iframe.parentNode.removeChild(iframe);
}
} while (k.length>0);
}
spelunkPinterestIframe();
}(pinterestOptions));
Then,
function getPinMarkup(photoName, description) {
var loc = document.location,
pathParts = loc.pathname.split('/'),
pageUri = loc.protocol + '//' + loc.hostname + loc.pathname,
href = '/' + pathToImages + photoName,
basePath = (pathParts.length == 3)?'/'+pathParts[1]:'',
mediaUri = loc.protocol+'//'+loc.hostname+basePath+href,
pinMarkup;
description = description || null;
pinMarkup = '<iframe class="pin-it-button" ' + 'scrolling="no" ' +
'src="//' + pinterestOptions.host + '/' + pinterestOptions.script +
'?url=' + encodeURIComponent(pageUri) +
'&media=' + encodeURIComponent(mediaUri);
if (description === null) {
description = 'Insert standard description here';
}
else {
description = 'My site - ' + description;
}
pinMarkup += '&description=' + encodeURIComponent(description);
pinMarkup += '&title=' + encodeURIComponent("Pin this " + tagType);
pinMarkup += '&layout=horizontal&count=1">';
pinMarkup += '</iframe>';
return pinMarkup;
}
And then use it from jQuery like this:
var pinMarkup = getPinMarkup("snap1.jpg", "Something clever here");
$('#pagePin').empty(); // a div...
$('#pagePin').append(pinMarkup);
I rewrote the Pinterest button code to support the parsing of Pinterest tags after loading AJAX content, similar to FB.XFBML.parse() or gapi.plusone.go(). As a bonus, an alternate JavaScript file in the project supports an HTML5-valid syntax.
Check out the PinterestPlus project at GitHub.
The official way to do this is by setting the "data-pin-build" attribute when loading the script:
<script defer="defer" src="//assets.pinterest.com/js/pinit.js" data-pin-build="parsePins"></script>
Then you can render your buttons dynamically like so:
// render buttons inside a scoped DOM element
window.parsePins(buttonDomElement);
// render the whole page
window.parsePins();
There is also another method on this site which lets you render them in JavaScript without the script tag.
Here is what i did.. A slight modification on #Derrick Grigg to make it work on multiple pinterest buttons on the page after an AJAX reload.
refreshPinterestButton = function () {
var url, media, description, pinJs, href, html, newJS, js;
var pin_url;
var pin_buttons = $('div.pin-it a');
pin_buttons.each(function( index ) {
pin_url = index.attr('href');
url = escape(getUrlVars(pin_URL)["url"]);
media = escape(getUrlVars(pin_URL)["media"]);
description = escape(getUrlVars(pin_URL)["description"]);
href = 'http://pinterest.com/pin/create/button/?url=' + url + '&media=' + media + '&description=' + description;
html = '<img border="0" src="http://assets.pinterest.com/images/PinExt.png" title="Pin It" />';
index.parent().html(html);
});
//remove and add pinterest js
pinJs = '//assets.pinterest.com/js/pinit.js';
js = $('script[src*="assets.pinterest.com/js/pinit.js"]');
js.remove();
js = document.createElement('script');
js.src = pinJs;
js.type = 'text/javascript';
document.body.appendChild(js);
}
});
function getUrlVars(pin_URL)
{
var vars = [], hash;
var hashes = pin_URL.slice(pin_URL.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
Try reading this post http://dgrigg.com/blog/2012/04/04/dynamic-pinterest-button/ it uses a little javascript to replace the pinterest iframe with a new button and then reloads the pinit.js file. Below is the javascript to do the trick
refreshPinterestButton = function (url, media, description) {
var js, href, html, pinJs;
url = escape(url);
media = escape(media);
description = escape(description);
href = 'http://pinterest.com/pin/create/button/?url=' + url + '&media=' + media + '&description=' + description;
html = '<img border="0" src="http://assets.pinterest.com/images/PinExt.png" title="Pin It" />';
$('div.pin-it').html(html);
//remove and add pinterest js
pinJs = $('script[src*="assets.pinterest.com/js/pinit.js"]');
pinJs.remove();
js = document.createElement('script');
js.src = pinJs.attr('src');
js.type = 'text/javascript';
document.body.appendChild(js);
}
Their pinit.js file, referenced in their "Pin it" button docs, doesn't expose any globals. It runs once and doesn't leave a trace other than the iframe it creates.
You could inject that file again to "parse" new buttons. Their JS looks at all anchor tags when it is run and replaces ones with class="pin-it-button" with their iframe'd button.
this works fine for me: http://www.mediadevelopment.no/projects/pinit/ It picks up all data on click event
I tried to adapt their code to work the same way (drop in, and forget about it), with the addition that you can make a call to Pinterest.init() to have any "new" buttons on the page (eg. ajax'd in, created dynamically, etc.) turned into the proper button.
Project: https://github.com/onassar/JS-Pinterest
Raw: https://raw.github.com/onassar/JS-Pinterest/master/Pinterest.js
As of June 2020, Pinterest updated the pin js code to v2. That's why data-pin-build might not work on
<script defer="defer" src="//assets.pinterest.com/js/pinit.js" data-pin-build="parsePins"></script>
Now it works on pinit_v2.js
<script async defer src="//assets.pinterest.com/js/pinit_v2.js" data-pin-build="parsePins"></script>
I have an ad tag that a third party is trying to stuff inside of a 'document.write' function and it's not working because the ad tag itself also contains document.write's. Is there a way to shove this ad tag inside of a single instance of document.write? If so, please help me figure this out and if not, is there an alternative?
<script type='text/javascript'>
var m3_u = 'http://this.that.com/adtag.js';
var m3_r = Math.floor(Math.random() * 99999999999);
var category='999';
if (!document.MAX_used)
document.MAX_used = ',';
document.write("<scr" + "ipt type='text/javascript' src='" + m3_u);
document.write("?c=" + category +"&b=Sampletag&p=ptnr&key=4984cc8f3064e22a4e29fb2b3b2e9cb5");
document.write('&cb=' + m3_r);
if (document.MAX_used != ',')
document.write("&exclude=" + document.MAX_used);
document.write(document.charset ? '&charset=' + document.charset :
(document.characterSet ? '&charset=' + document.characterSet : ''));
document.write("&loc=" + escape(window.location));
if (document.referrer)
document.write("&referer=" + escape(document.referrer));
if (document.context)
document.write("&context=" + escape(document.context));
if (document.mmm_fo)
document.write("&mmm_fo=1");
document.write("'><\/scr" + "ipt>");
</script>
document.write is often concidered a harmful method, as it directly inserts content into the document file itself. You should edit the innerHTML of the tag where you want to insert the code, although I've heard that directly using innerHTML isn't the correct way either. The method is called insertNode, If I'm remembering correctly, but I'm not sure, because I'm usually abstracting this type of problem away using frameworks such as jQuery, where it is as simple as
$("#myelement").html("<script>...</script>")
I hope that some of my fellow SO members can make this post more precise, I'll look some stuff up myself, but concider this to be my quick answer.