Is there a way to pass a variable to keypressed function? - javascript

I am trying to send the document and the control that the key was pressed in to the keypressed function.
Here is my code:
//Namespace
MyExt.BrowserOverlay = {
init: function() {
var appcontent = document.getElementById("appcontent"); // browser
if(appcontent)
appcontent.addEventListener("DOMContentLoaded", MyExt.BrowserOverlay.onPageLoad, true);
},
onPageLoad: function(aEvent) {
var doc = aEvent.originalTarget;
if (doc.location.href == "http://something.com"){
var txtBox = doc.getElementById('txtBox');
txtBox.addEventListener('keypress', keypressed, false); //Error Line
}
},
…
something like:
txtBox.addEventListener('keypress', keypressed(?,doc), false);
function keypressed(a,doc){
alert(a); //a relates to keypress
alert(doc.innerHTML);
}

Easiest way to pass variable is to attach it to Element that will trigger event, but you can access document by using global variable document.
As for event listeners, browsers handle events differently:
txtBox.someVar = "foobar"; // Any variable you want to pass
if(window.addEventListener){ // Firefox, Chrome...
txtBox.addEventListener('keypress', keypressed, false);
} else { // IE
txtBox.attachEvent('onkeypress', keypressed);
}
function keypressed(event){
// find event object
var e = event || window.event;
// find target object
var target = e.currentTarget;
if (e.target) target = e.target;
else if (e.srcElement) target = e.srcElement;
if (target.nodeType == 3) target = targ.parentNode;
// find key code
var code = e.charCode || e.keyCode;
alert(String.fromCharCode(code));
alert(target.someVar);
alert(document.body.innerHTML);
}

You can use gBrowser.contentDocument to get the document of the currently selected tab. See this article on the tabbed browser control for more info.

Related

Making a JavaScript code works with any element

document.getElementById("but").onclick = showDropDown;
function showDropDown(e) {
document.getElementById("but").onclick = function() {};
if (e.stopPropagation) e.stopPropagation(); // W3C model
else e.cancelBubble = true; // IE model
document.getElementById("window").style.display = "inline-block";
document.onclick = function(e) {
var ele = document.elementFromPoint(e.clientX, e.clientY);
if (ele == document.getElementById("but")) {
hideDropDown();
return;
}
do {
if (ele == document.getElementById("window")) return;
} while (ele = ele.parentNode);
hideDropDown();
};
}
function hideDropDown() {
document.onclick = function() {};
document.getElementById("window").style.display = "none";
document.getElementById("but").onclick = showDropDown;
}​
<input id="but" type="button" value="pressMe" />
<div id="window" style="display:none">popup</div>
Demo: http://jsfiddle.net/nazym/
I was trying to make the JavaScript code dynamic using variables instead of the specified elements' names but I could not. It always returns errors. I want to link it with different elements.
update
I want to replace the ids of the elements in the JavaScript code with variables so I can use it with any element.I tried to do it but failed. Basically, I want to use variables instead of the ids of the element and link it to the elements somehow again.
Use arguments instead:
function showDropDown(element, e) {
element.onclick = function() {};
// ....
hideDropDown(element);
}
And you would give the element it's onclick event handler like this:
document.getElementById('but').onclick = function(event) {
showDropDown(this, event);
};
Demo: http://jsfiddle.net/xNSZm/
Change the code to
var showDropdown = function(e) { ... };
document.getElementById("but").onclick = showDropDown;
In other words, store the function in a variable before assigning it.
In your code:
> document.onclick = function(e){
In browsers that support the IE event model, e will be undefined. To accommodate those browsers, you can use:
e = e || window.event;
To find the element that was clicked on, instead of:
> var ele = document.elementFromPoint(e.clientX, e.clientY);
you can do:
var ele = e.target || e.srcElement;
which will work in very many more browsers than elementFromPoint so should be more reliable and faster.

JavaScript event handler to insert new pre tag

I have a set of 3 pre tags that are editable. When someone is on one of the lines and hits 'enter', I want it to insert a new tag below (in the document tree) the one it is on. I have tried to put an event handler on the tags so that this occurs, but the 'onkeypress' doesn't seem to be firing.
<script>
function handlers(){
var pres = document.getElementsByTagName("pre");
for(i=0; i<pres.length;i++){
pres[i].addEventListener("onkeypress", function(e){
if(e.which != 13) return;//the ENTER key
var tag = e.srcElement;
if(tag.nextSibling){
var next = tag.nextSibling;
var newPre = document.createElement('pre');
tag.nextSibling = newPre;
newPre.nextSibling = next;
}
var tree = document.getElementById("tree");
tree.innerHTML = document.getElementByTagName().length;
});
}
}
</script>
<body onload="handlers();">
<div id="editor" contentEditable="true">
<pre>1</pre>
<pre>2</pre>
<pre>3</pre>
</div>
<div>
<p id="tree"></p>
</div>
</body>
You are iterating over the array of elements incorrectly, and you are not attaching event listeners correctly.
I recommend changing your for loop to:
for (var i=0, l=pres.length; i<l; i++) {
pres[i];//This is where the Element is stored
}
You can read up on attaching event listeners here
Additionally, it would appear: http://jsfiddle.net/vZYpX that the source of the keypress event under "contentEditable" is the actual element that is "contentEditable". So you have to either make the <pre>s content editable (and not the div), or attach the listener to the parent div (that is currently contentEditable).
I'm not sure the 'onkeypress' can be fired from 'pre' tag.
However I have a suggestion:
1. Register document.onmousemove to detect mouse position.
2. Register document.onkeypress event and when detecting the 'enter' key, check if the mouse is over a 'pre' tag. If so, run your code.
It should look like this:
function moveMoveHandler(e)
{
var evt = window.event || e;
window.lastMouseX = evt.clientX;
window.lastMouseY = evt.clientY;
}
function keypressHandler(e)
{
var evt = window.event || e;
// handling only 'enter' key
if (evt.keyCode !== 13) return;
// getting the element the mouse is on
var elem = document.elementFromPoint(window.lastMouseX,window.lastMouseY);
var node = elem;
// checking if the found node is a child of a 'pre' node
while (node.nodeName !== "PRE" && node !== document.body)
node = node.parentNode;
if (node.nodeName === "PRE")
{
... INSERT YOUR CODE HERE ...
}
}
// IE
if (window.attachEvent)
{
document.attachEvent("onkeypress", keypressHandler);
document.attachEvent("onmousemove", moveMoveHandler);
}
// other browsers
else
{
document.addEventListener("keypress", keypressHandler, false);
document.addEventListener("mousemove", moveMoveHandler, false);
}

Javascript event handler on body but not on input

I have the following event handler
document.addEventListener('keydown', handleBodyKeyDown, false);
HOW DO i prevent it from occurring when inside a input box
Within your handleBodyKeyDown function, check if
event.target.tagName.toUpperCase() == 'INPUT'
(or 'TEXTAREA').
Note: For older versions of IE, use event.srcElement.tagName.
Like so:
document.addEventListener('keydown', handleBodyKeyDown, false);
function handleBodyKeyDown(event)
{
var e = event || window.event,
target = e.target || e.srcElement;
if (target.tagName.toUpperCase() == 'INPUT') return;
// Now continue with your function
}
P.S. Why are you using addEventListener if you have jQuery on the page? In jQuery, all of this gets sorted out for you:
$(document).on('keydown', ':not(input)', function(e)
{
// Your code goes here...
});
In your handleBodyKeyDown method, check to see if the event originated on an input element:
function handleBodyKeyDown(event) {
if (event.target.tagName.toUpperCase() === 'INPUT') {
return; // do nothing
}
// do the rest of your code
}
Note that the toUpperCase call is necessary because the conditions that determine the case of the tagName property are quite complicated and sometimes all but uncontrollable.
See event.target at MDN.
If you are using jQuery you can try this which uses is() method to test the target element is input then do nothing.
function handleBodyKeyDown(event) {
if ($(event.target).is("input")) {
return;
}
else{
//Do your stuff here
}
}
This worked for me:
const fromInput = event => event.srcElement instanceof HTMLInputElement;
function handleBodyKeyDown(event) {
if(fromInput(event))
return;
// do your magic here
}
You could do something like:
handleBodyKeyDown = function(e) {
var e = e || window.event
if (e.target.tagName != "INPUT") {
// handle this since it isn't input
}
}
Sometimes (as to me) it is better not to prevent it to occur, but to ignore in the event cases, when it occured in the input. It's looks like this is also your case as well.
Just inspect evt.target || evt.srcElement property (modern frameworks do this normalization work for you, so, most probably this will be called target) whether it's input or not. If not, just ignore.
QuirksMode tells you how to get an event's target. You can check that it is not an input:
function doSomething(e) {
var targ;
if (!e) var e = window.event;
if (e.target) targ = e.target;
else if (e.srcElement) targ = e.srcElement;
if (targ.nodeType == 3) // defeat Safari bug
targ = targ.parentNode;
if( targ.tagName != "INPUT" ) {
//Perform your action here
}
}
Your question is tagged jQuery, in which case you can just test event.target as the framework normalizes this for you.
$(document).bind("keydown", function (event) {
if(event.target.tagName != "INPUT") {
//Do something
}
});
HandleBodyKeyDown function will be invoked in any case. You can not prevent its call on the method of recording as you indicated. You can only add a logic for checking if this an 'input' and return. Additionaly (if needed) you can prevent it from bubble up:
function handleBodyKeyDown(ev) {
ev=ev||event;
var sender=ev.target||ev.srcElement;
if(sender.tagName.toLowerCase()==="input") {
if(ev.stopPropagation)ev.stopPropagation();
else ev.cancelBubble=true; // for IE8 or less
return true; // do not prevent event from default action
}
// your code for global keydown
}
If you're using Prototype (which you have tagged but you also have two other frameworks tagged) then the event can be registered and filtered in one like this:
document.on('keydown', ':not(input)', handleBodyKeyDown);

Add a second onChange event?

Hi I found this script online that adds an onChange event to an element and I would like to now add a second onChange event to the same element. Heres the script:
document.getElementById('piname').onchange =
function() {
removeChildren({
parentId: 'account_table',
childName: 'extraaccount'
});
}
And the onChange event i want to add is:
showAccount(this.value)
Use addEventListener() (and attachEvent as a fallback, if needed).
Example:
document.getElementById('piname').addEventListener("change", function(e){
e = e || event;
showAccount(e.target.value);
}, false);
Example, with fallback:
var element = document.getElementById('piname');
if(element.addEventListener){
element.addEventListener("change", function(e){
e = e || event;
showAccount(e.target.value);
}, false);
}
else if(element.attachEvent){
element.attachEvent("onchange", function(e){
e = e || event;
showAccount(e.target.value);
});
}
The simplest way is to cache the old function and call it from the new one:
var el = document.getElementById('piname'),
old = el.onchange;
el.onchange = function () {
old.call(el);
showAccount(this.value);
}
Other than that, you could use addEventListener (W3C standards) and attachEvent (IE8 and lower):
var el = document.getElementById('piname'),
fn = function (e) {
e = e || window.event;
showAccount((e.target || e.srcElement).value);
};
if ("addEventListener" in el) {
el.addEventListener("change", fn, false);
}
else {
el.attachEvent("onchange", fn);
}
Those methods allow you to attach as many handlers to events as you like.

how to get src element in javascript for firefox

I am try to catch form event in javascript
var event = window.event.srcElement;
This is working fine in IE, but in
Netscape/Firefox where event return undefined.
Can someone tel me how to catch event
in Netscape/Firefox?
IE and Netscape play different games.
But you can easily make it crossbrowser as such:
if (window.event) e = window.event;
var srcEl = e.srcElement? e.srcElement : e.target;
Use .target:
var event = event.target;
Or to check for both/fallback in a single statement:
function myHandler(event) {
var target = window.event.srcElement || event.target;
}
(In both cases... I'd rename your variable, since this isn't the actual event object, but an element.)

Categories

Resources