Javascript in my Meteor app still not working - javascript

I originally posted this How can I load js into my templates with Meteor/handlebars.js?
and thought I had a solution to my issue. I was wrong. I have some external js I want to load as well as an internal script. I tried placing the scripts in a template alone for example:
<template name="myscripts">
<script src="myexternalscript"></script>
<script src="anotherexternalscript></script>
<script src="anotherexternalscript"></script>
<script>
//internal script code here
</script>
</template>
then on the template with the html I want those scripts to affect, which contains html named "myothertemplate", I added
{{myscripts}}
to the bottom of those elements where I wanted it to load. Then that template which contains the html elements and the {{myscripts}} which I want to load the JavaScript, is loaded on my main page in the body {{>myothertemplate}}. I run my project, localhost:3000 and get no errors. I see the scripts I wanted there on the page where I wanted them as well but they don't work. They have no affect on the page. I tried taking the internal JavaScript and saving it as a JavaScript file as well as the external JavaScript files however this is not working either. This is an example of what I want:
<!--HTML here-->
<!--some elements here
after the last div on this template page, I wanted to add my scripts.-->
<div>
</div>
<script src="some external script"></script>
<script src="some external script"></script>
<!--Now my internal script-->
<script>
(function() {
// Base template
var base_tpl =
"<!doctype html>\n" +
"<html>\n\t" +
"<head>\n\t\t" +
"<meta charset=\"utf-8\">\n\t\t" +
"<title>Test</title>\n\n\t\t\n\t" +
"</head>\n\t" +
"<body>\n\t\n\t" +
"</body>\n" +
"</html>";
var prepareSource = function() {
var html = html_editor.getValue(),
css = css_editor.getValue(),
js = js_editor.getValue(),
src = '';
src = base_tpl.replace('</body>', html + '</body>');
css = '<style>' + css + '</style>';
src = src.replace('</head>', css + '</head>');
js = '<script>' + js + '<\/script>';
src = src.replace('</body>', js + '</body>');
return src;
};
var render = function() {
var source = prepareSource();
var iframe = document.querySelector('#output iframe'),
iframe_doc = iframe.contentDocument;
iframe_doc.open();
iframe_doc.write(source);
iframe_doc.close();
};
var cm_opt = {
mode: 'text/html',
gutter: true,
lineNumbers: true,
};
var html_box = document.querySelector('#html textarea');
var html_editor = CodeMirror.fromTextArea(html_box, cm_opt);
html_editor.on('change', function (inst, changes) {
render();
});
cm_opt.mode = 'css';
var css_box = document.querySelector('#css textarea');
var css_editor = CodeMirror.fromTextArea(css_box, cm_opt);
css_editor.on('change', function (inst, changes) {
render();
});
cm_opt.mode = 'javascript';
var js_box = document.querySelector('#js textarea');
var js_editor = CodeMirror.fromTextArea(js_box, cm_opt);
js_editor.on('change', function (inst, changes) {
render();
});
var cms = document.querySelectorAll('.CodeMirror');
for (var i = 0; i < cms.length; i++) {
cms[i].style.position = 'absolute';
cms[i].style.top = '30px';
cms[i].style.bottom = '0';
cms[i].style.left = '0';
cms[i].style.right = '0';
cms[i].style.height = '100%';
}
/*cms = document.querySelectorAll('.CodeMirror-scroll');
for (i = 0; i < cms.length; i++) {
cms[i].style.height = '100%';
}*/
}());
</script>

$.getScript('/myscript.js') worked.

Related

JavaScript - Remove script tags from HTML

When a HTML file is loaded, I want to run a script which would remove few scripts tags from the HTML file based on the user agent.
To do this I've followed this question: Removing all script tags from html with JS Regular Expression
But couldn't achieve what I needed, the script tags are removed and they are getting downloaded.
HTML:
<html>
<head>
</head>
<body>
<p></p>
<script type="text/javascript">
function stripScripts(s) {
var div = document.createElement('div');
div.innerHTML = s;
var scripts = div.getElementsByTagName('script');
var i = scripts.length;
while (i--) {
scripts[i].parentNode.removeChild(scripts[i]);
}
return div.innerHTML;
}
var userAgent = navigator.userAgent;
console.log(userAgent);
if (!userAgent.includes("Chrome")) {
stripScripts(); // Here how can I call the present index.html?
}
else {
var para = document.createElement("P");
var t = document.createTextNode("You cannot view this in Chrome");
para.appendChild(t);
document.body.appendChild(para);
};
</script>
<script type="text/javascript" src="scripts2.js"></script> <!-- load only when the condition is met else remove it --!>
</body>
</html>
When I run the index.html in chrome, script2.js is loading all the time.

Reload only one (switch between) file after page load

I have to switch between several files (User theme choice) after page load (through select).
Unfortunately i can't figure out how to do it.
What i want to do is something like this:
betw: I use Polymer.js
Script:
document.addEventListener('select-theme', function(e){
// The event is fired from a nested component.
console.log('select-theme: ', e.detail.themeValue)
var theme = e.detail.themeValue;
var importTag = document.getElementById('themeImport');
var style = document.getElementById('style');
var stylePath;
var importPath;
if(theme == "Green"){
importPath = "../app-theme-green.html";
stylePath ="app-theme-green";
}else{
importPath = "../app-theme-default.html";
stylePath ="app-theme-default";
}
importTag.setAttribute('href', importPath);
style.setAttribute('include', stylePath);
//Load new file
});
HTML
<link id="themeImport" rel="import" href="../app-theme-green.html">
<template is="dom-bind" id="app">
<style id="style" is="custom-style" include="app-theme-green"></style>
// ... some content
</template>
Is this even possible?
Help would be greatly appreciated :-)
I followed this answers to get it work so I changed few parts of my code.
Instead of using html dom-modules i use now .ccs files.
document.addEventListener('select-theme', function(e){
console.log('select-theme: ', e.detail.themeValue)
var theme = e.detail.themeValue;
var importPath;
if(theme == "Green"){
importPath = "../app-theme-green.css";
}else{
importPath = "../app-theme-default.css";
}
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = importPath;
link.media = 'all';
head.appendChild(link);
});

Live reloading iframe script on change

I'm setting up some editors with HTML, CSS and JS code. The code of each of them is reloaded in an iframe when it's change. HTML and CSS code reloads perfectly, bus the JS code that is injected inside of a script in the body of the iframe is not working, possible because it's not rerunning once it's updated, but I don't know how to do it...
Any idea?
Here's an example in Plunker http://plnkr.co/edit/tpl:8rFfZljYNl3z1A4LKSL2?p=preview
HTML
<div class="result">
<!-- RESULT -->
<style id="style"></style>
<script id="script"></script>
<script id="jQ" type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<iframe id="view" class="view"></iframe>
</div>
JS
var app = angular.module('plunker', []);app.controller('MainCtrl', function($scope) {
var style = document.getElementById('style');
var script = document.getElementById('script');
var jQ = document.getElementById('jQ');
var view = document.getElementById('view');
var viewDocument = view.contentDocument || view.contentWindow.document;
var body = viewDocument.getElementsByTagName('body')[0];
var head = viewDocument.getElementsByTagName('head')[0];
var widgets = [];
var loadScript = document.createElement('script');
loadScript.innerHTML = "var $ = parent.$; console.log('loaded');";
$scope.html = '<div id="test">Testing</div>';
$scope.js = 'console.log("More test");';
head.appendChild(jQ);
head.appendChild(loadScript);
head.appendChild(style);
body.appendChild(script);
$scope.$watch('html', function(nv){
body.innerHTML = nv;
body.appendChild(script);
});
$scope.$watch('js', function(nv){
script.innerHTML = nv;
});});
Note: Code seems to run fine when is set by hand
SOLVED:
I found a way around. Here's the code in case someone else need it
setTimeout(updatePreview(codeHTML, codeCSS, codeJS), 300);
function updatePreview(codeHTML, codeCSS, codeJS) {
var view = document.getElementById('view');
var viewDocument = view.contentDocument || view.contentWindow.document;
var codeHTML = (codeHTML === undefined) ? '' : codeHTML;
var codeCSS = (codeCSS === undefined) ? '' : codeCSS;
var codeJS = (codeJS === undefined) ? '' : codeJS;
viewDocument.open();
viewDocument.write('<style type="text/css">' + codeCSS + '</style>');
viewDocument.write('<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>');
viewDocument.write(codeHTML);
viewDocument.write('<script type="text/javascript">' + codeJS + '</script>');
viewDocument.close();
}
This is called in $scope.$watch of de editors passing the updated value.
Weave: http://kodeweave.sourceforge.net/editor/#b6b39c95ec91f42950957a1ac8dc707f
I see you were able to solve your problem however I have a minor suggestion.
If a user uses setTimeout or setInterval like so...
setInterval((function() {
return $('body').css('background', newGradient())
}), 1000)
The problem you have in your code is it will add to the original literation and your setInterval function in this case will be added to the previous one.
Thus a good idea is to create the iframe dynamically and add the code within that. This way you have more control over what's being added to the iFrame and how to handle it.
document.querySelector(".preview").innerHTML = ""
var frame = document.createElement("iframe")
frame.setAttribute("id", "preview")
frame.setAttribute("sandbox", "allow-forms allow-modals allow-pointer-lock allow-popups allow-same-origin allow-scripts")
document.querySelector(".preview").appendChild(frame)

How do I refer to the parameter passed to javascript in html?

When I call the script via
<script type="text/javascript"
src="include/javascript/test_something.js?v=1128557"></script>
how do I refer to the variable V passed in the html?
Thanks in Advance!
The most simple way would be to use a server side technology. This is in php.
<?php
$v=1128557;
?>
<script type="text/javascript">
//This will make this value available to javascript too
var val=<?php=$v?>;
</script>
<script type="text/javascript"
src="include/javascript/test_something.js?v=<?php=$v?>"></script>
...
...
...
<div id='baba<?php=$v?>'>
...
...
</div>
This will be translated to the following html
<script type="text/javascript">
//This will make this value available to javascript too
var val=1128557;
</script>
<script type="text/javascript"
src="include/javascript/test_something.js?v=1128557"></script>
...
...
...
<div id='baba1128557'>
...
...
</div>
Get it from the src attribute of the last script element in your page:
var scripts = document.getElementsByTagName("script");
var src = scripts[scripts.length - 1].src;
var v = null;
if (/\?v=(.+)$/.test(src)){
v = RegExp.$1;
}
If it's the first script tag on the page, you can do something like:
var thescripttag = document.getElementsByTagName('script');
var v = thescripttag[0].src.replace(/^[^\?]+\??/,''); //gets everything after the '?'
If it's not the first script tag, you can change [0] to be whichever one it is, or try assigning an id to the script tag (untested).
You can find the appropriate script tag by looking for the desired filename and get the parameters off that .src URL.
function findScriptParams(fname) {
fname = "/" + fname + "?";
var scripts = document.getElementsByTagName("script");
for (var i = 0; i < scripts.length; i++) {
var pos = scripts[i].src.indexOf(fname);
if (pos != -1) {
return(scripts[i].src.substr(pos + fname.length));
}
}
}
And then you would invoke it like this:
var params = findScriptParams("test_something.js");
if (params) {
// process the params here
}
Change it to
<script type="text/javascript"
src="include/javascript/test_something.php?v=1128557" />
Then create the script test_something.php to be
<?php
echo "var queryString='" . $_SERVER[`QUERY_STRING] . "'\n;";
?>
... rest of javascript here
You can even perform error checking/parsing of the query string using PHP or just get Javascript to do this.
You should do the following:
var scripts = document.getElementsByTagName('script');
var data = {};
for (var i = 0; i < scripts.length; i ++) {
if (!scripts[i].src) {
continue;
}
var value = scripts[i]..substring(scripts[i].indexOf('?') + 1);
var params = value.split('&');
for (var i = 0; i < params.length; i ++) {
params[i] = params[i].split('=');
data[params[i][0]] = params[i][1];
}
}
EDIT: Just incorporated some of the tips from others, and added them to my own answer.
JavaScript only has access to URL data for the page it's being executed on via window.location. It does not have access to any HTTP request variables passed to the javascript file itself unless the web server explicitly serializes it to JavaScript in the output.
One hack/workaround would be to find the script tag, get the src attribute, parse the URL and extract the GET parameters you need.
function getParamsFor(script) {
var params, anchor, paramArray, keyVal, tag, scripts;
scripts = document.getElementsByTagName("script");
// Make sure [].filter exists beforehand
tag = Array.prototype.filter.call(scripts, function (e) {
return e.src.indexOf(script) > -1;
})[0];
if (tag) {
anchor = document.createElement("a");
anchor.href = tag.src;
paramArray = anchor.search.substring(1).split('&');
params = {};
for(var i = 0; i < paramArray.length; i++) {
keyVal = paramArray[i].split('=');
params[unescape(keyVal[0])] = (typeof keyVal[1] != "undefined") ? unescape(keyVal[1]) : keyVal[1];
}
return params;
}
}
var o = getParamsFor("test_something.js");
o.v; // 112..

Simple Javascript not working in IE, works in Firefox

The following is a simple piece of code to have javascript open up a soundcloud audio player in a pop-up window. It works perfectly in firefox and chrome, but doesn't work in IE7; it just shows a blank black screen. Does anyone know why?
I get the yellow drop down that says "to help protect.. IE has restricted this webpage from running scripts or ActiveX controls...." Even when I click on it and say allow, the soundcloud player still doesn't appear.
<HTML>
<HEAD>
<script type='text/javascript'>
function fetchArguments() {
var arg = window.location.href.split("?")[1].split("&"); // arguments
var len = arg.length; // length of arguments
var obj = {}; // object that maps argument id to argument value
var i; // iterator
var arr; // array
for (var i = 0; i < len; i++) {
arr = arg[i].split("="); // split the argument
obj[arr[0]] = arr[1]; // e.g. obj["song"] = "3"
}
return obj;
}
function loadTitle() {
var args = fetchArguments();
document.title = "Audio: Accidential Seabirds - " + args["name"];
}
function loadMusic() {
var args = fetchArguments();
var height = "100";
object = document.createElement("object");
object.height = height;
object.width = "100%";
nameParam = document.createElement("param");
nameParam.name="movie";
nameParam.value ="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F" + args["song"];
scriptParam = document.createElement("param");
scriptParam.name="allowscriptaccess";
scriptParam.value="always";
embedTag = document.createElement("embed");
embedTag.allowscriptaccess="always";
embedTag.height= height;
embedTag.src="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F" + args["song"];
embedTag.type="application/x-shockwave-flash";
embedTag.width="100%";
object.appendChild(nameParam);
object.appendChild(scriptParam);
object.appendChild(embedTag);
document.getElementsByTagName("body")[0].appendChild(object); // we append the iframe to the document's body
window.innerHeight=100;
window.innerWidth=600;
self.focus();
}
</script>
<script type='text/javascript'>
loadTitle();
</script>
</HEAD>
<BODY bgcolor="#000000" topmargin="0" marginheight="0" leftmargin="0" marginwidth="0">
<center>
<script type='text/javascript'>
loadMusic();
</script>
</center>
</BODY>
</HTML>
The code to call this window might be
function PopupMusic(song, name) {
var ptr = window.open("musicplayer.htm?song="+song+"&name='"+name+"'", song, "resizable='false', HEIGHT=90,WIDTH=600");
if(ptr) ptr.focus();
return false;
}
Listen
I figured it out. You need to use the setAttributeFunction:
function loadVideo() {
var args = fetchArguments();
var videoFrame = document.createElement("iframe");
videoFrame.setAttribute('id', 'videoFrame');
videoFrame.setAttribute('title', 'YouTube video player');
videoFrame.setAttribute('class', 'youtube-player');
videoFrame.setAttribute('type', 'text/html');
videoFrame.setAttribute('width', args["width"]);
videoFrame.setAttribute('height', args["height"]);
videoFrame.setAttribute('src', 'http://www.youtube.com/embed/' + args["vid"]);
videoFrame.setAttribute('frameborder', '0');
videoFrame.allowFullScreen;
document.getElementsByTagName("body")[0].appendChild(videoFrame); // we append the iframe to the document's body
self.focus();
}
Following code works fine in IE/FF/Chrome:
<script type='text/javascript'>
var musicSrc = 'http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fsoundcloud.com%2Frjchevalier%2Fjust-one-day-ft-deni-hlavinka&color=3b5998&auto_play=true&show_artwork=false';
document.write('<object type="application/x-shockwave-flash" width="100%" height="100%" data="'+musicSrc+'"><param name="movie" value="'+musicSrc+'" /></object>');
</script>

Categories

Resources