Best javascript questions in July 2012

Why does parseInt(1/0, 19) return 18?

486 votes

I've an annoying problem in JavaScript.

parseInt(1 / 0, 19)
18

Why does parseInt return 18?

The result of 1/0 is Infinity.

parseInt treats its first argument as a string which means first of all Infinity.toString() is called, producing the string "Infinity". So it works the same as if you asked it to convert "Infinity" in base 19 to decimal.

Here are the digits in base 19 along with their decimal values:

Base 19   Base 10 (decimal)
---------------------------
   0            0
   1            1
   2            2
   3            3
   4            4
   5            5
   6            6
   7            7
   8            8
   9            9
   a            10
   b            11
   c            12
   d            13
   e            14
   f            15
   g            16
   h            17
   i            18

What happens next is that parseInt scans the input "Infinity" to find which part of it can be parsed and stops after accepting the first I (because n is not a valid digit in base 19).

Therefore it behaves as if you called parseInt("I", 19), which converts to decimal 18 by the table above.

What are the best practices to follow when declaring an array in Javascript?

134 votes

When I need to declare a new array I use this notation

var arr = new Array();

But when testing online, for example on jsbin, a warning signals me to "Use the array literal notation []."

I didn't find a reason to avoid using the constructor. Is in some way less efficient than using []? Or is it bad practice?

Is there a good reason to use var arr = []; instead of var arr = new Array();?

Mostly, people use var a = [] because Douglas Crockford says so.

His reasons include the non-intuitive and inconsistent behaviour of new Array():

var a = new Array(5);     // an array pre-sized to 5 elements long
var b = new Array(5, 10); // an array with two elements in it

Note that there's no way with new Array() to create an array with just one pre-specified number element in it!

Using [] is actually more efficient, and safer too! It's possible to overwrite the Array constructor and make it do odd things, but you can't overwrite the behaviour of [].

Personally, I always use the [] syntax, and similarly always use {} syntax in place of new Object().

Why does "true" == true show false in JavaScript?

19 votes

MDC describes the == operator as follows:

If the two operands are not of the same type, JavaScript converts the operands then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers if possible; else if either operand is a string, the other operand is converted to a string if possible.

With this in mind, I would evaluate "true" == true as follows:

  1. Are they of the same type? No
  2. Is either operand a number or boolean? Yes
  3. Can we convert both to a number? No (isNaN(Number("true")) // true)
  4. Is either operand a string? Yes
  5. Can we convert the other operand to a string? Yes (String(true) === "true" // true)

I've ended up with the strings "true" and "true", which should evaluate to true, but JavaScript shows false.

What have I missed?

Because "true" is converted to NaN, while true is converted to 1. So they differ.

Like you reported, both are converted to numbers, because at least true can be (see Erik Reppen's comment), and then compared.

Managing text-maps in a 2D array on to be painted on HTML5 Canvas

17 votes

So, I'm making a HTML5 RPG just for fun. The map is a <canvas> (512px width, 352px height | 16 tiles across, 11 tiles top to bottom). I want to know if there's a more efficient way to paint the <canvas>.

Here's how I have it right now:

How tiles are loaded and painted on map

The map is being painted by tiles (32x32) using the Image() piece. The image files are loaded through a simple for loop and put into an array called tiles[] to be PAINTED on using drawImage().

First, we load the tiles...

enter image description here

and here's how it's being done:

// SET UP THE & DRAW THE MAP TILES
tiles = [];
var loadedImagesCount = 0;
for (x = 0; x <= NUM_OF_TILES; x++) {
  var imageObj = new Image(); // new instance for each image
  imageObj.src = "js/tiles/t" + x + ".png";
  imageObj.onload = function () {
    console.log("Added tile ... " + loadedImagesCount);
    loadedImagesCount++;
    if (loadedImagesCount == NUM_OF_TILES) {
      // Onces all tiles are loaded ...
      // We paint the map
      for (y = 0; y <= 15; y++) {
        for (x = 0; x <= 10; x++) {
          theX = x * 32;
          theY = y * 32;
          context.drawImage(tiles[5], theY, theX, 32, 32);
        }
      }
    }
  };
  tiles.push(imageObj);
}

Naturally, when a player starts a game it loads the map they last left off. But for here, it an all-grass map.

Right now, the maps use 2D arrays. Here's an example map.

[[4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 1, 1, 1, 1], 
[1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 13, 13, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 13, 13, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 13, 13, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 13, 13, 13, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 13, 11, 11, 11, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 1, 1, 1, 1, 1, 1, 1, 13, 13, 13, 13, 13, 1], 
[1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1]];

I get different maps using a simple if structure. Once the 2d array above is return, the corresponding number in each array will be painted according to Image() stored inside tile[]. Then drawImage() will occur and paint according to the x and y and times it by 32 to paint on the correct x-y coordinate.

How multiple map switching occurs

With my game, maps have five things to keep track of: currentID, leftID, rightID, upID, and bottomID.

  • currentID: The current ID of the map you are on.
  • leftID: What ID of currentID to load when you exit on the left of current map.
  • rightID: What ID of currentID to load when you exit on the right of current map.
  • downID: What ID of currentID to load when you exit on the bottom of current map.
  • upID: What ID of currentID to load when you exit on the top of current map.

Something to note: If either leftID, rightID, upID, or bottomID are NOT specific, that means they are a 0. That means they cannot leave that side of the map. It is merely an invisible blockade.

So, once a person exits a side of the map, depending on where they exited... for example if they exited on the bottom, bottomID will the number of the map to load and thus be painted on the map.

Here's a representational .GIF to help you better visualize:

enter image description here

As you can see, sooner or later, with many maps I will be dealing with many IDs. And that can possibly get a little confusing and hectic.

The obvious pros is that it load 176 tiles at a time, refresh a small 512x352 canvas, and handles one map at time. The con is that the MAP ids, when dealing with many maps, may get confusing at times.

My question

  • Is this an efficient way to store maps (given the usage of tiles), or is there a better way to handle maps?

I was thinking along the lines of a giant map. The map-size is big and it's all one 2D array. The viewport, however, is still 512x352 pixels.

Here's another .gif I made (for this question) to help visualize:

enter image description here

Sorry if you cannot understand my English. Please ask anything you have trouble understanding. Hopefully, I made it clear. Thanks.

Well there's a few things here so I'll respond to them in order.


...521 SEPARATE PNG FILES?

enter image description here

Use one. Just one. Maybe six, tops. Think about it, you're making every client do 500 GET requests just to get the tiles for the game? That's bonkers.

Almost every major site ever uses spritemaps to reduce requests. Youtube, for instance, uses this one image for all of its buttons:

enter image description here

You should do the same.


Your concept of using the canvas as a viewport is correct from a performance perspective. Definitely don't make it bigger than it needs to be!


As to your map performance question, giant arrays ought to be just fine to start. This is a fine way of dealing with it and I wouldn't bother exploring other options unless your word is very, very large. If it is massive, you could have "chunks" of the world that are 400x400 (or so) and when you come to the 400th row you start to use row 0 of the next array. The most arrays "in use" at any time will be four, of course, when your hero would be on a good old four corners sort of location.

Player location wouldn't be hard. If he was at tile 822, 20 that would mean he is in the chunk represented by (2, 0) (if we're starting from (0, 0)). Specifically, he'd be in tile 22, 20 of that chunk. No complex math, no ID's. There is no need to keep track of ID's. You don't even have to keep track of which chunk is the last chunk. You can just know that the total map size is (say) 1200x1200, and if he tries to move to (1201, 50), you don't even have to see if chunk (4, 0) exists. You know right away he can't move there, the map is only 1200 tiles wide!

Performance should be fine either way and will really depend on a large number of other things before you have to worry about this particular array. My advice is to worry about making the game before worrying about performance. Revisit performance once the game gets slow.

Once you get to performance, I would worry about everything except this issue first. In a canvas game its really unlikely to be the bottleneck. Reading from arrays is fast. Large arrays already in memory ought to be fast. There shouldn't be a problem, and I wouldn't spend time anticipating one until it actually presents itself.


EDIT: Example of viewport moving with player: http://jsfiddle.net/kmHZt/10/

15 votes

Arrays in JavaScript are very easy to modify by adding and removing items. It somewhat masks the fact that most languages array's are fixed-size, and require complex operations to resize. It seems that JavaScript makes it easy to write poorly performing array code. This leads to the question:

What performance (in terms of big O time complexity) can I expect from JavaScript implementations in regards to array performance?

I assume that all reasonable JavaScript implementations have at least the following big O's.

  • Access - O(1)
  • Appending - O(n)
  • Prepending - O(n)
  • Insertion - O(n)
  • Deletion - O(n)
  • Swapping - O(1)

JavaScript lets you pre-fill an array to a certain size, using new Array(length) syntax. (Bonus question: Is creating an array in this manner O(1) or O(n)) This is more like a conventional array, and if used as a pre-sized array, can allow O(1) appending. If circular buffer logic is added, you can achieve O(1) prepending. If a dynamically expanding array is used, O(log n) will be the average case for both of those.

Can I expect better performance for some things than my assumptions here? I don't expect anything is outlined in any specifications, but in practice it could be that all major implementations use optimized arrays behind the scenes. Are there dynamically expanding arrays or some other performance boosting algorithms at work?

P.S.

The reason I'm wondering this is because I'm researching some sorting algorithms, most of which seem to assume appending and deleting are O(1) operations when describing their overall big O.

In contrast to most languages, which implement arrays with, well, arrays, in Javascript Arrays are objects, and values are stored in a hashtable, just like regular object values. As such:

  • Access - O(1)
  • Appending - Amortized O(1) (sometimes resizing the hashtable is required; usually only insertion is required)
  • Prepending - O(n) via unshift, since it requires reassigning all the indexes
  • Insertion - Amortized O(1) if the value does not exist. O(n) if you want to shift existing values (Eg, using splice).
  • Deletion - Amortized O(1) to remove a value, O(n) if you want to reassign indices via splice.
  • Swapping - O(1)

In general, setting or unsetting any key in a dict is amortized O(1), and the same goes for arrays, regardless of what the index is. Any operation that requires renumbering existing values is O(n) simply because you have to update all the affected values.

HTML5/CSS3 - Custom Shape Div with google maps inside

14 votes

I need to make a custom shape div holding a "google maps" map. The custom border it's fine, I can handle it using a png, but the shape itself, I have only some theories of how to do it, but nothing in practice. But I think there is a way to do it using html5 canvas to make the custom shape on the div and use in css a overflow:hidden to hide what goes out of the div.

right now I have the following structure:

<html>
  <body>
    <div class="Orange_Background"></div>
    <div class="FX_Lines_over_background"></div>
    <div class="GoogleMaps_Container"></div>
  </body>
</html>

So as you can se I can't use the background as a png to only show the map, and because I need the map to be clickable.

Here is a image of what I was saying.

Teh Image

If anyone can help me, I'll be grateful !!

Thank you all.

PS: It can be with jquery too ! (if someone knows a plugin that do it.)

RE: Zee Tee's answer: If you do go this route, you can set pointer-events: none (in your css) for the div containing the images. this will send all mouse events to the layer below it. Sorry, I don't have the privilege to comment on answers yet :D

If you don't care about IE(6-8) support, then you can use CSS 3D transforms to do this directly on the map layer. But the map will look skewed, if that's the effect you are after, if not previous answer is still the best approach

Another solution is to use the mask image. sorry browser support sucks for this, but if you have a nice fallback until they catch up, you should be alright

https://developer.mozilla.org/en/CSS/-webkit-mask-image

Confused by behavior of `map` on arrays created using `new`

14 votes

I am confused by the results of mapping over an array created with new:

function returnsFourteen() {
    return 14;
}

var a = new Array(4);
> [undefined x 4] in Chrome, [, , , ,] in Firefox
a.map(returnsFourteen);
> [undefined x 4] in Chrome, [, , , ,] in Firefox

var b = [undefined, undefined, undefined, undefined];
> [undefined, undefined, undefined, undefined]
b.map(returnsFourteen);
> [14, 14, 14, 14]

I expected a.map(returnsFourteen) to return [14, 14, 14, 14] (the same as b.map(returnsFourteen), because according to the MDN page on arrays:

If the only argument passed to the Array constructor is an integer between 0 and 2**32-1 (inclusive), a new JavaScript array is created with that number of elements.

I interpret that to mean that a should have 4 elements.

What am I missing here?

When you create an array like so:

var arr1 = new Array( 4 );

you get an array that has a length of 4, but that has no elements. That's why map doesn't tranform the array - the array has no elements to be transformed.

On the other hand, if you do:

var arr2 = [ undefined, undefined, undefined, undefined ];

you get and array that also has a length of 4, but that does have 4 elements.

Notice the difference between having no elements, and having elements which values are undefined. Unfortunately, the property accessor expression will evaluate to the undefined value in both cases, so:

arr1[0] // undefined
arr2[0] // undefined

However, there is a way to differentiate these two arrays:

'0' in arr1 // false
'0' in arr2 // true

How can I show dots ("...") in a span with hidden overflow?

13 votes

my css

     #content_right_head span
    {
    display:inline-block;
    width:180px;
    overflow:hidden !important;
    }

now its showing content content

but i want to show like content content ...

I need to show dots after contents

Contents are coming dynamically from database

For this you can use text-overflow: ellipsis; property. Write like this

#content_right_head span{
    display:inline-block;
    width:180px;
    white-space: nowrap;
    overflow:hidden !important;
    text-overflow: ellipsis;
}

Check this http://jsfiddle.net/Y5vpb/

Optimize JavaScript CSS download

13 votes

I have a number of pages for my website all use jQuery and JSON and the same CSS, except for a few pages. The first page is user login. As the user will take time to type in his username and password, I want to download all the required JavaScript and CSS files for the entire user session during login. How can this be done? The header is the same for all pages. How do I optimize it?

My idea would be load in js and css files dynamically after document.load. This would not affect the load time of the login page, whilst also caching your js and css files once the user has logged in.

You could also easily change this to document.ready if it loads faster for you.

What about something like this?

$(document).load(function() {
    function preloadFile(filename, filetype){

        //For javascript files
        if (filetype=="js"){
            var fileref=document.createElement('script');
            fileref.setAttribute("type","text/javascript");
            fileref.setAttribute("src", filename);
        }

        //For CSS files
        else if (filetype=="css") {
            var fileref=document.createElement("link");
            fileref.setAttribute("rel", "stylesheet");
            fileref.setAttribute("type", "text/css");
            fileref.setAttribute("href", filename);
        }

        document.getElementsByTagName("head")[0].appendChild(fileref)
    }

    //Examples of how to use below
    preloadFile("myscript.js", "js"); 
    preloadFile("javascript.php", "js");
    preloadFile("mystyle.css", "css");
});

References

http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml

HTML Select padded with &nbsp; having issue in search

12 votes

I have an HTML select which has items like the below.

<SELECT id="mylist" size=5 >
   <OPTION Value="100">100</OPTION>
   <OPTION Value="200">200</OPTION>
   <OPTION Value="210">210</OPTION>
   <OPTION Value="211">211</OPTION>
</SELECT>

enter image description here

Now if I click inside the SELECT and type 21 then it will select the item 210 which is the first item starts with 21. All good.

Later I wanted to add a padding to the left of the item as requested by the client. But soon I realized that padding in SELECT will not work in IE (at least on IE6 and IE7 which I tested)

So I added &nbsp;&nbsp;

<SELECT id="mylist" size=5 >
   <OPTION Value="100">&nbsp;&nbsp;100</OPTION>
   <OPTION Value="200">&nbsp;&nbsp;200</OPTION>
   <OPTION Value="210">&nbsp;&nbsp;210</OPTION>
   <OPTION Value="211">&nbsp;&nbsp;211</OPTION>
</SELECT>

enter image description here

Now I can mimic padding.

But I lost the search option. It will not select 210 when I type 21 in IE. It works well in chrome. Please share your thoughts.

Find the sample here

How about wrapping it in a div:

HTML:

<div class="listwrapper">
    <SELECT id="mylist" size=5 >
        <OPTION Value="100">100</OPTION>
        <OPTION Value="200">200</OPTION>
        <OPTION Value="210">210</OPTION>
        <OPTION Value="211">211</OPTION>
    </SELECT>
</div>​

CSS:

.listwrapper
{
    padding: 0px 0px 0px 15px;
    border: solid 1px silver;
    width: 50px;
}
.listwrapper select,
.listwrapper select:active
{
    border: none 0px white;
    width: 50px;
}
​

My Fiddle

Tracking Users coming from a certain source

10 votes

I'm giving promotions to users who sends us other visitors. This is done on the client side.

I can do this using dynamic GET parameters, e.g. http://www.mysite.com?app_source=user_id or I can do this using the hash, e.g. http://www.mysite.com#app_source,user_id.

Are there any pros and cons for any of these methods?

Query String

  • Google Analytics, server logs, et al will have a record of the URL, which may be beneficial for later analysis.
  • Multiple URLs make caching harder and have a slight chance of confusing the Google

Hash

  • Analytics and server logs will not see/pay attention to hash params

The more semantic way of handling this is probably through a query string parameter, but it's not very strong. If none of the above-listed points is relevant, I would probably just stick with query strings because it is more common.

If you mean that you are building a service that other people integrate, and you don't want them to have to pass information back to their application (via query string), then using hash params seems like a solid option.

Getting the "match" object in a Custom Filter Selector in jQuery 1.8

10 votes

For reference, here's an article on Creating a Custom Filter Selector with jQuery.


Introduction:

For those not familiar with jQuery's Custom Filter Selectors, here's a quick primer on what they are:

If you need a reusable filter, you can extend jQuery’s selector expressions by adding your own functions to the jQuery.expr[':'] object.

The function will be run on each element in the current collection and should return true or false (much like filter). Three bits of information are passed to this function:

  1. The element in question

  2. The index of this element among the entire collection

  3. A match array returned from a regular expression match that contains important information for the more complex expressions.

Once you've extended jQuery.expr[':'], you can use it as a filter in your jQuery selector, much like you would use any of the built-in ones (:first, :last, :eq() etc.)


Here's an example where we'll filter for elements that have more than one class assigned to them:

jQuery.expr[':'].hasMultipleClasses = function(elem, index, match) {
    return elem.className.split(' ').length > 1;
};

$('div:hasMultipleClasses');

Here's the fiddle: http://jsfiddle.net/acTeJ/


In the example above, we have not used the match array being passed in to our function. Let's try a more complex example. Here we'll create a filter to match elements that have a higher tabindex than the number specified:

jQuery.expr[':'].tabindexAbove = function(elem, index, match) {
    return +elem.getAttribute('tabindex') > match[3];
};

$('input:tabindexAbove(4)');

Here's the fiddle: http://jsfiddle.net/YCsCm/

The reason this works is because the match array is the actual array returned from the regex that was used to parse the selector. So in our example, match would be the following array:

[":tabIndexAbove(4)", "tabIndexAbove", "", "4"]

As you can see, we can get to the value inside the parentheses by using match[3].


The Question:

In jQuery 1.8, the match array is no longer being passed in to the filter function. Since we have no access to the info being passed in, the tabindexAbove filter does not work anymore. The only difference between this fiddle and the one above, is that this uses a later version of jQuery.

So, here are several points I'd like clarified:

  1. Is this expected behavior? Is it documented anywhere?

  2. Does this have anything to do with the fact that Sizzle has been updated (even though it clearly states that "the old API for Sizzle was not changed in this rewrite". Maybe this is what they mean by "the removal of the now unnecessary Sizzle.filter")?

  3. Now that we have no access to the match array, is there any other way to get to the info being passed in to the filter (in our case, 4)?

I never found any documentation in the jQuery Docs about the custom filter selectors, so I don't know where to start looking for information about this.

By looking at the jQuery 1.8 beta2 source and the "Extensibility" section of the new sizzle, you have to set fn.sizzleFilter to true in order to get the pseudo argument and the context. If not, you'll just get all the elements in the arguments.

Here is the code that does the same thing as your example. Use the selector parameter passed in the function to get the pseudo argument.

Here is the working example on jsfiddle.

As mentioned in the blog post above, you can even pre-compile and cache the your selector.

var sizzle = jQuery.find;

var tabIndexAbove = function( selector, context, isXml ) {
    return function( elem ) {
        return elem.getAttribute("tabindex") > selector;
    };
};

/*
 fn.sizzleFilter is set to true to indicate that tabIndexAbove 
 is a function that will return a function for use by the compiler 
 and should be passed the pseudo argument, the context, and 
 whether or not the current context is xml. If this property is 
 not set, adding pseudos works similar to past versions of Sizzle
*/
tabIndexAbove.sizzleFilter = true;
sizzle.selectors.pseudos.tabIndexAbove = tabIndexAbove;

$('input:tabIndexAbove(4)').css('background', 'teal');

Just a note, if you're looking at the source, jQuery slightly changed the structure that the public-facing interface points to.

In jQuery 1.7.2:

jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.filters;

In jQuery 1.8b2:

jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.pseudos;

Advantage of *this* over event.target

9 votes

Is it better / faster inside an event listener to use this or event.target

I've been writing code like this (example is jQuery):

jQuery('input').bind('keyup', function (e) {
 var j = jQuery(e.target);
 foo(j.attr('id') , j.val() );
});

And I was told to replace e.target with this because it's "better". Is there really any advantage to one or the other?

I use target because it's a more general solution as it works for delegated events. I'm having trouble benchmarking because my tests get cluttered with the binding (Although, obviously, in this case the difference would be too small to matter anyway)

The one isn't better than the other, but they do different things: this refers to the element the event is attached to, while event.target is the element that invoked the event.

For example

div id=foo   
   div id=bar

when click is attached to foo, and bar is clicked, the event will bubble up to foo. In the event this will refer to foo and event.target to bar

In the end it depends on which element you need to handle.

There's a small example on api.jquery.com/event.target that illustrates event.target. Here's a small sample that uses that example, but which also displays this: http://jsbin.com/adifan/edit#javascript,html,live

jQuery's .css() implementation

9 votes

I was looking through the jQuery code and found this line:

elem.runtimeStyle.left = elem.currentStyle.left;

at

https://github.com/jquery/jquery/blob/449e099b97d823ed0252d8821880bc0e471701ea/src/css.js#L169

I am not sure why this is done. Isn't this useless?

Setting the runtimeStyle to the currentStyle would override nothing. Except make the runtimeStyle readable the next time you read it - which doesn't seem needed now.

I understand the overall concept here and why that code block exists (to convert numeric non-pixel values to the appropriate pixel value, by setting the left to the non-pixel value and reading its pixel value and then reverting the left back to the original value).

Edit See my answer below for why I think this is done (with jsFiddle illustration!).

I have been thinking about this. Here is why I believe it is done:

Setting the runtimeStyle to the currentStyle ensures that this is style that is applied on the element (the runtime style wins over the inline style). So when you set elem.style.left in the next line, there would be no change in the UI. However, the new pixel value can still be calculated using elem.style.pixelLeft - because this just converts the non-pixel value on the CSS to a pixel value. pixelLeft is not a measurement of the actual position, it is just a conversion to the pixel value.

See this: http://jsfiddle.net/RaSzc/

So this is done to figure out the pixel value without having anything change in the UI

Why is "element.innerHTML+=" bad code?

9 votes

I have been told not to append stuff using element.innerHTML += ... like this:

var str = "<div>hello world</div>";
var elm = document.getElementById("targetID");

elm.innerHTML += str; //not a good idea?

What is wrong with it?, what other alternatives do I have?

Every time innerHTML is set, the HTML has to be parsed, a DOM constructed, and inserted into the document. This takes time.

For example, if elm.innerHTML has thousands of divs, tables, lists, images, etc, then calling .innerHTML += ... is going to cause the parser to re-parse all that stuff over again. This could also break references to already constructed DOM elements and cause other chaos. In reality, all you want to do is append a single new element to the end.

It's better to just call appendChild:

var newElement = document.createElement('p');
newElement.innerHTML = '<div>Hello World!</div>';
elm.appendChild(newElement);​​​​​​​​​​​​​​​​

This way, the existing contents of elm are not parsed again.

NOTE: It's possible that [some] browsers are smart enough to optimize the += operator and not re-parse the existing contents. I have not researched this.

jQuery list of data

9 votes

Hey guys and girls :)

I've been battling this problem for a few hours and I thought I'd rather ask you for help than hammering my face into my desk repeatedly.

Need:

I have a series of editable lists which, on a press of a button should be transformed into some sort of data structure. When it has been turned into some sort of data I need to add duplicates together.

example:

  • 200g banana
  • 100g apple
  • 200g apple

Should be turned into a data list of some sort and should in the end look like this:

  • 200g banana
  • 300g apple

Hey I just met you, and this is crazy, but here's my code, so help me maybe?

//button click event
$(".calculate").bind("click", function(e)
{
    //get the correct parent of the button
    var parent = $(this).closest("#calc");

    //get relevant data
    parent.find(".options").each(function(index, element)
    {
        var opt1 = $(this).children(".opt1").children("input").val(); //weight
        var opt2 = $(this).children(".opt2").children("input").val(); //ingredient
    });
});

Basically I click the button and the above script finds all the relevant data. I cannot however for the life of me turn this into a multidimensional array or a list of objects I can search for duplicates in.

When I try to make a dynamic object it seems to fail and when I make a multidimensional array to search in I get blocked by inArray's inability to search through them.

Problem recap: I am able to get the user data no problem. Turning it into a list and adding together duplicates is the problem.

I will suggest you to have a global object that will contain the summary, this will look like this:

$(".calculate").bind("click", function(e)
{
    var fruits = {};

    //get the correct parent of the button
    var parent = $(this).closest("#calc");

    //get relevant data
    parent.find(".options").each(function(index, element)
    {
        var opt1 = $(this).children(".opt1").children("input").val(); //weight
        var opt2 = $(this).children(".opt2").children("input").val(); //ingredient

        // here is my code
        if(fruits[opt2] == undefined) {
            fruits[opt2] = opt1;
        } else {
            // assuming that opt1 is an integer
            fruits[opt2] += opt1;
        }
    });

    // use fruits variable here
});

Open a window behind the current window using Javascript/jQuery

8 votes

I want to open a window on click, but I want to open it behind the current window, or when the new window opens it should minimize itself. I have made a function but it actually did not work.

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript">
function wn(){
  var mm=window.open('http://www.google.com','newwindow','width=200, height=200', "_blank");
}
</script>
</head>
<body>
<a href="#" onclick="wn()">click</a>
</body>

EDIT

Parent window HTML

<script language="JavaScript" type="text/javascript">
function openPopUP() {
  window.open('mywindow.html','NewWin',
            'toolbar=no,status=no,width=350,height=135')
}
</script>

<body onLoad="openPopUP();">
or
<a href="javascript:openPopUP();">Click to open popup</a>

Child Winow i.e PopUp Window File

put the script in child window child window ill be get hide after 1 second if you wnat more time than change 1000 to 5000 or more

<body onLoad="setTimeout('window.blur()', 1000);" 
          onFocus="setTimeout('window.blur()', 1000);">

Try out this might work for you , write this line of code in the onload event of your child window...

window.parent.opener.focus(); 

shiftKey in Safari on iOS

8 votes

Is there any way to determine in javascript whether shift key is pressed on mobile keyboard, and distinguish it from the caps lock(twice pressed shift key)

Some Facts

First, let's look at some facts about iOS keyboards I assume you already know:

  • When you enter the keyboard mode, the shift key is always activated
  • Caps Lock must be activated manually (I guess this is not used too widely)

iPhone Shift Key Handling

I investigated a bit into this issue, and here's what I found:

  • The shift Key triggers no key Event

  • There is no special iPhone Browser API to detect whether the shift key is pressed or not, except in an iOS App (duh)

  • The keydown, keypress, keyup event triggered by iOS look normal, except they do not indicate shiftKey usage, and apart from their timestamp and type cannot be distinguished.

  • You cannot manually dispatch a Keyboard Event in iOS because of this issue, keyCode and which are readonly and always set to 0. Retriggering a Keyboard event to get some indication about the shift key still being on is impossible.

  • Actually, The iPhone treats the shift key like some sort of Short Term Caps Lock key. The difference is that normally, you activate it once, and it deactivates automatically.

What can be done

I assume you want to indicate on an input field whether the user should be careful about having Shift/Caps Lock pressed (a password field, for example). What I came up with is some sort of a workaround, but I think it's better than nothing.

You can also test the jsfiddle here.

DOM Setup

<div id="wrapper">
  <label for="test">ENTER SOMETHING HERE</label>
  <input type="text" name="test" id="test"/>
</div>
<div id="warning"></div>​

Javascript

This checks wheter the user did enter capitalized input, and it assumes the user is using caps lock if two capitalized letters where entered.

var isCaps = false,
isUppercase = false,
str = '',
test = document.getElementById('test'),
warning = document.getElementById('warning');

function capsDetection(e) {

    // Since where on iOS, we at least don't have to care 
    // about cross-browser stuff
    var s = String.fromCharCode(e.which);
    isCaps = isUppercase;

    // if the char doesn't match its lower case friend, and the shift key is 
    // not pressed (which is always the case on iOS, but we leave it there 
    // for readability), we have uppercase input
    isUppercase = (s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey);

    // if its the second uppercase input in a row, we may have caps lock input
    isCaps = isCaps && isUppercase;

    // set the warning
    if (isUppercase && !isCaps) {
        str = 'You where using the shift key';
    }
    else if (isCaps) {
        str = 'Caps lock seems to be activated';
    } else {
        str = '';
    }
    warning.innerHTML = str;
}

// the right event properties are only available on keypress
test.addEventListener('keypress', capsDetection);

As I said, better than nothing, but not a solution if you need to know the shift key is pressed without the user doing any input. That seems to be impossible right now.

Implemenitng Infinite Scrolling with jquery

8 votes

I am working on a project that uses the jQuery Masonry and Infinite Scroll plugins to load "n" amount of pictures from instagram using their API. Looking at this short example my understanding is that I need to have before hand the html pages to be rendered:

<nav id="page-nav">
  <a href="pages/2.html"></a>
</nav>

The problem is, I dont really know how many pictures will be retrieved. Here is for example how I retrieve 20 pics at a time.

    $(document).ready(function(){       
        var access_token = location.hash.split('=')[1];

        if (location.hash) {

              $.ajax({
            type: "GET",
            dataType: "jsonp",
            cache: false,
            url: "https://api.instagram.com/v1/users/MY_USER_ID/media/recent/?access_token=MY_ACCESS_TOKEN",
            success: function(data) {

                for (var i = 0; i < 20; i++) {
            $("#instafeed").append("<div class='instaframe'><a target='_blank' href='" + data.data[i].link +"'><img src='" + data.data[i].images.standard_resolution.url +"' /></a></div>");   
                }     

            }
        });


        } else {
        location.href="https://instagram.com/oauth/authorize/?display=touch&client_id=MY_CLIENT_ID&redirect_uri=MY_URI"; 

        }

    });

I guess I will need a pagination mechanism but based on the tutorial mentioned above I believe I will first need to pre-define the html pages to be loaded. So now here my questions

  1. Does that mean this plugin (Infinite Scroll) requires to have "n" amount of html files in a directory to achieve infinite scrolling?
  2. Is it possible to implement infinite scrolling with the same plugin if I dont know how many pages I will have. Even better without even having to create physical html files?
  3. How can this kind of pagination is implemented? (i.e loading chunks of 20 pics as long as the user keeps scrolling down) there is not that much documentation online, could you provide a short step through demo or description?

With kind regards

1) Does that mean this plugin (Infinite Scroll) requires to have "n" amount of html files

Absolutely not. You do not need to generate static html pages beforehand, The only think you need is a URL scheme where subsequent page content can be fetched by changing one number in URL.

Think of it from the perspective of the infinite scroll plugin. You load the plugin JavaScript in your page #1 and provide link to page#2 inside page #1. Now when the user scrolls past page#1, the only variable that the plugin has is the current page number, like, 2, or 3 or 4 (N)

The plugin needs to create the URL to fetch content from when user is scrolling. So how does the plugin do that? The plugin looks at the next URL structure provided in page#1, parses it and creates a "base path" to which it will keep adding current_page_number to fetch subsequent content. That is the role of NAV selector.

So let's say I have something like /home/page/2 as next URL in page#1. The plugin will parse this into an array as

[/home/page/,2]

and think that base_path = "/home/page/"

when the plugin attempts to fetch page_number 3, it will just append 3 to the base path, like base_path.join(current_page_num) making it /home/page/3

On server side I can just have a controller that takes care of all the /home/page/1 to /home/page/N links. You can just look inside the plugin, look for _determinePath and retrieve functions.

Now you can see the problem as well. The problem is that there can be an infinite variety of URL structure depending on how you are doing pagination inside your code and how many variables do you need. My way of doing pagination is different from your way of doing pagination. Same holds for frameworks. Drupal pagination scheme may be different from Djanga and wordpress etc.

The plugin cannot possibly cope with all these URL structures. Given a next URL, it cannot possible always deduce the "base path" to which it needs to add current_page_number. Again look at _determinePath() method of plugin to see what kind of URL it can cope with. It can parse simple URL structures, like page2.html or page=2 but you have to provide your own implementation if your URL structure is complicated or something that the plugin cannot handle. Look at pathParse() method as well.

2)Is it possible to implement infinite scrolling with the same plugin if I dont know how many pages I will have.

Again, there is no need to create HTML files. You have two options to signal end of content (without knowing how many pictures you have in advance)

  • When you have reached the "no content condition" you can return an HTTP 404.
  • Or you can return an empty string.

Does this answer the question?

How it can work with the plugin

  • First page - include - NAV SELECTOR - LOAD THNIGS THE USUAL WAY
  • First page on load - use instagram pagination and store "nextURL" in your javascript somewhere
  • On Scroll - override _determinePath to provide your own fetch URL using (2) - let plugin retrieve that URL
  • Override plugin content selector - so it returns new elements to callback
  • On Plugin fetch content - Use the callback inside plugin to update your page

Why is using "javascript: <code>" bad?

8 votes

Possible Duplicate:
Do you ever need to specify javascript: in an onclick?

To execute JavaScript on a DOM event, you could use something like this:

<div onclick="alert('Alert');">Alert</div>​

Something like this seems to work as well:

<div onclick="javascript: alert('Alert');">Alert</div>​

However, I've heard that the second example is "bad" and that the first example should be used over the second.

Is this bad? If so, why is this bad? What is the difference between alert('Alert') and javascript: alert('Alert')?

What about using it in <a> tags (if it is any different)?

<a href="javascript: alert('Alert');">Alert</a>

Edit: To clarify, I am asking about the javascript: part specifically, and not how I have inline JavaScript mixed in with my markup. Sorry about the confusion.

Oh the wonderful confusing world of JavaScript. The code you posted probably doesn't do what most programmers think it's doing.

There is a difference between each of the following lines:

<a onclick="alert('Hello World!')"...>example</a> //V1
<a href="javascript: alert('Hello World!')"...>example</a> //V2
<a onclick="javascript: alert('Hello World')"...>example</a> //V3

although they all will alert Hello World!.

The first (V1) has an inline click event bound via the [onclick] attribute. It may also contain an [href] attribute that navigates to another location after the [onclick] attribute has executed, or any number of other click events bound in the code, assuming the default behavior hasn't been prevented.

The second (V2) has an executable javascript: url set as the [href] attribute. It might also contain an [onclick] attribute or other click events bound in external scripts.

The first and second examples (V1 & V2) have identical code executed, which is:

alert('Hello World!')

The third example (V3) has an inline click event bound via the [onclick] attribute, just like V1, however the code being executed is different. The executed code is:

javascript: alert('Hello World')

Although it looks like a javascript: url, it's actually just using a label in javascript.

Labels in JavaScript are useful for skipping out of nested loops, as in the following example code:

label: for (i = 0; i < 5; i++) { //labeled line
    for (j = 0; j < 5; j++) {
        console.log(i, j);
        if (i === 2 && j === 3) {
            break label; //this jumps out of both for loops
        }
    }
}

In most inline JavaScript, it's misused because the author doesn't understand the difference between the three formats.


Why is using javascript: <code> bad?

That's a leading question. It assumes that using javascript: <code> is bad.

javascript: <code> isn't bad. It's a tool. Tools aren't inherently good or bad, only the people using the tools are. You wouldn't call a hammer "bad", even if someone used it as a weapon.

javascript: <code> has some nice uses. You shouldn't use it for most cases because it's the wrong tool for the job, however if you're writing a bookmarklet, you'd be required to use the javascript: <code> format.

Additionally, there are a few niche contexts where it could make sense to leave javascript inline. An example of this would be to add a simple print button to the page:

<a href="#" onclick="window.print(); return false">Print</a>

Although even this example could be easily replaced by a class and externalizing the javascript:

<a href="#" class="print">Print</a>
<script>
     //jQuery used for brevity
     $(document).on('click', '.print', function () {
         window.print();
         return false;
     });
</script>