How comes this "if" passes but for real it shouldn't? - javascript

Good day, first I would like to tell that I am not proud to post a whole source code. I couldn't isolate the problem in a smaller chunk.
Here is a snapshot of the file:
getRoomById : function( areaId, roomId ) {
if ( this.hAreas.get( areaId ) !== null && this.hAreas.get( areaId )[ roomId ] !== undefined )
{
//I can get here...
//alert( uneval( this.hAreas.get( areaId ) ) );
// returns: ({'000001':{areaId:"000001", roomId:"000001", Informations:{Name:"Room 1"}}, '000002':{areaId:"000001", roomId:"000002", Informations:{Name:"Room 2"}}, '000003':{areaId:"000001", roomId:"000003", Informations:{Name:"Room 3"}}})
//alert( roomId );
// returns: 000003
return this.hAreas.get( areaId )[ roomId ];
// returns: undefined
}
},
and the whole file is there: http://jsfiddle.net/JSWCu/2/
The problem: I have a method which tests the arguments against a JS.Hash containing an object. That if hopefully returns true but once inside, I can't get (either alert or return) the object inside that JS.Hash (an undefined is returned).
Thank you! your help is greatly appreciated. I would also appreciate tips to avoid such errors.
Edit: here is the whole codes. Sorry It's really big. It's just starting to get complex and I couldn't (for now) isolate the problems to a smaller piece of codes:
<html>
<head>
<style type="text/css">
</style>
<script type="text/javascript">
JSCLASS_PATH = 'http://www.poc.ca/cybrix/src';
function appendConsole( input ) {
document.getElementById( "console" ).innerHTML += input + "<br />";
}
</script>
<script type="text/javascript" src="http://www.poc.ca/cybrix/src/loader-browser.js"></script>
<script type="text/javascript">
JS.require('JS.Hash', 'JS.Observable', function() {
var AreaLists = {
"000001" : { "Name" : "Test Area", "Loaded" : false },
};
var World = new JS.Class({
hAreas : new JS.Hash([]),
getAreas : function( areaId ) {
if ( ! this.hAreas.get( areaId ) && AreaLists[ areaId ] !== undefined )
{
//TODO: Load from external sources
this.hAreas.put( areaId, {
"000001" : new Room( areaId, "000001", { "Name" : "Room 1" } ),
"000002" : new Room( areaId, "000002", { "Name" : "Room 2" } ),
"000003" : new Room( areaId, "000003", { "Name" : "Room 3" } ),
});
AreaLists[ areaId ].Loaded = true;
appendConsole( "Areas #" + areaId + " : " + AreaLists[ areaId ].Name + " Created" );
}
return this.hAreas.get( areaId );
},
getRoomById : function( areaId, roomId ) {
if ( this.hAreas.get( areaId ) !== null && this.hAreas.get( areaId )[ roomId ] !== undefined )
{
//I can get here...
//alert( uneval( this.hAreas.get( areaId ) ) );
// returns: ({'000001':{areaId:"000001", roomId:"000001", Informations:{Name:"Room 1"}}, '000002':{areaId:"000001", roomId:"000002", Informations:{Name:"Room 2"}}, '000003':{areaId:"000001", roomId:"000003", Informations:{Name:"Room 3"}}})
//alert( roomId );
// returns: 000003
return this.hAreas.get( areaId )[ roomId ];
// returns: undefined
}
},
reloadAreas : function( areaId ) {
//Triggered by Tick only if there is no players
},
addCharacter : function( areaId, roomId, character ) {
if ( this.hAreas.get( areaId ) && this.hAreas.get( areaId )[ roomId ] )
{
this.hAreas.get( areaId )[ roomId ].addCharacter( character );
}
},
removeCharacter : function( areaId, roomId, character ) {
return this.hAreas.get( areaId )[ roomId ].removeCharacter( character );
}
});
var Room = new JS.Class({
hDoors : new JS.Hash([]),
hExits : new JS.Hash([]),
hBodies : new JS.Hash([]),
hObjects : new JS.Hash([]),
initialize : function( areaId, roomId, Informations ) {
this.areaId = areaId;
this.roomId = roomId;
this.Informations = Informations;
//TODO: Load from external sources
if ( areaId == "000001" && roomId == "000003" )
{
this.hObjects.put("000001", new Objects("000001", { "Name" : "A table", "Type" : 0 }) );
this.hObjects.put("000002", new Objects("000002", { "Name" : "A water fountain", "Type" : 1 }) );
}
appendConsole( "Room: #" + this.areaId + "-" + this.roomId + " : " + this.Informations.Name + " Created" );
},
addCharacter : function( character ) {
this.hBodies.put( character.characterId , character );
character.onArriveRoom( this );
if ( ! character.Informations.Stealth )
{
//TODO: Broadcast Informations to others
appendConsole( character.Informations.Name + " has arrived to " + this.Informations.Name );
}
},
removeCharacter : function( character ) {
var characterId = ( typeof character == "object" ) ? character.characterId : character,
currentCharacter = this.hBodies.remove( characterId );
character.onLeaveRoom( this );
if ( currentCharacter !== null )
{
//TODO: Broadcast Informations to others
appendConsole( character.Informations.Name + " has left " + this.Informations.Name );
return currentCharacter;
}
return undefined;
},
onArrive : function() {
},
onLeave : function() {
},
getObjects : function( objectId, hash ) {
if ( this.hObjects.get( objectId ) )
{
var currentObjects = this.hObjects.get( objectId );
if ( hash )
{
return new JS.Hash([
currentObjects.objectId, currentObjects
]);
}
return currentObjects;
}
return this.hObjects;
},
toString : function( characterId ) {
}
});
var Objects = new JS.Class({
objectsTypes : {
0 : "lies",
1 : "stands"
},
initialize : function( objectId, Informations ) {
this.objectId = objectId;
this.Informations = Informations;
appendConsole( "Object: #" + this.objectId + " : " + this.Informations.Name + " Created" );
},
toString : function() {
return this.Informations.Name + " " + this.objectsTypes[ this.Informations.Type ] + " here.";
}
});
var Character = new JS.Class({
Pet : undefined,
initialize : function( characterId, Informations ) {
this.characterId = characterId;
this.Informations = Informations;
this.areaId = this.Informations.Zone.split("-")[ 0 ];
this.roomId = this.Informations.Zone.split("-")[ 1 ];
if ( this.Informations.Pet !== undefined )
{
//TODO: Load from external sources
if ( this.Informations.Pet === "000001" )
{
this.Pet = new Pet( "000001", { "Name" : "Molten Panther", "Zone" : this.areaId + "-" + this.roomId, "Stealth" : false } );
World.addCharacter( this.Pet.getArea() , this.Pet.getRoom() , this.Pet );
var petRoom = World.getRoomById( this.Pet.getArea() , this.Pet.getRoom() );
alert( petRoom ); // = undefined ????
}
}
appendConsole( "Character: #" + this.characterId + " : " + this.Informations.Name + " Created" );
},
onArriveRoom : function ( currentRoom ) {
},
onLeaveRoom : function( currentRoom ) {
},
onArrive : function() {
},
onLeave : function() {
},
getRoom : function() {
return this.roomId + "";
},
getArea : function() {
return this.areaId + "";
},
getInformations : function() {
return this.Informations;
},
hasPet : function() {
return ( typeof this.Pet == "object" );
},
getPet : function() {
return this.Pet;
},
equals : function( character ) {
return ( character instanceof this.klass ) && character.Informations.Name === this.Informations.Name;
}
});
var Pet = new JS.Class( Character, {
initialize : function( characterId, Informations ) {
this.callSuper();
appendConsole( "Pet: " + this.Informations.Name + " Created" );
}
});
//Tests
var World = new World();
var AreaOne = World.getAreas( "000001" );
var Cybrix = new Character( "000001", { "Name" : "Cybrix", "Zone" : "000001-000003", "Stealth" : false, "Pet" : "000001" } );
if ( World.getAreas( Cybrix.getArea() ) )
{
World.addCharacter( Cybrix.getArea() , Cybrix.getRoom() , Cybrix );
//Cybrix = World.removeCharacter( Cybrix.getArea() , Cybrix.getRoom() , Cybrix );
}
});
</script>
</head>
<body style="margin: 0; padding: 0;">
<div id="console" style="display: block; background-color: #000; height: 100%; color: #FFF; font-family: Lucida Console;"></div>
</body>
</html>

I've been playing around with your example on jsfiddle and I'm running into some rather odd behavior. In your Character class' initialization method you're calling the World.getRoomById() method in question and assigning it to a variable called petRoom.
As your code stands, when you alert(petRoom) you do get undefined. However, if you alert(petRoom.roomId) you get 000003 as intended so my guess is it's not really returning a true undefined. If you log petRoom to chrome's console it classifies it as a constructor and not an object. I'm not really sure what's going on there, but I thought it'd give some extra direction. I'll keep playing.....
UPDATE: The issue is that you're overriding the Room class' toString() method and not returning anything. By default, alerting something cast it to a string using the object's toString() method and because you've overridden that and aren't returning a value you get undefined.
var Room = new JS.class({
...
snip
....
toString: function(characterId) {
}
});

Answering your question in the comments
how could the if passes when once you return the value it is undefined
You're using the comparison this.hAreas.get( areaId )[ roomId ] !== undefined. What that will do is test that the value on the left isn't strictly equal to that specific undefined instance. If you're dealing with multiple windows/frames, it's possible to have different undefined instances (because each window has its own undefined). If that sounds really weird, it's because it is.
To guard against that, you usually see that comparison written as:
if (typeof this.hAreas.get( areaId )[ roomId ] !== "undefined")
...which tests that the type of the operand is "undefined" (note the quotes), which is reliable cross-window.

Try this instead:
typeof this.hAreas.get( areaId )[ roomId ] !== "undefined"

Related

Scrapping memory issue (Out Of Memory)

Good day,
I have cameras that are saving videos by clips on a cloud service, with a limit on N clips. In order to save more clips, I made a scrapping script that gets all my video links from the website where I can preview them. (to be executed on page load with a JS extension)
Note that these are M3U8 files.
Here is my script:
var cameraScrapper = {
playerReady: false,
videos: {},
cameraCurrent: 0,
cameras: [
'cid1', // #1
'cid2', // #3
'cid3', // #2
],
gui: function() {
return {
calendarPreviousMonth: document.getElementById( 'event_calendar_section' ).getElementsByClassName( 'navigation' )[0].getElementsByClassName( 'prev' )[0],
calendarNextMonth: document.getElementById( 'event_calendar_section' ).getElementsByClassName( 'navigation' )[0].getElementsByClassName( 'next' )[0],
calendarSelectedDate: document.getElementById( 'event_selected_date' ),
calendarMonthDays: document.getElementById( 'event_calendar_section' ).getElementsByClassName( 'month' )[0].children,
cameras: document.getElementById( 'camera_list_dropdown' ).children,
dayClips: document.getElementById( 'event_clips_wrap' ).children,
noRecords: document.getElementsByClassName( 'no_recording' )[0]
};
},
init: function() {
document.getElementById( 'hls_player' ).addEventListener( 'canplay', function() { this.playerReady = true; }.bind( this ) );
for( let i = 0; i < this.cameras.length; i++ ) {
if( window.location.href.includes( '=' + this.cameras[i] + '&' ) ) {
this.cameraCurrent = i;
break;
}
}
while( !this.gui().calendarPreviousMonth.children[0].classList.contains( 'disabled' ) ) {
this.gui().calendarPreviousMonth.click();
}
this.scrap();
},
getVideo: function( pCamera, pTimeStamp ) {
let performance = window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {};
let requests = ( performance.getEntries() || {} );
for( let i = 0; i < requests.length; i++ ) {
if( requests[i].name.includes( '.ts?' ) ) {
if( this.videos[encodeURIComponent( requests[i].name )] === undefined ) {
this.videos[encodeURIComponent( requests[i].name )] = { 'camera': pCamera, 'timestamp': this.formatDate( pTimeStamp ) };
}
}
}
if( Object.entries( this.videos ).length > 25 ) {
this.save();
this.videos = {};
performance.clearMarks();
performance.clearMeasures()
performance.clearResourceTimings();
}
},
formatDate( pTimestamp ) {
let date = pTimestamp.split( ' ' )[0];
let time = pTimestamp.split( ' ' )[1];
let month = {
JAN: '01',
FEB: '02',
MAR: '03',
APR: '04',
MAY: '05',
JUN: '06',
JUL: '07',
AUG: '08',
SEP: '09',
OCT: '10',
NOV: '11',
DEC: '12'
}
return date.split( '.' )[2] + '-' + month[date.split( '.' )[1]] + '-' + date.split( '.' )[0] + ' ' + time;
},
sleep: function( pMs ) {
return new Promise( resolve => setTimeout( resolve, pMs ) );
},
scrap: async function() {
let scrapDays = true;
while( scrapDays ) {
for( let i = 0; i < this.gui().calendarMonthDays.length; i++ ) {
if( !this.gui().calendarMonthDays[i].classList.contains( 'is-disabled' ) && !this.gui().calendarMonthDays[i].classList.contains( 'is-expired' ) && !this.gui().calendarMonthDays[i].classList.contains( 'is-future' ) ) {
// console.log( 'day ' + this.gui().calendarMonthDays[i].innerText );
this.gui().calendarMonthDays[i].click();
let clipsLoaded = false;
if( this.gui().noRecords !== undefined ) {
clipsLoaded = !this.gui().noRecords.classList.contains( 'displayOff' )
}
while( !clipsLoaded && ( this.gui().dayClips.length == 0 ) ) {
await this.sleep( 99 );
if( this.gui().noRecords !== undefined ) {
clipsLoaded = !this.gui().noRecords.classList.contains( 'displayOff' )
}
}
// console.log( 'clips ' + this.gui().dayClips.length );
for( let j = 0; j < this.gui().dayClips.length; j++ ) {
this.playerReady = false;
this.gui().dayClips[j].children[0].click();
while( !this.playerReady ) {
await this.sleep( 99 );
}
this.getVideo( ( '' + this.cameraCurrent ), this.gui().calendarSelectedDate.innerText + ' ' + this.gui().dayClips[j].children[0].children[1].children[1].innerText );
}
}
}
if( !this.gui().calendarNextMonth.children[0].classList.contains( 'disabled' ) ) {
this.gui().calendarNextMonth.click();
} else {
scrapDays = false;
}
}
this.save();
this.sleep( 4999 );
let cameraNext = this.cameraCurrent + 1;
if( this.cameras.length >= cameraNext ) {
cameraNext = 0;
}
window.location.href = 'https://cloudcamerasservice.com/camera?no=' + this.cameras[cameraNext] + '&model=CAM';
},
save() {
let xhr = new XMLHttpRequest();
xhr.open( 'POST', 'http://localhost/videomonitoring/stack.php', true );
xhr.setRequestHeader( 'Content-type', 'application/x-www-form-urlencoded' );
xhr.onload = ( e ) => { /* console.log( 'saved' ); */ };
xhr.onerror = ( e ) => {};
xhr.send( 'stack=' + encodeURIComponent( JSON.stringify( this.videos ) ) );
}
};
setTimeout( function() { cameraScrapper.init() }.bind( this ), 4999 );
stack.php will handle file download from provided list, my script is mainly about getting the video links and date of recording.
But when launching my script, my browser run out of memory after 75-100 clips saved. Can you help me with this?
Not sure if it's comming from my script, indeed, I have the feeling this is due to preloading many videos on the same page.

ajaxStart - Change display not always working

NOTE:: I have replaced some code with comments to make it much shorter and more readable
I am working with Javascript (Ajax) and PHP (Laravel). I have run into a predicament! When calling an ajax function I have two listener to show a loading symbol while the ajax is processing, and then hide it again once it's done.
$( document ).ajaxStart( function() {
$( '#loading' ).css( 'display', 'block' );
} );
$( document ).ajaxStop( function() {
$( '#loading' ).css( 'display', '' );
} );
When you click on the submit button, the HTML onclick says to go to this function which is working just fine:
function submit( button ) {
var table = $( button ).closest( '.popup' ).find( 'table:first' );
var verified = verifyTable( table );
if ( verified == -1 ) {
return -1;
}
if ( table.hasClass( 'campaigns' ) ) {
campaign = table.find( '.campaign:first' );
submitNewCampaign( campaign );
} else if ( table.hasClass( 'groups' ) ) {
groups = table.find( 'tr.group' );
for ( var i = 0; i < groups.length; ++i ) {
submitNewGroup( groups.eq( i ) );
}
} else if ( table.hasClass( 'keywords' ) ) {
keywords = table.find( 'tr.keyword' );
for ( var i = 0; i < keywords.length; ++i ) {
submitNewKeyword( keywords.eq( i ) );
}
}
closePopup();
}
If from there you are sent to submitNewCampaign(), everything works just fine.
function submitNewCampaign( campaign ) {
// Set campaign variables
$.ajax({
url : '/ajax/addCampaign',
type : 'POST',
data : { // set campaign data },
success : function( result ) {
// get all groups in campaigns and loop through
for ( var i = 0; i < groups.length; ++i ) {
// set group variables
$.ajax({
url : '/ajax/addGroup',
type : 'POST',
async : false,
data : { // set group data },
success : function( result ) {
// get all keywords in group and loop
for ( var i = 0; i < keywords.length; i++ ) {
// set keyword variables
$.ajax({
url : '/ajax/addKeyword',
type : 'POST',
async : false,
data : { // set keyword data },
success : function( result ) { // done },
error : function( result ) {
alert( "error adding new keyword (name - " + keyword_name + ")");
console.log( result );
}
);
}
},
error : function( result ) {
alert( "error adding new group (name - " + group_name + ")" );
console.log( result );
}
});
}
},
error : function( result ) {
alert( "error adding new campaign (name - " + campaign_name + "): " + JSON.parse( xhr.responseText ) );
}
});
}
However if you are send to either submitNewGroup() or submitNewKeyword(), the loading image does not appear.
function submitNewGroup ( group ) {
// set group variables
$.ajax({
url : '/ajax/addGroup',
type : 'POST',
async : false,
data : { // set group data },
success : function( result ) {
// get all keywords in group and loop
for ( var i = 0; i < keywords.length; ++i ) {
// set all keyword variables
$.ajax({
url : '/ajax/addKeyword',
type : 'POST',
async : false,
data : { // set all keyword data },
success : function( result ) { // done },
error : function( result ) {
console.log( result );
}
});
}
},
error : function( result ) {
console.log( result );
}
});
}
function submitNewKeyword( keyword ) {
// set keyword variables
$.ajax({
url : '/ajax/addKeyword',
type : 'POST',
async : false,
data : { // set keyword data },
success : function( result ) { //done },
error : function( result ) {
console.log( result );
}
});
}
IMPORTANT: No errors appear in the log when any of the three functions are called. All three complete their assigned tasks with no issues.
I tried a few things and the one that made it work was: I removed async from the outer most ajax call for both group and keyword

Jquery error in autocomplete

Im getting Uncaught TypeError: Cannot use 'in' operator to search for 'length' in on a autocomplete field. This is the code:
enable_autocomplete: function() {
$( 'input.fm-autocomplete:visible' ).each( function() {
if ( !$( this ).hasClass( 'fm-autocomplete-enabled' ) ) {
var ac_params = {};
var $el = $( this );
var $hidden = $el.siblings( 'input[type=hidden]' ).first();
ac_params.select = function( e, ui ) {
e.preventDefault();
$el.val( ui.item.label );
$hidden.val( ui.item.value ).trigger( 'change' );
};
ac_params.focus = function( e, ui ) {
e.preventDefault();
$el.val( ui.item.label );
}
if ( $el.data( 'action' ) ) {
ac_params.source = function( request, response ) {
// Check for custom args
var custom_args_js_event = $el.data( 'customArgsJsEvent' );
var custom_data = '';
if ( 'undefined' !== typeof custom_args_js_event && null !== custom_args_js_event ) {
var custom_result = $el.triggerHandler( custom_args_js_event );
if ( 'undefined' !== typeof custom_result && null !== custom_result ) {
custom_data = custom_result;
}
}
$.post( ajaxurl, {
action: $el.data( 'action' ),
fm_context: $el.data( 'context' ),
fm_subcontext: $el.data( 'subcontext' ),
fm_autocomplete_search: request.term,
fm_search_nonce: fm_search.nonce,
fm_custom_args: custom_data
}, function( result ) {
console.log( result );
$.parseJSON( response( result ) );
} );
};
All other questions related to this error suggested a $.parseJSON but it's not working for me. This is the console.log of result when i type eco:
[{"label":"Economy Talks","value":1480},{"label":"Economy","value":212},{"label":"Economy motors","value":2038},{"label":"Telecomunica\u00e7\u00f5es","value":402}]
Console.log of response:
function (){return a.apply(b||this,c.concat(e.call(arguments)))}
It finds the right suggestions but then i get Uncaught TypeError: Cannot use 'in' operator to search for 'length' in and i'm not able to select any option. Any ideas how to fix this?

WP - Get stylesheet_directory in JS

I am trying to get stylesheet_directory in JS, but can't get it to work.
Here is what I have tried:
url : '<?php bloginfo('stylesheet_directory'); ?>/img/hamburger.svg'
AND:
var stylesheetDir = "<?php bloginfo('stylesheet_directory') ?>";
url : '$stylesheetDir/img/hamburger.svg',
I guess there is just a problem with some characters or something? Could you please help me out?
svgicons-config-js
var stylesheetDir = "<?php bloginfo('stylesheet_directory') ?>";
url == $stylesheetDir;
decodeURI(url);
var svgIconConfig = {
hamburgerCross : {
url : stylesheetDir + '/img/hamburger.svg',
animation : [
{
el : 'path:nth-child(1)',
animProperties : {
from : { val : '{"path" : "m 5.0916789,20.818994 53.8166421,0"}' },
to : { val : '{"path" : "M 12.972944,50.936147 51.027056,12.882035"}' }
}
},
{
el : 'path:nth-child(2)',
animProperties : {
from : { val : '{"transform" : "s1 1", "opacity" : 1}', before : '{"transform" : "s0 0"}' },
to : { val : '{"opacity" : 0}' }
}
},
{
el : 'path:nth-child(3)',
animProperties : {
from : { val : '{"path" : "m 5.0916788,42.95698 53.8166422,0"}' },
to : { val : '{"path" : "M 12.972944,12.882035 51.027056,50.936147"}' }
}
}
]
},
};
hamburger_animation.js
(function() {
[].slice.call( document.querySelectorAll( '.si-icons-default > .si-icon' ) ).forEach( function( el ) {
var svgicon = new svgIcon( el, svgIconConfig );
} );
new svgIcon( document.querySelector( '.si-icons-easing .si-icon-hamburger' ), svgIconConfig, { easing : mina.backin } );
new svgIcon( document.querySelector( '.si-icons-easing .si-icon-hamburger-cross' ), svgIconConfig, { easing : mina.elastic, speed: 600 } );
})();
svgicons.js
/**
* svgicons.js v1.0.0
* http://www.codrops.com
*
* Licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright 2013, Codrops
* http://www.codrops.com
*/
;( function( window ) {
'use strict';
/*** helper functions ***/
// from https://github.com/desandro/classie/blob/master/classie.js
function classReg( className ) {
return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
}
function hasClass( el, c ) {
return 'classList' in document.documentElement ? el.classList.contains( c ) : classReg( c ).test( el.className )
}
function extend( a, b ) {
for( var key in b ) {
if( b.hasOwnProperty( key ) ) {
a[key] = b[key];
}
}
return a;
}
// from http://stackoverflow.com/a/11381730/989439
function mobilecheck() {
var check = false;
(function(a){if(/(android|ipad|playbook|silk|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
return check;
}
// http://snipplr.com/view.php?codeview&id=5259
function isMouseLeaveOrEnter( e, handler ) {
if (e.type != 'mouseout' && e.type != 'mouseover') return false;
var reltg = e.relatedTarget ? e.relatedTarget :
e.type == 'mouseout' ? e.toElement : e.fromElement;
while (reltg && reltg != handler) reltg = reltg.parentNode;
return (reltg != handler);
}
/*** svgIcon ***/
function svgIcon( el, config, options ) {
this.el = el;
this.options = extend( {}, this.options );
extend( this.options, options );
this.svg = Snap( this.options.size.w, this.options.size.h );
this.svg.attr( 'viewBox', '0 0 64 64' );
this.el.appendChild( this.svg.node );
// state
this.toggled = false;
// click event (if mobile use touchstart)
this.clickevent = mobilecheck() ? 'touchstart' : 'click';
// icons configuration
this.config = config[ this.el.getAttribute( 'data-icon-name' ) ];
// reverse?
if( hasClass( this.el, 'si-icon-reverse' ) ) {
this.reverse = true;
}
if( !this.config ) return;
var self = this;
// load external svg
Snap.load( this.config.url, function (f) {
var g = f.select( 'g' );
self.svg.append( g );
self.options.onLoad();
self._initEvents();
if( self.reverse ) {
self.toggle();
}
});
}
svgIcon.prototype.options = {
speed : 200,
easing : mina.linear,
evtoggle : 'click', // click || mouseover
size : { w : 64, h : 64 },
onLoad : function() { return false; },
onToggle : function() { return false; }
};
svgIcon.prototype._initEvents = function() {
var self = this, toggleFn = function( ev ) {
if( ( ( ev.type.toLowerCase() === 'mouseover' || ev.type.toLowerCase() === 'mouseout' ) && isMouseLeaveOrEnter( ev, this ) ) || ev.type.toLowerCase() === self.clickevent ) {
self.toggle(true);
self.options.onToggle();
}
};
if( this.options.evtoggle === 'mouseover' ) {
this.el.addEventListener( 'mouseover', toggleFn );
this.el.addEventListener( 'mouseout', toggleFn );
}
else {
this.el.addEventListener( this.clickevent, toggleFn );
}
};
svgIcon.prototype.toggle = function( motion ) {
if( !this.config.animation ) return;
var self = this;
for( var i = 0, len = this.config.animation.length; i < len; ++i ) {
var a = this.config.animation[ i ],
el = this.svg.select( a.el ),
animProp = this.toggled ? a.animProperties.from : a.animProperties.to,
val = animProp.val,
timeout = motion && animProp.delayFactor ? animProp.delayFactor : 0;
if( animProp.before ) {
el.attr( JSON.parse( animProp.before ) );
}
if( motion ) {
setTimeout(function( el, val, animProp ) {
return function() { el.animate( JSON.parse( val ), self.options.speed, self.options.easing, function() {
if( animProp.after ) {
this.attr( JSON.parse( animProp.after ) );
}
if( animProp.animAfter ) {
this.animate( JSON.parse( animProp.animAfter ), self.options.speed, self.options.easing );
}
} ); };
}( el, val, animProp ), timeout * self.options.speed );
}
else {
el.attr( JSON.parse( val ) );
}
}
this.toggled = !this.toggled;
};
// add to global namespace
window.svgIcon = svgIcon;
})( window );
The site can be found here: http://goo.gl/wuUwUG
Please inspect element (or similar), and look at the code where it says "Failed to load resource: the server responded with a status of 404 (Not Found)"
Instead of:
url : '$stylesheetDir/img/hamburger.svg',
use
url : stylesheetDir + '/img/hamburger.svg',
EDIT
So, the following code is obsolete and unnecessary (it does nothing and can be removed):
url == $stylesheetDir;
decodeURI(url);
Feel free to remove it. Other than that everything looks fine.
I guess some more code is needed. You should reveal how you're using the svgIconConfig variable, and specifically, the url property.
EDIT
Thanks for revealing some more code. It appears that you're calling a <?php ... ?> block within a JS file. This block is not parsed by the server, so it is directly displayed instead of rendering the URL to the theme.
I'm not sure how you're enqueueing the scripts in the code, so I'll propose a solution that will work with any use case.
To fix this, insert the following in your theme functions.php
add_action('wp_head', 'my_js_var_stylesheet_directory', 9);
function my_js_var_stylesheet_directory() {
echo '<script type="text/javascript">';
echo 'var stylesheetDir = "' . get_bloginfo('stylesheet_directory') . '"';
echo '</script>';
}
and delete the top 3 lines from your svgicons-config-js file, as they are unnecessary.
From your code you have to echo the path for the css directory.
Check this one out :
var stylesheetDir = '<?php echo loginfo('stylesheet_directory') ; ?>/img/hamburger.svg';
console.log(stylesheetDir);

How can I add a css element change to an onlick event in this jquery lib?

I've got this awesome slideshow library working just fine on my site (yoinked from codrops), but since I'm shifting between different pieces of information, I want to really call out the difference by adding a CSS change so that the background color matches the color of the content in the slide. Now, this is a library, so i figure I need to add the $('body').css call into it, and not my html doc. I'm including the code below, with a note marking where I think it's supposed to go. I'm jsut not sure what the exact phrasing would be since I've never worked inside a lib before. Any suggestions would be welcome!
;( function( $, window, undefined ) {
'use strict';
// global
var Modernizr = window.Modernizr;
$.CBPFWSlider = function( options, element ) {
this.$el = $( element );
this._init( options );
};
// the options
$.CBPFWSlider.defaults = {
// default transition speed (ms)
speed : 500,
// default transition easing
easing : 'ease'
};
$.CBPFWSlider.prototype = {
_init : function( options ) {
// options
this.options = $.extend( true, {}, $.CBPFWSlider.defaults, options );
// cache some elements and initialize some variables
this._config();
// initialize/bind the events
this._initEvents();
},
_config : function() {
// the list of items
this.$list = this.$el.children( 'ul' );
// the items (li elements)
this.$items = this.$list.children( 'li' );
// total number of items
this.itemsCount = this.$items.length;
// support for CSS Transitions & transforms
this.support = Modernizr.csstransitions && Modernizr.csstransforms;
this.support3d = Modernizr.csstransforms3d;
// transition end event name and transform name
var transProperties = {
'WebkitTransition' : { transitionEndEvent : 'webkitTransitionEnd', tranformName : '-webkit-transform' },
'MozTransition' : { transitionEndEvent : 'transitionend', tranformName : '-moz-transform' },
'OTransition' : { transitionEndEvent : 'oTransitionEnd', tranformName : '-o-transform' },
'msTransition' : { transitionEndEvent : 'MSTransitionEnd', tranformName : '-ms-transform' },
'transition' : { transitionEndEvent : 'transitionend', tranformName : 'transform' }
};
if( this.support ) {
this.transEndEventName = transProperties[ Modernizr.prefixed( 'transition' ) ].transitionEndEvent + '.cbpFWSlider';
this.transformName = transProperties[ Modernizr.prefixed( 'transition' ) ].tranformName;
}
// current and old itemĀ“s index
this.current = 0;
this.old = 0;
// check if the list is currently moving
this.isAnimating = false;
// the list (ul) will have a width of 100% x itemsCount
this.$list.css( 'width', 100 * this.itemsCount + '%' );
// apply the transition
if( this.support ) {
this.$list.css( 'transition', this.transformName + ' ' + this.options.speed + 'ms ' + this.options.easing );
}
// each item will have a width of 100 / itemsCount
this.$items.css( 'width', 100 / this.itemsCount + '%' );
// add navigation arrows and the navigation dots if there is more than 1 item
if( this.itemsCount > 1 ) {
// add navigation arrows (the previous arrow is not shown initially):
this.$navPrev = $( '<span class="cbp-fwprev"><</span>' ).hide();
this.$navNext = $( '<span class="cbp-fwnext">></span>' );
$( '<nav/>' ).append( this.$navPrev, this.$navNext ).appendTo( this.$el );
// add navigation dots
var dots = '';
for( var i = 0; i < this.itemsCount; ++i ) {
// current dot will have the class cbp-fwcurrent
var dot = i === this.current ? '<span class="cbp-fwcurrent"></span>' : '<span></span>';
dots += dot;
}
var navDots = $( '<div class="cbp-fwdots"/>' ).append( dots ).appendTo( this.$el );
this.$navDots = navDots.children( 'span' );
}
},
_initEvents : function() {
var self = this;
if( this.itemsCount > 1 ) {
this.$navPrev.on( 'click.cbpFWSlider', $.proxy( this._navigate, this, 'previous' ) );
this.$navNext.on( 'click.cbpFWSlider', $.proxy( this._navigate, this, 'next' ) );
this.$navDots.on( 'click.cbpFWSlider', function() { self._jump( $( this ).index() ); } );
}
},
_navigate : function( direction ) {
// do nothing if the list is currently moving
if( this.isAnimating ) {
return false;
}
this.isAnimating = true;
// update old and current values
this.old = this.current;
if( direction === 'next' && this.current < this.itemsCount - 1 ) {
++this.current;
//***I think maybe it goes here?!?
}
else if( direction === 'previous' && this.current > 0 ) {
--this.current;
//***I think maybe it goes here?!?
}
// slide
this._slide();
},
_slide : function() {
// check which navigation arrows should be shown
this._toggleNavControls();
// translate value
var translateVal = -1 * this.current * 100 / this.itemsCount;
if( this.support ) {
this.$list.css( 'transform', this.support3d ? 'translate3d(' + translateVal + '%,0,0)' : 'translate(' + translateVal + '%)' );
}
else {
this.$list.css( 'margin-left', -1 * this.current * 100 + '%' );
}
var transitionendfn = $.proxy( function() {
this.isAnimating = false;
}, this );
if( this.support ) {
this.$list.on( this.transEndEventName, $.proxy( transitionendfn, this ) );
}
else {
transitionendfn.call();
}
},
_toggleNavControls : function() {
// if the current item is the first one in the list, the left arrow is not shown
// if the current item is the last one in the list, the right arrow is not shown
switch( this.current ) {
case 0 : this.$navNext.show(); this.$navPrev.hide(); break;
case this.itemsCount - 1 : this.$navNext.hide(); this.$navPrev.show(); break;
default : this.$navNext.show(); this.$navPrev.show(); break;
}
// highlight navigation dot
this.$navDots.eq( this.old ).removeClass( 'cbp-fwcurrent' ).end().eq( this.current ).addClass( 'cbp-fwcurrent' );
},
_jump : function( position ) {
// do nothing if clicking on the current dot, or if the list is currently moving
if( position === this.current || this.isAnimating ) {
return false;
}
this.isAnimating = true;
// update old and current values
this.old = this.current;
this.current = position;
// slide
this._slide();
},
destroy : function() {
if( this.itemsCount > 1 ) {
this.$navPrev.parent().remove();
this.$navDots.parent().remove();
}
this.$list.css( 'width', 'auto' );
if( this.support ) {
this.$list.css( 'transition', 'none' );
}
this.$items.css( 'width', 'auto' );
}
};
var logError = function( message ) {
if ( window.console ) {
window.console.error( message );
}
};
$.fn.cbpFWSlider = function( options ) {
if ( typeof options === 'string' ) {
var args = Array.prototype.slice.call( arguments, 1 );
this.each(function() {
var instance = $.data( this, 'cbpFWSlider' );
if ( !instance ) {
logError( "cannot call methods on cbpFWSlider prior to initialization; " +
"attempted to call method '" + options + "'" );
return;
}
if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
logError( "no such method '" + options + "' for cbpFWSlider instance" );
return;
}
instance[ options ].apply( instance, args );
});
}
else {
this.each(function() {
var instance = $.data( this, 'cbpFWSlider' );
if ( instance ) {
instance._init();
}
else {
instance = $.data( this, 'cbpFWSlider', new $.CBPFWSlider( options, this ) );
}
});
}
return this;
};
} )( jQuery, window );
Answered my own question with a little digging.
_navigate : function( direction ) {
// do nothing if the list is currently moving
if( this.isAnimating ) {
return false;
}
this.isAnimating = true;
// update old and current values
this.old = this.current;
if( direction === 'next' && this.current < this.itemsCount - 1 ) {
++this.current;
}
else if( direction === 'previous' && this.current > 0 ) {
--this.current;
}
console.log(this.current);
if(this.current == 0)
{
$('body').css('background', '#FF6A00');
}else if(this.current == 1)
{
$('body').css('background', '#595C5A');
}else if(this.current == 2)
{
$('body').css('background', '#000000');
}
// slide //AROUND HERE?
this._slide();
},

Categories