prevent Adobe Edge preload.js file from loading jquery - javascript

First I have to say that I am not a professional programmer but designer learning by doing. So I am afraid I need simple explanations if possible.
I am using Edge animate as parts of a website with the help of a particular script (by Andrew Trice, see here: http://www.tricedesigns.com/2012/07/12/using-adobe-edge-animations-as-components/ ). I also succeeded in storing only 1 Edge preload.js file in my libs folder. In it I introduced a variable at the end in order to be able to load Edge animations one after another. Code:
function setupAnimationView( template ) {
var $workPage = $("#workPage")
$workPage.empty();
window.AdobeEdge = undefined;
AdobeEdge = undefined;
var viewModel = { workChart: workChart };
var html = Mustache.to_html(template, viewModel)
$workPage.append( html );
//detect if edge is loaded yet
var edgeDetectionFunction = function() {
if ( AdobeEdge && AdobeEdge.compositions != undefined ) {
//put a delay here
var hasComposition = false;
if ( AdobeEdge.compositions ) {
//loop to see if the composition is actually loaded
for ( var key in AdobeEdge.compositionDefns ) {
hasComposition = true;
break;
}
}
if ( hasComposition ) {
setTimeout( function() {
$(window).trigger( "animationReady" ); }, 100 );
return;
}
}
else if ( AdobeEdge ) {
window.onDocLoaded();
}
setTimeout( edgeDetectionFunction, 100 );
}
edgeDetectionFunction();
}
Modified Adobe Edge preload.js:
...
requiresSVG=false;
doDelayLoad=false;
htFallbacks={
};
aLoader = [
{ load: "libs/jquery-1.10.2.min.js"},
{ load: "libs/jquery.easing.1.3.js"},
{ load: "libs/jquery.rotate.js"},
{ load: "libs/edge.1.0.0.min.js"},
{test: !hasJSON, yep:"libs/json2_min.js"},
{ load: "templates/Chart_" + workChart + "/Page_work_edge.js"},
{ load: "templates/Chart_" + workChart + "/Page_work_edgeActions.js"}];
loadResources(aLoader, doDelayLoad);
preContent={dom:[
]}
;//simpleContent
dlContent={dom: [
]}
;//simpleContent
//updated paths for loader
//added this so it can be invoked later
window.onDocLoaded = onDocLoaded;
})( "animation_content");
So far thanks to Andrew everything works very fine except that I saw in my developer tool (Safari) that my code leads to loading the basic js files like jquery-1.10.2.min.js over and over again each time a new animation starts to run and this files are summing up to an endless number… which I guess isn’t a good thing.
I even understand why (at least I believed) and so I deleted the respective lines in the aLoader object at the end of preload. (of course they are loaded within the script tag in my index page)
aLoader = [
{ load: "libs/jquery-1.10.2.min.js"}, // deleted this one
{ load: "libs/jquery.easing.1.3.js"}, // deleted this one
{ load: "libs/jquery.rotate.js"}, // deleted this one
{ load: "libs/edge.1.0.0.min.js"}, // deleted this one
{test: !hasJSON, yep:"libs/json2_min.js"},
{ load: "templates/Chart_" + workChart + "/Page_work_edge.js"},
{ load: "templates/Chart_" + workChart + "/Page_work_edgeActions.js"}];
because I can’t see why it would be necessary to load them more than once. Yet, after doing so only the first animation runs, the second does not any longer. But why? I checked in the browser and see that jquery-1.10.2.min.js is in the page so why can’t (or seems so) the Edge files use it any longer? The same for the other ones (rotate etc.).
I also tried to suppress these two lines from the function above:
window.AdobeEdge = undefined;
AdobeEdge = undefined;
without any result though.
Where is the trick to avoid reloading those basic needed .js files? Any ideas? Thank you so much for advice
Garavani
#Jamie
EDIT:
So ,hello Jamie! I was so curious about your solution that I dropped everything else and tried it. Sadly it does not work in the situation I tried to explain as exactly as possible in the lines above this edit.
To avoid any misunderstandings here my changed code following your instructions (very good explanation by the way!):
edgePreload.js (in my version it has no filename addition and lies in my „lib“ folder that is accessed by each new animation after the method by Andrew - see above!) :
window.AdobeEdge = window.AdobeEdge || {};
window.AdobeEdge.$_ = $;
// Include yepnope
if(!AdobeEdge.yepnope) {…
Then further on:
$(function() { // your insert opening function
(function(compId){
var htFallbacks; …
…
window.onDocLoaded = onDocLoaded;
})( "animation_content");
}); // your insert closure
My index.html contains the following scripts (among others):
<script src="libs/jquery-1.11.0.min.js"></script>
<script src="libs/jquery.easing.1.3.js"></script>
<script src="libs/jquery.rotate.js"></script>
<script src="libs/edge.1.0.0.min.js"></script>
<script src="libs/mustache.js"></script>
<script src="libs/mustacheHelper.js"></script>
which I like to host on my server. (avoiding all kinds of trouble coming up with versions updates not under my control)
Now I dared and hoped to be able to cancel that stuff from my aLoader arrow as follows:
aLoader = [
// { load: "libs/jquery-1.11.0.min.js"},
// { load: "libs/jquery.easing.1.3.js"},
// { load: "libs/jquery.rotate.js"},
// { load: "libs/edge.1.0.0.min.js"},
{test: !hasJSON, yep:"libs/json2_min.js"},
{ load: "templates/Chart_" + workChart + "/Page_work_edge.js"},
{ load: "templates/Chart_" + workChart + "/Page_work_edgeActions.js"}];
but id t doesn’t work (throwing all kinds of errors obviously based on lacking edge codes).
When I replace all in the aLoader again at least it works without showing errors concerning the new inserted lines. But I have no result. Yet, would be soooooooooo cool!!!
Did I miss something? Did you really check thoroughly what I did in my initial lines above?
I am curious to hear your ideas!
Thank you so far for your interest and willing to share your knowledge of this complicated edge material (not much discussed - for good reasons I guess – here in stack overflow).

I've been having the exact issue and you've probably solved it by now, but hopefully it'll help someone else.
1) Make sure you get your files by choosing 'HTML' in your publish settings, and publishing to a clean folder.
2) Use a prettifier tool (e.g. http://jsbeautifier.org/) to make the [filename]_edgePreload.js file readable.
3) Add this line window.AdobeEdge.$_ = $; just under the top line window.AdobeEdge = window.AdobeEdge || {};
4) Find this line (function(compId) { (which is the start of the load method) and wrap that whole method (everything between here and the bottom of the page) with $(function() { and });
5) In the aLoader array, remove the first two entries that specify how to load edge and jquery.
6) Add the edge library (currently https://animate.adobe.com/runtime/4.0.1/edge.4.0.1.min.js) to the head of your site, along with jQuery.
Don't feel too bad that this was confusing, the Adobe Edge output code has been written by a cabbage with legs. Everyone struggles with it :)

Related

JS no longer working after WordPress update - Uncaught TypeError: $ is not a function

I updated a website I am working on to the latest WordPress last week. None of the custom JS is working anymore and I can't work out why.
Even if I remove it in sections to try and isolate the issue, I always get 'Uncaught TypeError: $ is not a function'.
I cannot work out what has caused this to happen.
As far as I can see, all the scripts load as expected.
Unfortunately all the JS in my custom file has been acquired either from Stack Overflow or other online resources - I did not write it myself (only amended) and thus am struggling to diagnose the issue.
Any help would be appreciated
// apply effect to pages
var $headereffect = $('.hero-effect');
$headereffect.waypoint(function (direction) {
if (direction == 'down') {
$headereffect.addClass('hero-effect-animation');
} else {
$headereffect.removeClass('hero-effect-animation');
}
}, { offset:'1px' });
// apply effect to default page headers
var $headereffect = $('#page-header');
$headereffect.waypoint(function (direction) {
if (direction == 'down') {
$headereffect.addClass('hero-effect');
} else {
$headereffect.removeClass('hero-effect');
}
}, { offset:'1px' });
My wild guess is to use jQuery instead of the $ as sometimes the latter is used by other scripting libraries and this causes issues and conflicts.
So
var $headereffect = $('.hero-effect');
becomes
var $headereffect = jQuery('.hero-effect');
This will fix the current issue but others also may be raised on a later stage. Inspect your code and make sure you use a consistent jQuery reference.
Options to handle the $ issue the jQuery way can be found here. From a practical point of view, you can put jQuery into "no conflict" mode by using shortcut for jQuery. In this case "$j" instead of the default "$":
var $j = jQuery.noConflict();
$j(function(){
$j("#sidebar li a").hover(function(){
$j(this).stop().animate({
paddingLeft: "20px&"
}, 400);
}, function() {
$j(this).stop().animate({
paddingLeft: 0
}, 400);
});
});
A best practice as Wordpress suggest is to wrap your code in immediately invoked function expression, pass jQuery to it and use the $ internally like this:
( function( $ ) {
// Your code goes here
} )( jQuery );

PhantomCSS/CasperJS - Greying out advertisement images

Hey guys just testing our pages out using the grunt-phantomcss plugin (it's essentially a wrapper for PhantomJS & CasperJS).
We have some stuff on our sites that comes in dynamically (random profile images for users and random advertisements) sooo technically the page looks different each time we load it, meaning the build fails. We would like to be able to jump in and using good ol' DOM API techniques and 'grey out'/make opaque these images so that Casper/Phantom doesn't see them and passes the build.
We've already looked at pageSettings.loadImages = false and although that technically works, it also takes out every image meaning that even our non-ad, non-profile images get filtered out.
Here's a very basic sample test script (doesn't work):
casper.start( 'http://our.url.here.com' )
.then(function(){
this.evaluate(function(){
var profs = document.querySelectorAll('.profile');
profs.forEach(function( val, i ){
val.style.opacity = 0;
});
return;
});
phantomcss.screenshot( '.profiles-box', 'profiles' );
});
Would love to know how other people have solved this because I am sure this isn't a strange use-case (as so many people have dynamic ads on their sites).
Your script might actually work. The problem is that profs is a NodeList. It doesn't have a forEach function. Use this:
var profs = document.querySelectorAll('.profile');
Array.prototype.forEach.call(profs, function( val, i ){
val.style.opacity = 0;
});
It is always a good idea to register to page.error and remote.message to catch those errors.
Another idea would be to employ the resource.requested event handler to abort all the resources that you don't want loaded. It uses the underlying onResourceRequested PhantomJS function.
casper.on("resource.requested", function(requestData, networkRequest){
if (requestData.url.indexOf("mydomain") === -1) {
// abort all resources that are not on my domain
networkRequest.abort();
}
});
If your page handles unloaded resources well, then this should be a viable option.

addEventListener and setInterval fail silently in a Greasemonkey script

I am trying to get code to execute every x amount of time and begin doing so after the page has loaded for the first time, while my debug throws no errors, the script doesn't actually do anything.
So, I am at a bit of a loss and I am thinking it has something to do with the syntax or the way the code is nested. Can you be so kind as to look at my code below and tell me what in the heck I am doing wrong and if there is a better way to fix it?
window.addEventListener('load', function() {
setInterval(function setTitle(){
var sInfo = document.getElementById("play_info");
var iTags = sInfo.innerHTML.split("\">");
var pTags = iTags[3].split("<");
document.title = pTags[0];
return setTitle;
},5000);
});
This is a code inside a Greasemonkey script that will run inside Firefox. Thank you.
Update (Now that target page was given):
The question code did not match the structure of the actual page. It typically would throw TypeError: iTags[3] is undefined errors.
Using DOM methods, to get the desired info, does the job. A working script is:
// ==UserScript==
// #name _KROQ, song info to page title
// #include http://betaplayer.radio.com/player/*
// #grant GM_addStyle
// ==/UserScript==
/*- The #grant directive is needed to work around a design change
introduced in GM 1.0. It restores the sandbox.
*/
if (window.top != window.self) //-- Don't run on frames or iframes.
return;
window.addEventListener ('load', function () {
setInterval (setTitle, 5000);
}, false);
function setTitle () {
var songInfoNode = document.querySelector (
"#play_info #oflw_shield div.sleeve.hori"
);
if (songInfoNode) {
var songInfoText = songInfoNode.textContent.trim ();
//console.log ("songInfoText", songInfoText);
document.title = songInfoText;
}
}
That code is "brittle", but it will work fine on a site that has the structure you seem to expect. However, the only "output" is that the page title might change. That doesn't happen?
One or more of the following is the script's immediate problem:
The page does not have the structure you are expecting, so the code throws exceptions. You say, "My debug throws no errors". Verify that you checked Firefox's error console, ControlShiftJ, with the display set to "Errors" or to "All".
Something else in the script, that you are not showing us, is the problem. Include or link to the complete Greasemonkey script.
The script is operating on <iframe>d content, so changing document.title will have no visible effect. Link to the target page.
For reference, here is more robust version of that code, that also has a console message, so that you can verify operation:
window.addEventListener ('load', function () {
setInterval (setTitle, 5000);
}, false);
function setTitle () {
console.log ("Running setTitle().");
var sInfo = document.getElementById ("play_info");
if (sInfo) {
var iTags = sInfo.innerHTML.split ("\">");
if (iTags && iTags.length > 3) {
var pTags = iTags[3].split ("<");
if (pTags && pTags.length) {
document.title = pTags[0];
}
}
}
}
Note that it's not good practice to parse HTML that way, but without seeing the actual target page (or at least the structure of the play_info node), we can't provide a specific alternative.
As Brandon Boone stated, if you are looking for a pure JS solution to find cross-browser solutions for addEventListener, I suggest you use a solution like this.
var e = window.addEventListener ? window.addEventListener : window.attachEvent;
e('load',function(){ ... };

Loading external Javascript Sequentially

I am working on a javascript that sequentially loads a list of other external javascript.
The code I have so far:
function loadJavascript(url){
var js = document.createElement("script");
js.setAttribute("type", "text/javascript");
js.setAttribute("src", url);
if(typeof js!="undefined"){
document.getElementsByTagName("head")[0].appendChild(js)
}
}
loadJavascript("Jquery.js");
loadJavascript("second.js");
loadJavascript("third.js");
The problem I ran into is that sometimes the other js files loads before the Jquery file completes its loading. This gives me some errors.
Is it possible to make it so that the next JS file is only initiated when the previous file is finished loading.
Thanks in advance
Sure there is, but there's entire libraries written around doing this. Stop reinventing the wheel and use something that already works. Try out yepnope.js or if you're using Modernizr it's already available as Modernizr.load
loadJavascript("Jquery.js");
$(function(){
$.getScript('second.js', function(data, textStatus){
$.getScript('third.js', function(data, textStatus){
console.log("loaded");
});
});
}
Also, consider using the Google or Microsoft CDN for the jQuery, it will save you bandwidth and hopefully your visitors will already have it cached.
Actually, it's not necessary to load jquery within a js function. But if you insist, you can callback to make sure other js loaded after jquery.
Still, I recommend you load jquery just before </body> then use $.getScript to load other .js
You could do a check to see if jQuery is loaded, not the best way to do it, but if you really have to wait until jQuery is loaded before loading the other scripts, this is how I would do it, by checking for $ :
loadJavascript("Jquery.js");
T=0;
CheckIfLoaded();
function CheckIfLoaded() {
if (typeof $ == 'undefined') {
if (T <= 3000) {
alert("jQuery not loaded within 3 sec");
} else {
T=T+200;
setTimeout(CheckIfLoaded, 200);
} else {
loadJavascript("second.js");
loadJavascript("third.js");
}
}
In technical terms: Browsers have a funny way of deciding I which order to execute/eval dynamically loaded JS, so after suffering the same pain and checking a lot of posts, libraries, plugins, etc. I came up with this solution, self contained, small, no jquery needed, IE friendly, etc. The code is extensively commented:
lazyLoader = {
load: function (scripts) {
// The queue for the scripts to be loaded
lazyLoader.queue = scripts;
lazyLoader.pendingScripts = [];
// There will always be a script in the document, at least this very same script...
// ...this script will be used to identify available properties, thus assess correct way to proceed
var firstScript = document.scripts[0];
// We will loop thru the scripts on the queue
for (i = 0; i < lazyLoader.queue.length; ++i) {
// Evaluates if the async property is used by the browser
if ('async' in firstScript ) {
// Since src has to be defined after onreadystate change for IE, we organize all "element" steps together...
var element = document.createElement("script");
element.type = "text/javascript"
//... two more line of code than necessary but we add order and clarity
// Define async as false, thus the scripts order will be respected
element.async = false;
element.src = lazyLoader.queue[i];
document.head.appendChild(element);
}
// Somebody who hates developers invented IE, so we deal with it as follows:
// ... In IE<11 script objects (and other objects) have a property called readyState...
// ... check the script object has said property (readyState) ...
// ... if true, Bingo! We have and IE!
else if (firstScript.readyState) {
// How it works: IE will load the script even if not injected to the DOM...
// ... we create an event listener, we then inject the scripts in sequential order
// Create an script element
var element = document.createElement("script");
element.type = "text/javascript"
// Add the scripts from the queue to the pending list in order
lazyLoader.pendingScripts.push(element)
// Set an event listener for the script element
element.onreadystatechange = function() {
var pending;
// When the next script on the pending list has loaded proceed
if (lazyLoader.pendingScripts[0].readyState == "loaded" || lazyLoader.pendingScripts[0].readyState == "complete" ) {
// Remove the script we just loaded from the pending list
pending = lazyLoader.pendingScripts.shift()
// Clear the listener
element.onreadystatechange = null;
// Inject the script to the DOM, we don't use appendChild as it might break on IE
firstScript.parentNode.insertBefore(pending, firstScript);
}
}
// Once we have set the listener we set the script object's src
element.src = lazyLoader.queue[i];
}
}
}
}
Of course you can also use the minified version:
smallLoader={load:function(d){smallLoader.b=d;smallLoader.a=[];var b=document.scripts[0];for(i=0;i<smallLoader.b.length;++i)if("async"in b){var a=document.createElement("script");a.type="text/javascript";a.async=!1;a.src=smallLoader.b[i];document.head.appendChild(a)}else b.readyState&&(a=document.createElement("script"),a.type="text/javascript",smallLoader.a.push(a),a.onreadystatechange=function(){var c;if("loaded"==smallLoader.a[0].readyState||"complete"==smallLoader.a[0].readyState)c=smallLoader.a.shift(),
a.onreadystatechange=null,b.parentNode.insertBefore(c,b)},a.src=smallLoader.b[i])}};

SYNTAX_ERR: DOM Exception 12 - Hmmm

I have been working on a small slideshow / public display for a client that uses HTML5 Rock's Slideshow code. I have run into a DOM Exception 12 - a syntax error that is supposedly related to CSS selectors - while monkeying around with it... but I can't trace it back to any changes I made in the code. I am thinking it might be something that was uncovered as I added features.
I have traced it down to this object (live version here):
var SlideShow = function(slides) {
this._slides = (slides || []).map(function(el, idx) {
return new Slide(el, idx);
});
var h = window.location.hash;
try {
this.current = h;
} catch (e) { /* squeltch */ }
this.current = (!this.current) ? "landing-slide" : this.current.replace('#', '');
if (!query('#' + this.current)) {
// if this happens is very likely that someone is coming from
// a link with the old permalink format, i.e. #slide24
alert('The format of the permalinks have recently changed. If you are coming ' +
'here from an old external link it\'s very likely you will land to the wrong slide');
this.current = "landing-slide";
}
var _t = this;
doc.addEventListener('keydown',
function(e) { _t.handleKeys(e); }, false);
doc.addEventListener('touchstart',
function(e) { _t.handleTouchStart(e); }, false);
doc.addEventListener('touchend',
function(e) { _t.handleTouchEnd(e); }, false);
window.addEventListener('popstate',
function(e) { if (e.state) { _t.go(e.state, true); } }, false);
};
Instantiation of SlideShow() (line 521 in main.js):
var slideshow = new SlideShow(queryAll('.slide'));
Calling queryAll('.slide') returns an array of all the slides with an class of .slide. However, when passing queryAll('.slide') as a parameter for instantiating SlideShow(), it returns a DOM Exception 12 error.
Has anybody seen this before?
You are using illegal id-attributes(illegal before HTML5) inside the document, e.g. 2-slide . Fix them.
To explain:
to solve the known misbehaviour of element.querySelectorAll() the selector .slide will be internally rewritten(by using the id of the element). This will result in something like that:
#2-slide .moreselectors
...and forces the error, because an ID may not start with a Number.
See the fiddle: http://jsfiddle.net/doktormolle/FGWhk/
If you are coming here after searching for this error in HTML5 rocks slides:
For some reason they remove the class 'to-build' with the following:
toBuild[0].classList.remove('to-build', '');
That breaks all slide decks the use build, even the Google demo right now is broken
Just change line 220 of default.js to
toBuild[0].classList.remove('to-build');
all is well!
In my case it was using self.postMessage(e.data); in the main thread while using web workers.
I know it's not related to the OP's issue, but it's an odd error so I'm leaving this here in hope it helps others.
Same problem to me but in my case a try to get elements from their attribute
document.querySelectorAll('input[name="path"]')
and SYNTAX_ERR: DOM Exception 12 occurred only on Safari. So i've change it to get the element directly from class and now work fine.
You can escape the quotes like in applescript then no issue on safari
do JavaScript "document.querySelector('span[" & attrName & "=\"" & attrValue & "\"]').click();"

Categories