JavaScript: add keyboard events (focus on window is wrong?) - javascript

I'm putting my hands in javascript for the first time and I can't seem to find a way to do what I need to do for a class.
We have a html file that defines a calculator and already works with mouse input.
The style and the functions are defined in separate .css and .js files. We're supposed to add keyboard-events in order to make the calculator accessible. I've been trying several options, especially from this page, but none seemed to work.
The problem is that I don't even know how to find out whether it's not working because my function is wrong or it's not working because I don't have the correct focus in my window...
I'll give an example of code below. I'll focus just on the "clear" functionality, which I'd like to assign to the backspace key (keycode=8).
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>MyCalc</title>
<link title="screen" media="screen" type="text/css" href="css/stylesheet.css" rel="stylesheet">
<script type="text/javascript" src="js/functions.js"></script>
</head>
<body>
<div id="calculator">
<!-- Screen and clear key -->
<div class="top">
<span class="clear" onclick="clearScreen()">C</span>
<div class="screen"></div>
</div>
<div class="keys">
<!-- operators and other keys -->
</div>
</div>
</body>
</html>
where the clearScreen function is defined as:
function clearScreen() {
var input = document.querySelector('.screen');
input.innerHTML = '';
}
I'd appreciate if someone could tell me how to bind my backspace key to that clearScreen function. As I mentioned above, so far I tried to paste the following code in my .js file, but with no success:
function keyListener(event) {
event = event || window.event;
var key = event.key || event.which || event.keyCode;
var input = document.querySelector('.screen');
if (key === 8) { //this is for 'backspace'
input.innerHTML = '';
}
}
var el = window; //does this even work?
var eventName = 'keypress';
if (el.addEventListener) {
el.addEventListener('click', keyListener, false);
} else if (el.attachEvent) {
el.attachEvent('on' + eventName, keyListener);
}
NOTE: I'm using Google Chrome but I also did some tests in Mozilla and IE. I didn't notice any difference.

Related

One-( keypress-)event-delay between javascript input and output

The following snippet reproduces the input text in the webpage using simple javaScript and jQuery.
I am wondering, though, how come there is a one character (or more precisely : one keystroke) latency between the input and the output
eg :
I type 'abcde'
the output is 'abcd'
however if I press the Insert key, the ultimate 'e' prints.
My code :
<!doctype html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<input type="text" name="enteredText" id="myTextInput" />
<p id="myTextOutput">
blabla
</p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$("#myTextInput").keypress(function( ){
var theText = $("#myTextInput").val();
$("#myTextOutput").html(theText);
});
$( "html" ).click(function( event ) {
var value = $("#myTextInput").val();
$("#myTextOutput").html(value);
});
</script>
</body>
</html>
Any idea ? Thanks
If you want to get rid of tat latency. use keyup or keydown instead of keypress:
$("#myTextInput").keyup(function( ){
var value = $("#myTextInput").val();
$("#myTextOutput").html(value);
});
Here is the DEMO
The most likely reason is that the keypress event handler is executed before the content of the input field is updated. When you read the content, you still read the old content, not the updated one.
From jQuery's keypress docs:
Note: as the keypress event isn't covered by any official specification, the actual behavior encountered when using it may differ across browsers, browser versions, and platforms.
Using keyup instead fixes the issue:
$("#myTextInput").keyup(function() {
var theText = $("#myTextInput").val();
$("#myTextOutput").html(theText);
});
$("html").click(function(event) {
var value = $("#myTextInput").val();
$("#myTextOutput").html(value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="enteredText" id="myTextInput" />
<p id="myTextOutput">
blabla
</p>
You're grabbing the value before you've allowed the event to propagate up to where the text field has been updated. You can add an infinitesimal delay to get the full value:
$("#myTextInput").keypress(function( ){
setTimeout(function() {
var value = $("#myTextInput").val();
$("#myTextOutput").html(value);
}, 0);
});

jquery keypress condition glitch any key

i am having a problem with jQuery. i am trying to create an even that is triggered by a single key pressed, but instead -some of it- is triggered by any key. don't understand why. i have done this a bunch of times and had no problem. all of a sudden this particular combination of code is acting weird. i don't understand. i have tried all sorts of experiments on it to figure it out. the problem is very specific and consistent on multiple browsers. please help! here is the link to the page. http://www.lyliansill.com/test.html>
to see what i am talking about press 'a' and it works like it should. reload and press any other keys and half of the event is still triggered.
<!DOCTYPE html PUBLIC "-//W3C/DTD/ XHTML 1.0 Strict/EN" "http://www.w3.org/TR/xhtml1/dtd/xhtml1-strict.dtd">
<!-- This file is on level 02 -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Test</title>
<style type="text/css">
.hidden
{
display: none;
}
.select
{
color:#cc0000;
}
</style>
</head>
<body>
<h1 class="test hidden">Test</h1>
<script type="text/javascript" src="playground/libraries/jquery.js">
</script>
<script type="text/javascript">
function showIt()
{
$(".showIt").show();
}
$(document).keypress
(
function(e)
{
if (e.which === 97)
$(".test").addClass("select"); // this line works like it should
$(".test").addClass("showIt"); // these two lines are activated...
showIt(); // ...by pressing any key! why??
}
);
</script>
</body>
</html>
This is why you should make sure to use brackets, lets look at the code:
if (e.which === 97)
$(".test").addClass("select"); // this line works like it should
$(".test").addClass("showIt"); // these two lines are activated...
showIt(); // ...by pressing any key! why??
Notice the if statements has no brackets: if(){ ... }, so the line under is is only executed if that if-statement is true, but the rest is not in the if statement so:
$(".test").addClass("showIt"); // these two lines are activated...
showIt(); // ...by pressing any key! why??
Always runs. To fix this add brackets:
if (e.which === 97) {
$(".test").addClass("select"); // this line works like it should
$(".test").addClass("showIt"); // these two lines are activated...
showIt(); // ...by pressing any key! why??
}
here's how to fix it (Add curly braces):
function(e)
{
if (e.which === 97) {
$(".test").addClass("select"); // this line works like it should
$(".test").addClass("showIt"); // these two lines are activated...
showIt();
} // ...by pressing any key! why??
}

JQuery partly triggered

I'm a beginner with JQuery and I was trying to create a button that dynamically changes the colors defined in the CSS depending on what color it is right now (just switch between blue / red) and also change the text on the button.
The .draggable() part executes just fine and so does the first and last console.log, so everything but the part within the click event handler works ... but why?
Relevant html code:
<!DOCTYPE html>
<html>
<head>
<title>Meine Website</title>
<meta charset="utf-8">
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"
type="text/javascript">
</script>
<script
src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"
type="text/javascript">
</script>
<script src="home_jquery.js"></script>
<script src="home_javascript.js"></script>
<link rel="stylesheet" type="text/css" href="home_style_blau.css">
</head>
<body>
<input type="button" id="farbwechsel_button" value="Rot" />
/* rest of html (taschenrechner_box, etc.) */
</body>
Here's the jQuery part:
var blau = true;
$(document).ready(function () {
$('#taschenrechner_box').draggable();
console.log("test1");
$('#farbwechsel_button').click(function() {
console.log("test2");
if (blau == true) {
console.log("blau = " + blau);
$('body').css({"background-color": "8b0000"});
$('#farbwechsel_button').value = "Blau";
blau = false;
}
else {
console.log("blau = " + blau);
$('body').css({"background-color": "lightsteelblue"});
$('#farbwechsel_button').value = "Rot";
blau = true;
}
console.log("test3");
})
console.log("test4");
});
In your HTML you have:
<input type="button" id="farbwechsel_button" value="Rot" />
But in your JS you refer to
$('#farbwechel_button').click(function() {
Note the forgotten s in your JS. So the JS should be:
$('#farbwechsel_button').click(function() {
Edit: you've forgotten the s in al your referrals to the button. Don't forget to add it everywhere. You've also forgotten a ; just before the last console.log() function.
Edit 2: Here's a Fiddle with a working example. It's pretty much self explanatory. In this case you preferably should make use of classes which you toggle on pressing the button.

Multiple modes Codemirror

I want my TextArea to be able to support multiple CodeMirror modes. For now I want it to support json and xml. Is this possible?
Also, is it possible to automatically detect whether the user placed json or xml in the area?
Thanks.
CodeMirror actually has an example very close to what you are looking for here.
Here is a more specific example that does what you want.
Create a CodeMirror instance.
When the content changes we determine if we should switch modes.
The logic I put in for determining what mode you are in is very simplistic and can be refactored to support as robust a check as you deem appropriate for either mode. (Regex is good for complex checking if you want to get fancy...that is the only reason I used it even in my simple example) Currently, my example code just checks for any content where the first non-space character is "<" thus indicating xml mode. When deciding to switch back it just checks that the first non-space character is not "<" and that it is not blank (in case the user just deleted everything to start over with more xml).
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Code Mirror Example</title>
<script src="lib/codemirror.js"></script>
<link rel="stylesheet" href="lib/codemirror.css">
<script src="mode/javascript/javascript.js"></script>
<script src="mode/xml/xml.js"></script>
<style type="text/css">.CodeMirror{border:1px solid black;}</style>
</head>
<body>
<div><span>Mode: </span><span id="modeType">JSON</span></div>
<textarea class='codeEditor'></textarea>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
function determineCodeMirrorType(cm)
{
if (cm.getMode().name == 'javascript')
{
checkAndSwitchToXML(cm, cm.getValue());
}
else if (cm.getMode().name == 'xml')
{
checkAndSwitchToJSON(cm, cm.getValue());
}
}
function checkAndSwitchToXML(cm, val)
{
if (/^\s*</.test(val))
{
cm.setOption("mode", "xml");
$('#modeType').html("XML");
}
}
function checkAndSwitchToJSON(cm, val)
{
if (!/^\s*</.test(val) && val.match(/\S/))
{
cm.setOption("mode", "javascript");
$('#modeType').html("JSON");
}
}
function buildCMInstance(mode, value)
{
var cm = CodeMirror.fromTextArea($('.codeEditor')[0], {
mode:mode,
value:value,
lineNumbers:true,
onChange:function(cmInstance){
determineCodeMirrorType(cmInstance);
}
});
return cm;
}
$(document).ready(function(){
//mode changing demo: "http://codemirror.net/demo/changemode.html";
var cm = buildCMInstance("javascript");
});
</script>
</body>
</html>

Add CSS gradient with javascript - bug in IE7

I am trying to add gradient on only .link.box.gradient but in ie7 it add on .link.box.gradient and .style.box.gradient
<!DOCTYPE html>
<html lang="sv">
<head>
<title></title>
<script src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.4.min.js"></script>
<script>
jQuery(function ($) {
$('head').append("<style>.link.box{height:100px;width:100px;}.link.box.gradient{filter:progid:DXImageTransform.Microsoft.gradient(startColorStr='#000000',EndColorStr='#ffffff');}</style>");
});
</script>
</head>
<body>
<div class="style box gradient">Gradient (style-tag)</div>
<div class="link box gradient">Gradient (link-tag)</div>
</body>
</html>
You can see here too, http://jsfiddle.net/Zhvpy/
One strange thing is when i move out .link.box{height:100px;width:100px;} from javascript as you can see here http://jsfiddle.net/Zhvpy/1 it seems to work, but I dont want to move out.
Why is it like this? How can I fix this bug?
removed original incorrect answer
EDIT 1
Odd - decided it might be the way older versions of IE handle certain elements (like <script />) so tried a non-jQuery solution.
Seems to work!
EDIT 2
Added this to your full script - outputs different results which are more in line with what IE8 outputs
function appendStyle(element, cssObj) {
//$('#a').append($('<span/>').text(cssObjToText(cssObj)));
if ($.browser.version == 7) {
var head = document.getElementsByTagName('head')[0],
style = document.createElement('style'),
rules = document.createTextNode(cssObjToText(cssObj));
style.type = 'text/css';
head.appendChild(style);
style.styleSheet.cssText = rules.nodeValue;
}
else {
element.after('<style class="css-finalized">' + cssObjToText(cssObj) + '</style>');
}
}

Categories

Resources