snap.load() fails to load multiple svgs properly - javascript

Exactly how Snap.load() loads svgs internally. If run iteratively on array of svgs the script shows array index of bound. If run recursively the order of the images messes up. Although one by one loading works fine. Here is what i tried:
http://jsfiddle.net/nahid/C3q2r/
p.s: comment out the necessary portions to see the behavior.

I was originally thinking of another way (posted in google groups an answer), but I think this solution is a bit neater if it works for you, so putting this as an answer...
To get them in order, you could call the next loading on completion of the the previous loading, which is what I think you were trying to do.
jsfiddle here... http://jsfiddle.net/C3q2r/4/
var handlr = function( i ){
if(i >= svg_array.length) return;
var name = svg_array[i];
Snap.load(name,function(f){
var g = f.select('g');
footpaper[i].append(g.clone());
}, handlr( i + 1));
}
handlr(0);

Related

sports - title-- -- > {} third-- -- > undefined

i am new to js
Around eight hours I am trying to debug why I am getting the below empty object
document.getElementsByClassName("sports-title") is working fine in fiddle but when I put in my code base its not working fine.
it is returning like this so I am not able to proceed.
codebase output
sports - title-- -- > {}
third-- -- > undefined
fiddle ouput
sports-title---->{"0":{}} third---->{}
I am using same html structure.
can you guys tell me what could be problem so that I can proceed.
findStringInsideDiv() {
var sportsTitle = document.getElementsByClassName("sports-title");
var third = sportsTitle[0];
var thirdHTML = third.innerHTML
//str = str.split(" ")[4];
console.log("sports-title---->" + JSON.stringify(sportsTitle));
console.log("third---->" + JSON.stringify(third));
console.log("thirdHTML---->" + JSON.stringify(thirdHTML));
if ( thirdHTML === " basketball football swimming " ) {
console.log("matching basketball---->");
var menu = document.querySelector('.sports');
menu.classList.add('sports-with-basketball');
// how to add this class name directly to the first div after body.
// but we are not rendering that div in accordion
//is it possible
}
else{
console.log("not matching");
}
}
If document.getElementsByClassName("sports-title") isn't returning any elements this could mean:
Your HTML source doesn't have any elements with class="sports-title", possibly because of a syntax error, spelling error, etc.. Try inspecting your web page with a browser's DOM inspector and look for the elements which you think should be in the sports-title class.
Or
Your Javascript is executing before the .sports-title elements are actually added to the document, because scripts are (normally) executed synchronously during document parsing, as soon as the parser encounters them. Try moving the <script> element to the end of the <body>, after all the other elements are defined.
There may be other possible causes that I can't think of right now.
This probably isn't the answer but I can't leave a comment so here goes:
I was messing with your jsFiddle and I noticed that if you change JSON.stringify(object) to object.ToString that they turn into undefined. So my question to you is are you sure you're code in your codebase matches the jsfiddle?
Also if you're using JSfiddle to make and test your code first, you might consider installing Brackets.io. It has a nifty live update feature that makes web development easier for beginners and it opens up a preview on the browser. I've noticed in the past that JSfiddle doesn't always operate the same as a browser.

How to _prevent_ divs from appearing in random order

Okay, so I'm learning front-end dev with javascript/jquery/bootstrap through FreeCodeCamp. This is not a core part of the project, but I don't understand it and it's distracting me too much. In this code pen here:
http://codepen.io/JDenman6/pen/zqeGwp/ --
I have an array of Twitch.tv usernames that I check through an API and build divs to display them based on the JSON object comes back from the API call.
The weird thing is that every time I refresh the page, I get the divs in a different (apparently random) order. I'm guessing that the API calls are going out asynchronously and the divs are appearing in the order that the API calls finish.
When I Googled for other people having problems with divs in random order I found many solutions for causing random display order, but nothing on preventing it. So then I went looking for a solution to sorting divs and found this post, Ordering DIVs based on class name using Javascript/Jquery, which led me to this bit of code:
$(function(){
var elem = $('#twitcherList').find('div').sort(sortMe);
$('#twitcherList').append(elem);
});
function sortMe(a, b) {
return a.className < b.className;
}
Only I haven't been able to get it to work. I forked off my original codepen to do some poking around here: http://codepen.io/JDenman6/pen/MeYOJP.
The list of divs in the twitcherList in the html tab is from inspecting the twitcherList after rendering the original code. I thought it might be easier to sort them if they're hard coded, rather than coming in from the API call. I also added a little test div and inserted some code into the sort function to 1) check that it was running and 2) double check that a.classname and b.classname were returning what I thought they were, which they are.
I feel like I'm missing something massive, fundamental, and possibly quite obvious. Any thoughts?
You need to return -1, 0 or 1 based on the condition for proper sorting.
function sortMe(a, b) {
return a.className.localeCompare(b.className);
}
For better browser support use,
function sortMe(a, b) {
return a.className < b.className ? 1 : -1;
}

Is it a good idea to cache jQuery selections on a page level?

I am working on an intranet website where there is a lot of interaction with the main page. The site uses jQuery extensively. So I thought about caching the jQuery selections the first time they are requested and pull them from the cache for each subsequent request. (I also have built in an override if I want to force a re-selection).
Here is the basic snippet of code I am wondering about:
( function(window, $, undefined) {
var mp = {};
mp.cache = [];
mp.get = function ( selector, force) {
return ( !force || !mp.cache[ selector ] ) /*separating for readability */
? mp.cache[ selector ] = $( selector )
: mp.cache[ selector ];
}
/* more functions and code */
window.mp = mp;
window.$$ = mp.get;
})(window, jQuery);
It would be used just like a normal jQuery selection but checks to see if that selector already exists in the cache array and, if it does, just returns the results from there.
UPDATED EXAMPLE
$('#mainmenu').on('click','.menuitem', highlightSelectedMenuItem );
function highlightSelectedMenuItem () {
var menuitems = $$('.menuitem'); //selected first time, from cache every other time
menuitems.find('.current').removeClass('current');
$(this).addClass('current');
}
There are about 20 - 30 different selections in the code. So each would be cached on first call. This code will only be run on desktop clients (no phones/tablets).
Good idea? Any issues this might cause? Is there a good way to test if this helps/hurts performance? Any pros/cons you can come up with would be appreciated.
Let me know if more information is required.
Here is a fiddle to "fiddle" with.
Thanks!
Bottom line: Probably a bad idea.
You're introducing complexity that is likely unnecessary and is likely just going to eat up memory.
If you're trying to speed up selections that are repeated, then store the selection in a variable. When it's no longer needed, the garbage collector will remove it. For 99% of applications out there, that's as much caching as you need.
A big problem with your example is that the items you've selected will stick around indefinitely. Think about the people who may work on this code later. Everyone may just start using $$('....') because they see it in a few spots and it does the same thing as $('....'). Suddenly you're storing thousands of DOM elements in memory for no reason at all.
Beyond that, if the DOM changes and you don't know about it changing, the code that you have in cache is useless.. but unless you're forcing it to reload then you'll end up continuing to get that cached code. Which of course introduces bugs. In order to prevent that from happening, you'd have to force reload the cache constantly, which pretty much negates the usefulness of it.
You're going to be better off just following good, solid programming patterns that are already out there.. rather than programming up a caching mechanism that is going to be a bug magnet.
I made your question into a jsperf, and I found that un-cached jQuery appears to run faster.
http://jsperf.com/jquery-cache-array-test
because of this I would recommend just using pure jQuery.
I think it's a bad idea. If you need to use a selection in several places the save the selection to a variable.
var mySelection = $(#myId).
it will be garbage collected when its no longer needed.

Contextualizing jQuery

I've got a fairly large site, with a lot of jQuery code for lots of different pages. We're talking about 1000 lines of fairly well optimized code (excluding plugins).
I know jQuery is fairly good at ignoring listeners for page elements that don't exist, but it still has to test their existence when the page loads. I'm also creating a load of vars (including decent sized arrays and objects), but only a few of them are used on each page.
My Question is: What's the best method of cutting down the amount of work each page has to do?
However, I do NOT want to split up the code into separate files. I want to keep all my code in 1 place and for the sake of efficiency I only want to call the server to download JS once (it's only 30kb, smaller than most images).
I've thought of several ways so far:
Put all my code chunks into named functions, and have each page call the functions it needs from inline <script> tags.
Have each page output a variable as the pageID, and for each chunk of have an if statement: if (pageID = 'about' || pageID = 'contact') {code...}
Give each page (maybe the body tag) a class or ID that can be used to identify the chunks that need executing: if ($('.about').length || $('.contact').length) {code...}
Combine 1 and 2 (or 1 and 3), so that each page outputs a variable, and the if statements are all together and call the functions: if (pageID = 'about') {function calls...}
Any other ideas? Or which is the best/most efficient of those?
Your first option will be fastest (by a minute margin).
You'll need to remember to call the functions from the correct pages.
However, don't bother.
Unless you've measured a performance impact in a profiler, there is no need to optimize this much.
I would argue that you are taking more of a performance hit for downloading the 30k then you will ever see from the code execution. That said, you could always test your url to determine the page and run all setup methods through a bootloader that determines the correct functions to run/ events to bind at load time. Something like the following maybe:
$(function(){
var page_methods = {
home : [meth_1, meth_2],
about : [meth_3, meth_2]
},
page = location.pathname.match(/\/(\w)$/)[1],
i = 0,
meth;
for ( ; meth = page_methods[ page ][ i++ ] ; ){
meth();
}
});

How to increase speed of getElementById() function on IE or give other solutions?

I have a project using Javascript parse json string and put data into div content.
In this case, all of itemname variables is the same div's id.
If variable i about 900, I run this code in Firefox 3 for <10ms, but it run on IE 7 for >9s, IE process this code slower 100 times than Firefox
I don't know what happen with IE ?
If I remove the line document.getElementById(itemname), speed of them seems the same.
The main problem arcording to me is document.getElementById() function?
Could you show me how to solve this prolem to increase this code on IE ?
Thank in advance.
var i = obj.items.length-2;
hnxmessageid = obj.items[i+1].v;
do{
itemname = obj.items[i].n;
itemvalue = obj.items[i].v;
document.getElementByid(itemname);
i--;
}while(i>=0);
Are you really noticing any latency?
gEBI is natively very very fast, I don't think you can avoid it anyway for what you're doing. Could you provide a low-down of what you're doing precisely? It looks like you're using a loop, but can you post exactly what you're doing inside of the loop, what your common goal of the script is?
document.getElementByid(itemname) is the fastest way to get a single element from the DOM in any real application you will sould not see any problems with using it, if you do see a problem you need to rethink you code a little it possible to acomplish any task with just a handfull of calls for this method. You can present you full problem if you like so I could show you an example
At least cache the reference to document:
var doc = document;
for(;;) {
doc.getElementById(..);
}

Categories

Resources