Hi All i'm developping a game when i run it on chrome it works but when i try it on the emulator i'm getting an error in my javascript code that i can't understand the source or the cause
here's the error:
05-13 11:53:11.726: E/Web Console(790): ReferenceError: Can't find variable: $ at file:///android_asset/www/js/html5games.matchgame6.js:5
the error is in line 5: here's my javascript file content:
var matchingGame = {};
***var uiPlay1 = $("#gamePlay1");*** //////line 5
var uiPlay2 = $("#gamePlay2");
var uiIntro = $("#popup");
var uiExit = $("#gameExit");
var uiNextLevel = $("#gameNextLevel");
var uigameQuit =$("#gameQuit");
var uiPlay3 = $("#gamePlay3");
matchingGame.savingObject = {};
matchingGame.savingObject.deck = [];
matchingGame.savingObject.removedCards = [];
// store the counting elapsed time.
matchingGame.savingObject.currentElapsedTime = 0;
//store the last-elapsed-time
//matchingGame.savingObject.LastElapsedTime = 0;//now
// store the player name
matchingGame.savingObject.palyerName=$("#player-name").html();
matchingGame.savingObject.currentLevel="game6.html";
// all possible values for each card in deck
matchingGame.deck = [
'cardAK', 'cardAK',
'cardAQ', 'cardAQ',
'cardAJ', 'cardAJ',
];
$( function(){init();} );
//initialise game
function init() {
$("#game").addClass("hide");
$("#cards").addClass("hide");
uiPlay1.click(function(e) {
e.preventDefault();
$("#popup").addClass("hide");
startNewGame();
});
uiPlay2.click(function(e) {
e.preventDefault();
$("#popup").addClass("hide");
var savedObject = savedSavingObject();
// location.href =savedObject.currentLevel ;
if (savedObject.currentLevel=="game6.html")
rejouer();
else
location.href =savedObject.currentLevel ;
//ResumeLastGame();
//alert ("level :"+savedObject.currentLevel );
});
uiExit.click(function(e) {e.preventDefault();
//alert("u clicked me ");
}
);
uiPlay3.click(function(e) {
e.preventDefault();
$("#popupHelp").fadeIn(500, function() {
$(this).delay(10000).fadeOut(500)}); });
}
Any idea please thank u in advance
You probably didn't include jQuery.
Presumably you haven't defined the $ function anywhere.
Perhaps you a working from documentation that assumes you have loaded Prototype.js, Mootools, jQuery or one of the many other libraries that set up a variable of that (very poor) name.
make sure you have loaded jquery, mootools, other javascript libraries etc before you use the $.
Have you included your library at the end of your document and you have your script written before the library is downloaded.
make sure you have a script tag that refers to your library and then have your script content.
Also one more thing to note is that your document may not have been loaded when your scriot is executed and some of the controls might not exist on the page, thus make sure you wrap them in an API that will run the function once the document is loaded completely. In jquery you use $(document).ready(function(){});
I am developing a JS app in Ejecta. jQuery was included but the DOM ready doesn't work with Ejecta. Instead on site/app initialization I do something like this:
function func() {
init();
animate();
}
setTimeout(func, 1000);
This gives jQuery time to be loaded and parsed.
Related
I'm writing a website using VueJS which allows (selected) users to add scripts that are automatically executed upon page load. Here's a sample text that a user might upload:
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.0.5/howler.js"></script>
<script>
var sound = new howler.Howl({
src: ['./sample.mp3']
)}.play();
</script>
This text is stored into a string after retrieving from API backend. The problem now is: I couldn't get it to execute however I try. Is there an option in VueJS that can automatically execute javascripts in strings?
As a reference, here's my code:
var temp_arr = utils.preprocess(vm.chapterInfo.Content)
vm.display = temp_arr[0]
vm.control_script = console.log(temp_arr[1])
// None of below worked
eval(vm.control_script)
document.getElementsByTagName("head")[0].appendChild(control_script)
The problem isn't a Vue one, but a JavaScript one.
I assume that you already understand the security implications of allowing users to run JavaScript; it's rarely a good idea. Sites like JSFiddle do it successfully, however it will take a lot of work and understanding to make it safe, so if you're not 100% sure with what you are doing, then as #WaldemarIce said, you shouldn't do it!
Right, with the warning out the way, you need to do a few things to get this to work:
1) Load the external scripts:
loadScripts() {
return new Promise(resolve => {
let scriptEl = document.createElement("script");
scriptEl.src = "https://cdnjs.cloudflare.com/ajax/libs/howler/2.0.5/howler.js";
scriptEl.type = "text/javascript";
// Attach script to head
document.getElementsByTagName("head")[0].appendChild(scriptEl);
// Wait for tag to load before promise is resolved
scriptEl.addEventListener('load',() => {
resolve();
});
});
}
Here I'm simply attaching the external script to the head of the document and attaching a load event, which resolves the Promise when loaded.
2) Now we have loaded the external script we can execute the remainder of the script. You will need to strip out the script tags, so you can do something like this:
executeScript() {
// remove script tags from string (this has been declared globally)
let script = string.replace(/<\/?script>/g,"")
eval(script)
}
Form the Vue perspective, you can then execute this inside the created hook:
created() {
this.loadScripts().then(() => {
this.executeScript();
});
},
I'll leave it to you to extract the external scripts you want to load from your user input, but here's a JSFiddle: https://jsfiddle.net/49dq563d/
I recently came across this problem and had to extend on the answer from #craig_h. The example below allows full embed code to be sent through as string (HTML elements as well as scripts and inline JS). This is using DOMParser.
<div ref="htmlDump"></div>
<script>
import Vue from "vue";
export default {
...
methods: {
cloneAttributes(element, sourceNode) {
let attr;
let attributes = Array.prototype.slice.call(sourceNode.attributes);
while(attr = attributes.pop()) {
element.setAttribute(attr.nodeName, attr.nodeValue);
}
}
},
mounted(){
if(this.embedString && this.embedString.length > 0)
{
//Parse the code given from the API into a new DOM so we can easily manipulate it
var parser = new DOMParser();
var htmlDoc = parser.parseFromString(this.embedString, 'text/html');
//Get the contents of the new DOM body and loop through.
//We want to add all HTML elements to the page and run / load all JS
var kids = [...htmlDoc.body.children];
let len = kids.length;
for (var i = 0; i < len; i++) {
var item = kids[i];
if(item.tagName == "SCRIPT")
{
//If we have a 'src' attribute then we're loading in a script
if(item.hasAttribute('src'))
{
//Create a new element within the current doc to trigger the script load
let scriptEl = document.createElement("script");
//Copy all attributes from the source element to the new one
this.cloneAttributes(scriptEl, item);
//Attach script to the DOM to trigger it to load
this.$refs.htmlDump.appendChild(scriptEl);
} else {
//if we don't have a 'src' attribute then we have some code to run
eval(item.innerText);
}
} else{
this.$refs.htmlDump.appendChild(item);
}
}
}
}
...
}
</script>
I have written two applications:
JS script attached on different websites
Management panel for me
Each script will create different DOM structure using JS, I can create javascript code doing this for each website from management panel.
Thus I have to keep this part of code in the database, and use eval in each script to run it.
The sample eval looks like this:
var container = document.createElement('div');
container.innerHTML = "Fjkdfjdf";
html = {
container: container
};
doAction();
So first I create DOM elements, then I attach some of them to the attribute in my script, then I call some function in my script - attaching these elements to body. The script looks like this:
(function() {
var module = (function() {
var html = ();
var fire = function() {
Api.getStyles(function(response) {
eval(response.script);
};
};
var doAction = function() {
document.getElementsByTagName('body')[0].appendChild(html.container);
};
return {
fire: fire,
doAction: doAction
};
});
module.fire();
)();
Is this safe enoough? Can someone override doAction() method and do whatever he wants?
what I need
I need to hide js code in view source
js code
function unloadJS(scriptName) {
var head = document.getElementsByTagName('head').item(0);
var js = document.getElementById(scriptName);
js.parentNode.removeChild(js);
}
function unloadAllJS() {
var jsArray = new Array();
jsArray = document.getElementsByTagName('script');
for (i = 0; i < jsArray.length; i++){
if (jsArray[i].id){
unloadJS(jsArray[i].id)
}else{
jsArray[i].parentNode.removeChild(jsArray[i]);
}
}
}
var page_count = {{count()}};
if (page_count == 4)
{
dataLayer.push({'event':'mobilePromo-android'});
}
$(document).ready(function()
{
var page_count = {{count()}};
var height= $(window).height();
if (page_count == 4 )
{
$.ajax({
type: "GET",
url: "http://times.com/mobilepopuptracker?from=android",
});
$('body').html('<div class="row flush aligncenter popbx" style="height:'+height+'px"><div class="12u">');
}
else
{
}
});
function redirect()
{
var a=$(location).attr('href');
window.location.href=a;
}
</script>
Problem
I Need to hide js code in view source.
Debug
i have reffred the link find solution on http://www.sitepoint.com/hide-jquery-source-code/.
though code is still viewed.
any suggestion are most welcome.
though we know we cannot stop viewing of js in view source but still there must be some trick.
Use the online Google Closure Compiler service, it will make your code almost unreadable by doing things like renaming variables and function names. For example:
Raw JS
function toggleDisplay(el){
if (!el) return;
el.style.display = (el.style.display==='none') ? 'block' : 'none';
}
Closure Compiled
function toggleDisplay(a){a&&(a.style.display="none"===a.style.display?"block":"none")};
JavaScript Beautified
function toggleDisplay(a){
a&&(a.style.display="none"===a.style.display?"block":"none")
};
In doing so it also reduces the size of your script, helping to boost the loading time of your webpage.
You can still read the script, but its harder to understand and can get really complex when using things like JavaScript Closures.
You can't truly hide your js code. You can obfuscate it (i.e. make it difficult to read), but unlike PHP or Perl - which is processed on the server side - JS runs in the client's browser itself. Therefore, the client always has a copy of it, and can view that source at any time.
This is my first post to the forum.
I am setting up an English/Thai language course website which will contain many audio files of English and Thai speech. I did a single webpage proof of concept using a mouseover/button javascript function
http://www.javascriptkit.com/script/script2/soundlink.shtml
With some mods and some inline js, this worked OK.
$(document).ready(function() {
var html5_audiotypes = {
"mp3": "audio/mpeg",
"ogg": "audio/ogg",
};
function createsoundbite(sound) {
"use strict";
var html5audio = document.createElement('audio');
if (html5audio.canPlayType){
for(var i=0; i<arguments.length; i++) {
var sourceEl = document.createElement('source');
sourceEl.setAttribute('src', arguments[i]);
if (arguments[i].match(/\.(\w+)$/i))
sourceEl.setAttribute('type', html5_audiotypes[RegExp.$1]);
html5audio.appendChild(sourceEl);
}
html5audio.load();
html5audio.playclip = function() {
html5audio.pause();
html5audio.currentTime=0;
html5audio.play();
}
return html5audio;
}
else{
return {playclip:function(){throw new Error("Your browser doesn't support HTML5 audio unfortunately")}};
}
}
var cn402=createsoundbite("audio/cn402.ogg", "audio/cn402.mp3");
var ry402=createsoundbite("audio/ry402.ogg", "audio/ry402.mp3");
var cn403=createsoundbite("audio/cn403.ogg", "audio/cn403.mp3");
var ry403=createsoundbite("audio/ry403.ogg", "audio/ry403.mp3");
var cn404=createsoundbite("audio/cn404.ogg", "audio/cn404.mp3");
var ry404=createsoundbite("audio/ry404.ogg", "audio/ry404.mp3");
});
The javascript code is called by a line of html code like this:
Please don't swim by yourself</span>
I want to incorporate this function and its associated variables into jquery. so that all js code is removed from the html. The first step, just getting the jquery code to work has proved a bit problematic for me. I've tried just including the js audio code in a document ready function. as shown above but this doesn't work. Any help would be much appreciated.
I'm not sure if I get you right, but you can remove the javascript code from the given link very easily:
$('.rollover').click(function(){
ry402.playclip();
});
Let's have a look at: http://api.jquery.com/click/
I am aware that when coding an extension, there is no way we can delay a function call except for using a setTimeout call but here's what I am trying to achieve in a plugin that I am developing for Firefox (this is not for Javascript embedded into a web page by the way):
for (var i = 0; i < t.length ; i++) {
//Load a URL from an array
//On document complete, get some data
}
The idea is simple. I have an array of URLs that I want to parse and extract some data out of. Each of these URLs take some time to load. So, if I try to get some data from the current page without waiting for the page to load, I will get an error. Now, the only way to do this as I know is as follows:
firstfunction: function() {
//Load the first url
setTimeout("secondfunction", 5000);
}
secondfunction: function() {
//Load the second url
setTimeout("thirdfunction", 5000);
}
And so on... I know this is obviously wrong.. I was just wondering how people achieve this in Javascript...
EDIT: Sorry about not being more detailed...
I'm not convinced that this type of foolery is necessary but I'm not an extension dev so who knows. If this is the approach you want, then just have the setTimeout call refer to the same function:
var index;
firstfunction: function() {
// do something with `index` and increment it when you're done
// check again in a few seconds (`index` is persisted between calls to this)
setTimeout("firstfunction", 5000);
}
I am not sure how to do this from a plugin, but what I've done with iframes in the past is attach a callback to the target document's onLoad event.
Maybe something like:
var index = 0;
var urls = [ ..... ];
function ProcessDocument() { ....; LoadNextDocument(); }
function LoadNextDocument() { index++; /* Load urls[index] */; }
document.body.onLoad = ProcessDocument;
Somewhere in there you'd need to test for index > urls.length too for your end condition.
I had same problem but I used recursion instead of looping.
Below is the running code which changes the innerHTML of an element by looping through the list. Hope its helpful.
<Script type="text/javascript">
var l;
var a;
function call2()
{
l = document.getElementById('listhere').innerHTML;
a = l.split(",");
call1(0);
}
function call1(counter)
{
if(a.length > counter)
{
document.getElementById('here').innerHTML = a[counter];
counter++;
setTimeout("call1("+counter+")",2000);
}
}
</Script>
<body onload="call2()">
<span id="listhere">3,5,2,8</span><Br />
<span id="here">here</span>