FireFox Javascript event handling - javascript

I have the following function that works in Chrome/IE:
for(var i = 0; i < 5; ++i) {
document.all["elems" + i].onscroll = getFunc("onScrollAdj(document.all['tb" + i + "']);");
}
function getFunc(jsString) {
return new Function(jsString);
}
However I get the error:
ReferenceError: event is undefined.
I have tried to re-write the function to include an event however I then get another error:
var i is undefined.
document.all["elems" + i].onscroll = onScrollAdj(event, document.all['tb" + i + "');
Is there any way to ensure both event and attributes can be passed?

however I get 'ReferenceError: event' is undefined.
That's because you're trying to use event without declaring it as an argument. That only works on Microsoft browsers, which make event a global, and Chrome which throws a bone to Microsoft-only code. You will need to declare the argument.
There's no need for new Function virtually ever, and certainly not in this case:
for(var i = 0; i < 5; ++i) {
document.all["elems" + i].onscroll = getFunc(i);
// ------------------------------------------^
}
function getFunc(i) {
// --------------^
return function(event) { onScrollAdj(event, document.all['tb' + i]); };
// -------------^--------------------^
}
Note that you'll have to ensure that onScrollAdj accepts event:
function onScrollAdj(event, tbThingy) {
// ------------------^

Related

eventListener is not triggering

I have the following code:
function expandTextarea () {
var textareas = document.getElementsByTagName('textarea');
for (var i = 0; i < textareas.length; i++) {
if (textareas[i].scrollHeight > 100) {
textareas[i].style.height = textareas[i].scrollHeight + 2 + 'px';
} else {
textareas[i].style.height = '100px !important';
}
textareas[i].addEventListener('onchange', adjustTextareaHeight(this));
// textareas[i].addEventListener('keyup', adjustTextareaHeight(textareas[i]));
// textareas[i].addEventListener('paste', adjustTextareaHeight(textareas[i]));
// textareas[i].addEventListener('cut', adjustTextareaHeight(textareas[i]));
}
}
function adjustTextareaHeight (textarea) {
console.log(textarea.length);
if (textarea.length > 0) {
textarea.style.height = textarea.scrollHeight + 2 + 'px';
}
}
For some reason the event listener is never fired. Note that expandTextarea is called from my window.onload = function () {} function.
When I call expandTextarea directly it runs without any issues but when I make a change, pressing enter a bunch, it never calls the onchange event.
You have to pass a function to addEventListener. Currently you are passing undefined, the return value of adjustTextareaHeight. So the browser doesn't know what to execute when the event occurs.
What you want is:
textareas[i].addEventListener('change', function() {
adjustTextareaHeight(this);
});
In your code you are calling adjustTextareaHeight immediately (not on change). this likely refers to the global object (window) and window.length is undefined, which is not > 0.

Convert Onclick to addEventListener

for(var i=1;i<=s;i++){if(e[r]<0&&n<=0)
{n=Math.abs(e[r])-1;r++}
else if(n>0){n--}else{t=e[r];r++}
var o=document.createElement("div");
o.style.height=t+"px";o.className="thumbnail";
o.id="thumb"+i;
o.setAttribute("onclick","Viewer.goToPage("+i+");");
I'm trying to convert onclick into addEventListener due to CSP restrictions in Firefox OS but not getting success.
for (var i = 1; i <= s; i++) {
if (e[r] < 0 && n <= 0) {
n = Math.abs(e[r]) - 1;
r++
} else if (n > 0) {
n--
} else {
t = e[r];
r++
}
var o = document.createElement("div");
o.style.height = t + "px";
o.className = "thumbnail";
o.id = "thumb" + i;
(function(j, elem) {
elem.addEventListener('click', function() {
Viewer.goToPage(j);
}, false);
}(i, o));
}
You'll have to capture the value of the iterator in an IIFE to make it persist in the callback for addEventListener
You can use addEventListener for this, however I don't see any benefit over direct property assignment (based on adeneo's code):
o.onclick = (function(pageNum) {
return function() {
Viewer.goToPage(pageNum);
};
}(i));
// Presumably o is added to the document before the next iteration
One benefit of this approach is that you can remove the listener later by assigning a new value to the element's onclick property, or add additional listeners using addEventListener (or equivalent).
If addEventListener is used to add an "anonymous" function, there's no easy way to remove it later.
And it's good to avoid setAttribute for attaching handlers as it's inconsistent across browsers. Directly setting the property is supported by every browser back to IE and NN version 3 or earlier.

shiny.js - method not called

I've implemented a javascript-file that, show a loading screen while the shiny is busy. It didn't worked so I've debugged it and I've found that the function
addMessageHandler('progress', function(message) {
$(document.documentElement).addClass('shiny-busy');
for (var i = 0; i < message.length; i++) {
var key = message[i];
var binding = this.$bindings[key];
if (binding && binding.showProgress) {
binding.showProgress(true);
}
}
});
is never called. But the function that removes the class("shiny-busy") it's always called.
The problem seems to be here:
// A function for sending messages to the appropriate handlers.
// - msgObj: the object containing messages, with format {msgObj.foo, msObj.bar
this._sendMessagesToHandlers = function(msgObj, handlers, handlerOrder) {
// Dispatch messages to handlers, if handler is present
for (var i = 0; i < handlerOrder.length; i++) {
var msgType = handlerOrder[i];
if (msgObj[msgType]) { //when msgType = "progress", the if is false and so the function for addClass("shiny-busy") it's not called
// Execute each handler with 'this' referring to the present value of
// 'this'
handlers[msgType].call(this, msgObj[msgType]);
}
}
};
How can/should I solve the problem?
Thank you!
EDIT: PROBLEM SOLVED!

java script last iteration set the value for all iterations

var myElements = document.getElementsByName('bb1');
for (var i = 0; i < myElements.length; i++) {
var curValue = myElements[i].getAttribute('innerId')
myElements[i].addEventListener('mouseover', function () {
alert('Hello i am : ' + curValue);
}, false);
}
when mouse over, every element, instead of showing a different value for curValue, a constant value (the last iteration value) is displayed.
what am i doing wrong here?
There is no different scope inside blocks like for in JavaScript, so when your mouseover event is triggered, it will alert the current variable value which was set in the last iteration.
You can just use this inside your callback function to get the attribute of the object which the event was triggered.
var myElements = document.getElementsByName('bb1');
for (var i = 0; i < myElements.length; i++) {
myElements[i].addEventListener('mouseover', function () {
alert('Hello i am : ' + this.getAttribute('innerId'));
}, false);
}
The general issue here is the closure in Javascript. This happens when using variable (in this case curValue) not defined within the callback function.
I recommend reading answers about JS closures here.

javascript error is null or not an object

I am trying to open a window from a php script. But when I click I get this error
Line: 389
Error: 'surgExpressBuildDefaultButton' is null or not an object
Line 389 code is as follow
function setupLayout(i)
{
document.body.onselectstart = function()
{
if (event.srcElement.tagName.search(/input|textarea/i)) return false;
}
setupButtons();
if(window.parent.opener.parent.frames[0].surgExpressBuildDefaultButton)
{
buttonClick(window.parent.opener.parent.frames[0].surgExpressBuildDefaultButton);
}
else
{
layout.buttons.commonButton.fixSelected();
}
for(i = 0; i < da.imgPlus.length; i++)
{
da.imgPlus[i].onclick = clickPlus;
da.imgMinus[i].onclick = clickMinus;
}
for(i = 0; i < da.spnName.length; i++)
{
da.spnName[i].selected = 0;
da.spnName[i].title = da.spnName[i].innerText;
da.spnName[i].onclick = function(){selectCommonProcedure(this);}
da.spnName[i].ondblclick = function(){addCommonProcedure(this);}
da.spnName[i].onmouseout = function(){this.className = (this.selected ? "nSelected" : "nOut");}
da.spnName[i].onmousedown = function(){this.className = "nDown";}
da.spnName[i].onmouseover = da.spnName[i].onmouseup = function(){this.className = "nOver";}
}
da.inpSearch.onkeydown = function(){if(event.keyCode == 13) updateProcedureList();}
da.btnSearch.onclick = da.selSpecialty.onchange = updateProcedureList;
da.btnClose.onclick = function(){window.close();}
da.btnAdd.disable = da.btnSave.disable = CC.Disable;
da.btnAdd.disable(1);
da.btnAdd.onclick = addCommonProcedure;
da.btnSave.disable(1);
da.btnSave.onclick = saveExpress;
}
what could be the problem. Any idea?
It's hard to tell without knowing which of those four dozen lines is line 489, but this jumped out at me:
function setupLayout(i)
{
document.body.onselectstart = function()
{
if (event.srcElement.tagName.search(/input|textarea/i)) return false;
^-- here
You're using event without having declared it (at least, not in the code you quoted). On IE, that'll work because IE makes the event object a property of window (and unless they're shadowed by other declarations, you can access window properties without explicitly qualifying them), but on most other browsers the event object is an argument to the event handler function – and so that code tries to use an undefined value as an object reference, which triggers exactly the error message you're seeing.
The usual idiom for dealing with this discrepancy in browsers (other than using a library like jQuery or Prototype that handle it for you) is this:
document.body.onselectstart = function(event)
{
event = event || window.event;
// ...
};
That idiom declares event it as an argument to the function, but then has it fall back to looking on the window (to support IE).

Categories

Resources