Unwanted Event Override - javascript

Here is my code (simplified):
function FillTable ( oProfile_data ) {
var oTable = document.getElementById ( "table" );
for ( var key in oProfile_data ) {
var oRow = oTable.insertRow ( oTable.rows.length );
var oCell = oRow.insertCell ( 0 );
var oLink = document.createElement ( "a" );
oLink.href = "javascript:void(0)";
oLink.innerHTML = "Visit Homepage";
oLink.addEventListener ( "click",
function () {
var win = window.open ( oProfile_data [key]["url"], "_blank" );
win.focus();
}, false );
oCell.appendChild ( oLink );
}
}
The problem is that every row has a link to the same document and I can't figure out why!
My temporary solution is:
oLink.href = "javascript:void(0); var win = window.open ( \"" + oProfile_data [key]["url"] + "\", \"_blank\" ); win.focus();";
Which works fine.
I suppose it is an event overriding problem but I may be wrong.
Any help would be really appreciated!

This is a problem that can be solved through an understanding of closures. Your anonymous function (bound to the click event) doesn't get called until the user clicks on the link, and when this line gets executed:
var win = window.open ( oProfile_data [key]["url"], "_blank" );
The value of key will be enclosed by the FillTable function. So, it will retain the value that it had when the function ended (ie, the last value it held in the loop).
You'll have to create a new closure for each iteration of the loop. Something like:
oLink.addEventListener ("click",
(function (k) {
return function () {
var win = window.open ( oProfile_data [k]["url"], "_blank" );
win.focus();
}
}
)(key), false);
Above, we create a function that returns a function that opens your window. Then, we pass the value of key into that function, thus creating a new closure.

Related

TypeError: morphSearch.querySelector(...) is null

Can anyone resolve my problem with my code ( i just discovered it from debug mode )
<script type="text/javascript">
(function() {
var morphSearch = document.getElementById( 'morphsearch' ),
input = morphSearch.querySelector( 'input.morphsearch-input' ),
ctrlClose = morphSearch.querySelector( 'span.morphsearch-close'),
// ...
</script>
This is not all of the code that I have, it's long so I just put the first lines of it.
In debug mode I get this error :
TypeError: morphSearch.querySelector(...) is null
Here is the generated markup: http://pastebin.com/P6tfvcZS
Is there a solution for this issue ?
found this...
var offsets = morphsearch.getBoundingClientRect();
morphSearch is the wrong case, I'm thinking it should be...
var offsets = morphSearch.getBoundingClientRect();
I also separated your var statements. The last one looked like this...
isOpen = isAnimating = false,
I don't think that's valid, try it like this.
var morphSearch = document.getElementById( 'morphsearch' );
var input = morphSearch.querySelector( 'input.morphsearch-input' );
var ctrlClose = morphSearch.querySelector( 'span.morphsearch-close' );
var isOpen = false;
var isAnimating = false;
Those querySelector's appear to be working...
Actually, a side from the above, I think I found the only querySelector that wasn't working.
Try changing this...
morphSearch.querySelector( 'button[type="submit"]' ).addEventListener( 'click', function(ev) { ev.preventDefault(); } );
To...
morphSearch.querySelector( 'input.morphsearch-submit' ).addEventListener( 'click', function(ev) { ev.preventDefault(); } );
All that should do it.

removeEventListener not working

Adds listener
for ( i = 0; i < kbButtons.length; i++ ) {
kbButtons[i].addEventListener("click", function() { clickKbButton( this ); }, false);
}
Should remove listener
function clickKbButton ( elem ) {
elem.removeEventListener("click", function() { clickKbButton( this ); }, false);
elem.id = "invis"
}
Everything is working fine, no errors in console, button click works but it's not being removed after I click it
As per documentation, my guess is that event handler should reference the same function:
for ( i = 0; i < kbButtons.length; i++ ) {
kbButtons[i].addEventListener("click", clickKbButton, false);
}
function clickKbButton ( ev ) {
this.removeEventListener("click", clickKbButton, false);
this.id = "invis"
}
Simple fiddle example
I guess you should use a variable reference to the function() { clickKbButton(this); }, the two functions in your addEventListener & removeEventListener are actually two different functions.
var handler = function() { clickKbButton(this) };
then use this handler variable when you add & remove listener.

Why am I getting TypeError: obj.addEventListener is not a function?

Here's my code:
function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
obj.attachEvent( 'on'+type, obj[type+fn] );
} else
obj.addEventListener(type, fn, false);
}
function alertWinner(){
alert("You may be a winner!");
}
function showWinner (){
var aTag = document.getElementsByTagName("a");
addEvent(aTag, 'click', alertWinner);
}
showWinner();
Basically, I'm working in the firebug console and trying to get an alert to pop up when any a tag is clicked.
I can't see the problem that results in this not working and giving me the error stated in my questions title (viewed in firebug). Anybody?
document.getElementsByTagName returns a NodeList of DOM elements. Each element has an addEventListener function, but the array doesn't have one.
Loop over it:
function showWinner (){
var aTags = document.getElementsByTagName("a");
for (var i=0;i<aTags.length;i++){
addEvent(aTags[i], 'click', alertWinner);
}
}
aTag is an instance of DOMNodeList, not from DOMElement.
You could do this instead:
var aTags = document.getElementsByTagName("a");
var aTag = aTags[0];
But obviously this approach presents a flaw, in that there might be more than one a element returned. You should use a different selector that returns only one element, if possible.
Not sure why, but I got addEvent is not defined in Firefox. I couldn't even find addEvent() on MDN. I had to use this:
function showWinner (){
var aTags = document.getElementsByTagName("a");
for (var i=0;i<aTags.length;i++){
// addEvent(aTags[i], 'click', alertWinner);
aTags[i].addEventListener("click", alertWinner);
}
}

cannot debug onmouseover event

/* this is our script for monopoly_first_page.html */
var result;
var button;
var image;
var x = 0;
function animation( animatedObject ){
var hereObject = animatedObject;
alert( hereObject );
/*setInterval( animate( animatedObject, x ), 100 );*/
}
function animate( hereObject, x ){
alert( x );
if( x == 0){
hereObject.style.width++;
}
else{
hereObject.style.width--;
}
if( hereObject.style.width <= 225 ){
x = 0;
}
if( hereObject.style.width >= 300 ){
x = 1;
}
}
function disanimation( animatedObject ){
var hereObject = animatedObject;
clearInterval();
}
window.onload = init;
function init(){
result = document.getElementById( "result" );
button = document.getElementById( "button-container" );
document.getElementById( "button-container" ).onmouseclick = animation( button );
document.getElementById( "button-container" ).onmouseout = disanimation( button );
alert( button );
alert( button );
}
hi every one...this is one of my source code and im a beginner...i faced a problem and it is where i wrote this statement:
document.getElementById( "button-container" ).onmouseclick = animation( button );
when function init begins to run function animation also execetues... but im sure im not rolling my mouse over the specified DIV...
what is the problem?
You need to pass a function to any handlers. What is happening with your code is that it calls animation(button) then sets that value to the onmouseclick property. Since the animation(...) function doesn't return a function, nothing beneficial will happen.
This would be a lot closer.
whatever.onmouseclick = animation;
If you need to, you could also do this: (assuming you want a specific button passed)
whatever.onmouseclick = function(e) { animation(button); }
just wanted to add to john, you can also do
document.getElementById( "button-container" ).addEventListener("click",function(){animation(button);},true);
insetead of "onmouseclick"
:-)
As #JohnFisher already mentioned, you assign the RESULT of your function to the event
However I only ever use onclick. Where did you get onmouseclick from?
Also you repeat your getElementById unnecessarily and have an init that is an onload so consolidate it:
window.onload = function() {
var button = document.getElementById( "button-container" );
// button is not necessarily known or the same at the time of the click so use (this)
button.onclick = function() { animation(this); }
button.onmouseout = function() { disanimation(this); }
}

javascript function not running

I have the script below placed in the HEAD of the page. The map should initialize when the page loads. There's two pieces to this puzzle, one is the script within the document.ready which sets all variables and configures the map i am wanting to place on a page. The second piece is the window.onload=initialize_map; that starts the map.
I believe everything is running correctly, however, i don't know for sure. All i know is that the initialize_map function never runs. I even tried to set an onclick on a button with initialize_map(); to try and manually start the map and it still didn't work. Is there something wrong with my code? Any help is greatly appreciated.
Thanks!
CODE IN QUESTION:
<script src= "http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAhTrgZ5jvdqcEQouEpPcZ_hS81NmJwGXlxuJr8lEEo4Njw3WRVhT8auzZb55JSMDkwIaCdNkPHL5gNg" type="text/javascript"> </script>
<script type="text/javascript">
$(document).ready(function(){
var dealerName = $('.name', '.adr').text();
var customerName = dealerName.slice(0, - 1);
var customerAddress = $('.street', '.adr').text() + ', ' + $('.locality', '.adr').text() + ', ' + $('.state', '.adr').text() + ', ' + $('.zipCode', '.adr').text();
$("#nameAddress .placeholderName").html(customerName);
$("#nameAddress .placeholderAddress").html(customerAddress);
var error_address_empty = 'Please enter a valid address first.';
var error_invalid_address = 'This address is invalid. Make sure to enter your street number and city as well?';
var error_google_error = 'There was a problem processing your request, please try again.';
var error_no_map_info = 'Sorry! Map information is not available for this address.';
var default_address = customerAddress;
var current_address = null;
var map = null;
var geocoder = null;
var gdir = null;
var map_compatible = false;
if( GBrowserIsCompatible() ) {
map_compatible = true;
}
function initialize_map() {
if( map_compatible ) {
map = new GMap2(document.getElementById('map_canvas'));
geocoder = new GClientGeocoder();
show_address(default_address);
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
}
}
function show_address(address) {
if( map_compatible && geocoder ) {
current_address = address;
geocoder.getLatLng(
address,
function( point ) {
if( !point ) {
alert(error_no_map_info);
} else {
map.setCenter(point, 13);
var marker = new GMarker(point);
map.addOverlay(marker);
marker.openInfoWindowHtml("<span style='font-size:14px; font-weight:bold;'>" + customerName + "<br /></span><span style='font-size:12px;'>" + address + "</span>");
}
}
);
}
return false;
}
function get_directions() {
if( map_compatible ) {
if( document.direction_form.from_address.value == '' ) {
alert(error_address_empty);
return false;
}
document.getElementById('directions').innerHTML = '';
gdir = new GDirections(map, document.getElementById('directions'));
GEvent.addListener(gdir, 'error', handleErrors);
set_directions(document.direction_form.from_address.value, current_address);
}
return false;
}
function set_directions(fromAddress, toAddress) {
gdir.load("from: " + fromAddress + " to: " + toAddress,
{ "locale": "en" });
}
function handleErrors(){
if( gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS )
alert(error_invalid_address);
else if( gdir.getStatus().code == G_GEO_SERVER_ERROR )
alert(error_google_error);
else if( gdir.getStatus().code == G_GEO_MISSING_QUERY )
alert(error_address_empty);
else
alert(error_invalid_address);
}
});
window.onload=initialize_map;
</script>
Two problems jump out right away:
initialize_map is not in the global scope (it's defined within the anonymous ready event handler), so you're likely assigning an undefined value to window.onload, as you've placed the assignment itself outside of that function (in the global scope).
Why are you mixing jQuery's ready handler with window.onload? At worst, this is flat-out not going to work - from the jQuery documentation:
The .ready() method is generally incompatible with the attribute. If load must be used, either do not use .ready() or use jQuery's .load() method to attach load event handlers to the window or to more specific items, like images.
...and even at best, it's unnecessary. Use jQuery for both or neither:
$(document).ready(function(){
...
$(window).load(initialize_map);
...
});
The entire body of your function is in an if statement that depends on the boolean variable map_compatible being true. Are you sure that it is true?
Try putting an alert before the if statement and see if it runs that way. Maybe print out the value of map_compatible.
If it is not true then you can use a tool like firebug for firefox to step through your javascript and see why it is not being set to true as you expect it to.

Categories

Resources