Searching here, I found this tutorial and it is really helpful. I could easily do document.onkeypress to get the key pressed, and String.fromCharCode() to convert the keycode to a readable char. But I was wondering how can I be able to detect specific words?
Like:
var words; // something to store the latest 3 words for example
// then somehow concatenate each key pressed
// separating in the array based on the space key
var all = words[0]+" "+words[1]+" "+words[2];
var lastTwo = words[1]+" "+words[2];
if(all == "i love you"){
alert("I love you too :)");
}else if(lastTwo = "screw you"){
alert("You should not say something like this to me");
}
EDIT: What I am really interested in is how can I concatenate the keys recursively?
First you need to build your array elements into a string:
var phrase = words.join(" ");
Then see what's in there.
if(phrase.indexOf('sandwiches')>-1) {
alert("found sandwiches! let's eat.");
}
My only problem is that I am editing the html file directly on the server with nano, so I just commit some mistakes that I could not recognize.
Basically doing:
var word = "";
function dump(e){
var unicode = e.keyCode? e.keyCode : e.charCode;
var actualkey = String.fromCharCode(unicode);
word += actualkey;
alert(word);
}
document.onkeypress = dump
I am able to see the keys concatenating which was my main problem. After that I will just adjust the values to an array and join them neatly like #Diodeus suggested.
Related
I know this seems a quite easy target. I have an input[type=text], and I want to detect the new added character(s) in it. The normal way is:
$selector.keypress(function(e) {
//do sth here
var newchar = String.fromCharCode(e.which);
});
But the above method not working properly for some browsers on android devices. Typing the android virtual keyboard will not fire the keypress.
Then I found the following method is better:
$selector.on('input', function(e){
//do sth here
});
It works fine for android devices, and also, it can detect cut/paste.
Now the question is, is there a way to know the new added character(s) to the input? Do I need to do the complicated string comparison during inputing each time, i.e. compare the previous string and the new string in the input box? I said it's complicated because you may not always type in char(s) at the end, you may insert some char(s) in the middle of the previous string. Think about this, the previous string in the input box is "abc", the new string after pasting is "abcxabc", how can we know the new pasted string is "abcx", or "xabc"?
The method from keypress is quite simple:
String.fromCharCode(e.which);
So, is there similar way to do this by the on('input') method?
After reading Yeldar Kurmangaliyev's answer, I dived into this issue for a while, and find this is really more complicated than my previous expectation. The key point here is that there's a way to get the cursor position by calling: selectionEnd.
As Yeldar Kurmangaliyev mentioned, his answer can't cover the situation:
it is not working is when you select text and paste another text with
replacing the original one.
Based on his answer, I modified the getInputedString function as following:
function getInputedString(prev, curr, selEnd) {
if (selEnd === 0) {
return "";
}
//note: substr(start,length) and substring(start,end) are different
var preLen = prev.length;
var curLen = curr.length;
var index = (preLen > selEnd) ? selEnd : preLen;
var subStrPrev;
var subStrCurr;
for(i=index; i > 0; i--){
subStrPrev = prev.substr(0, i);
subStrCurr = curr.substr(0, i);
if (subStrCurr === subStrPrev) {
var subInterval = selEnd - i;
var interval = curLen - preLen;
if (interval>subInterval) {
return curr.substring(i, selEnd+(interval-subInterval));
}
else{
return curr.substring(i, selEnd);
}
}
}
return curr.substring(0, selEnd);
}
The code is quite self explanation. The core idea is, no matter what character(s) were added(type or paste), the new content MUST be ended at the cursor position.
There's also one issue for my code, e.g. when the prev is abcabc|, you select them all, and paste abc, the return value from my code will be "". Actually, I think it's reasonable, because for my scenario, I think this is just the same with delete the abc from previous abcabc|.
Also, I changed the on('input') event to on('keyup'), the reason is, for some android browsers, the this.selectionEnd will not work in a same way, e.g., the previous text is abc|, now I paste de and the current string will be abcde|, but depending on different browsers, the this.selectionEnd inside on('input') may be 3, or 5. i.e. some browsers will report the cursor position before adding the input, some will report the cursor position after adding the input.
Eventually, I found on('keyup') worked in the same way for all the browsers I tested.
The whole demo is as following:
DEMO ON JSFIDDLE
Working on the cross-browser compatibility is always difficult, especially when you need to consider the touch screen ones. Hope this can help someone, and have fun.
Important notes:
when a user types in a character, the cursor stands after it
when a user pastes the text, the cursor is also located after the pasted text
Assuming this, we can try to suggest the inputed \ pasted string.
For example, when we have a string abc and it becomes abcx|abc (| is a cursor) - we know that actually he pasted "abcx", but not "xabc".
How do this algorithmically? Lets assume that we have the previous input abc and the current input: abcx|abc (cursor is after x).
The new one is of length 7, while the previous one is of length 4. It means that a user inputed 4 characters. Just return these four characters :)
The only case when it is not working is when you select text and paste another text with replacing the original one. I am sure you will come up with a solution for it yoruself :)
Here is the working snippet:
function getInputedString(prev, curr, selEnd) {
if (prev.length > curr.length) {
console.log("User has removed \ cut character(s)");
return "";
}
var lengthOfPasted = curr.length - prev.length;
if (curr.substr(0, selEnd - lengthOfPasted) + curr.substr(selEnd) === prev)
{
return curr.substr(selEnd - lengthOfPasted, lengthOfPasted);
} else {
console.log("The user has replaced a selection :(");
return "n\\a";
}
}
var prevText = "";
$("input").on('input', function() {
var lastInput = getInputedString(prevText, this.value, this.selectionEnd);
prevText = this.value;
$("#result").text("Last input: " + lastInput);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />
<div id="result">Start inputing...</div>
Sorry i cant find the tutorial in google because i dont know the keyword...
var currentURL=location.href;
var str = currentURL;
if(str == "http://web.com/blabla" || str == "http://web.com/bleble"){
window.location = "http://web.com/ban";
} else {
}
How to make str == "http://web.com/blabla" || str == "http://web.com/bleble" to list ? so if i want to input some url again, i just input the url to the list. Can give me the code or link tutorial ???
Basically you'll need to place all of your URL's into an array and then iterate over the array checking each item.
var urls = ['http://web.com/','http://web.net/','http://web.org'];
var current_url = '...';
for (var i = 0; i < urls.length; i++){
if (current_url == urls[i]){
window.location = "http://web.com/ban";
break; // exit the loop since we have already found a match
}
}
The break command will terminate the loop and stop searching the array for matching URLs. Since the action you want to take needs to happen if any of the URLs match, it's enough for one to match in order to stop searching.
Lists are called arrays in javascript, and are declared using square brackets, like this: var badUrls = ["http://web.com/blabla", "http://web.com/bleble"].
To check whether the current URL appears in the array, you can use the .indexOf function of the array, which will return the first position in the array where the string you provide can be found (starting with 0 for the first element), or -1 if it doesn't exist. For example, if you have an array var arr = ["foobar", "foo", "bar", "baz"], and you do arr.indexOf("foo"), you get 1 because it's the 2nd element in the array. If instead you do arr.indexOf("fooba"), you will get -1 because none of the elements in the array are fooba exactly. In your code, you want to redirect the user if badUrls.indexOf(str) > -1. You can get more information on indexOf in the MDN Documentation.
That makes your code look like:
var currentURL=location.href;
var str = currentURL;
var badUrls = ["http://web.com/blabla", "http://web.com/bleble"]
if(badUrls.indexOf(str) > -1){
window.location = "http://web.com/ban";
} else {
}
window.location is a browser object, it you want the page to go to http://web.com/ban, you should use
window.location.href = "http://example.com/ban";
However, it looks like you are trying to prevent people from visiting pages using JavaScript. This is extremely insecure, because anyone that lists your code will see which URLs you're trying to protect and immediately request them. If they request those URLs with JavaScript disabled, or using curl, the pages will be delivered.
You should protect the pages with server side configuration. With Apache, you can use the Allow/Deny configuration or RewriteRules.
Hi I'm not that experienced in JavaScript, and I'm trying to parse commands given as full sentences. It has to be able to match the sentence to a function that will answer, and select sections that it will pass as arguments. I know that's not too clear so here's an example:
sentnce = "Show me a gift of a car"
commands = {
gif: {
pattern: "*gif of a [target]*"
action: gifMe(target)
This scenario should result in the call gifMe("a car") or even better, gimme could be called with a object containing all of the arguments specified, there may be more than just target. I have no idea how to go about coding this or searching for a method to do this. Thanks in advance.
It's not relevant (I think) but I'm using jquery and Coffeescript.
I think this is the code you are looking for. See the comment in the code for some more information about how it works.
var sentence = "Show me a gift of a car";
// specify commands
var commands = {
gif: {
pattern: /gift of a (.*).?/,
action: call
}
// you can add more commands here
}
// iterate over all commands
for(var key in commands)
{
// get settings for command
var settings = commands[key];
// apply command regex to sentence
var result = sentence.match( settings.pattern );
// if there is a match trigger the action with the word as argument
if( result && result.length > 1 )
settings.action.call(this, result[1]);
}
function call(value)
{
alert(value);
}
Is it possible to merge two strings in JavaScript so that all the similarities are kept only keeping the differences.
For example
var string1 = "I am a sentence";
var string2 = "I am a dancer";
var string3 = function(string1, string2);
string3 = "I am a sentence dancer";
The similarities between the were preserved but the differences are added onto the string.
The reason I am asking is that I have a website application where the user can either edit the page through contenteditable or the code itself through a <textarea></textarea>. And so if they edit both, it submits both changes.
I would rather update the textarea data, when content editable is edited, and update content editable, when textarea is edited. This way, you would be sure, that all edits are saved for the user.
I think it can be as a variant.
function merge(str, str2){
var a = str.split(" ");
str2.split(" ").forEach(function(i, index){
var len = a.filter(function(item){return item == i;}).length;
if(len == 0) a.push(i);
});
return a.join(" ");
}
console.log(merge("I am a sentence","I am a dancer"));
// result "I am a sentence dancer"
Play with demo!
If you're looking to merge at the character level (rather than just at the word level), then you need a more general solution.
The levenshtein distance is the number of changes (replacements, additions) needed to turn one sting into another. For an example, try this site
http://andrew.hedges.name/experiments/levenshtein/
There are a number of levenshten algorithm examples which can be found on the web. You will need to modify them slightly to not just report the changes between the two strings, but use them to merge the two together.
I'm trying to warning the user if he types a word that is not necessary in a textarea.
its just a little validation for some words.
i reach making something like this:
var words = "hello";
$("textarea").keyup(function(e){
var spliting = $("textarea").val().split(" ");
if(e.keyCode == 32){ // when the user hits space bar
if($.inArray(words, spliting) != -1){
$("span").css("background","red");
}else{
$("span").css("background","green");
}
}
});
is this the best way of doing this ?
and how can i migrate the variable words as a array, if i need to check more then one word?
Demo
To use an array, you will need to loop over each word in it and loop over each word in the split array. However, you can return on the first match:
var words = ["hello","goodbye"];
$("textarea").keyup(function(e){
var spliting = $("textarea").val().split(" ");
for (var i=0; i<words.length; i++) {
if($.inArray(words[i], spliting) != -1){
$("span").css("background","red");
// break on first match since there is no need to continue looping
// if it is already red.
break;
}else{
$("span").css("background","green");
}
}
});
I have removed the check for spaces. Even though it makes the function more efficient, you need to be wary of cases when someone goes back to correct spelling and ends up with an invalid word. The way you had it, those cases would never cause the flagged words to be found unless a space was typed later.
It would be advisable to call this function for onchange and blur events as well, since typing is not the only way users enter input into form inputs.
Here is the updated demo
You don't need to .split the input every time a key is pressed, this is a situation where a regular expression is to be preferred:
Check the updated fiddle
To generate the expression based on an array:
var blackList = ['hello','world'];
var expression = new RegExp('\\b(' + blackList.join('|') + ')\\b','i');
$("textarea").keyup(function(e)
{
//if (e.keyCode === 32)
//{in comment after reading the answer posted by Michael Berkowski
if ($(this).val().match(expression))
{
$("span").css("background","red");
return;
}
$("span").css("background","green");
//}
});