我正在使用插件(https://jsfiddle.net/me7on070/),我需要在发生某些事件时使用不同的参数重新初始化。 有人能告诉我怎么做吗? 我试过简单地传递一个这样的变量:
$("input#chatMessage").intlKeyboard({
language: t,
suggestions: "#suggestions",
numResults: 5 // default
});
其中t是在调用事件中更改的变量。但是,这不起作用。该插件的原始实例仍然存在。
答案 0 :(得分:1)
我不得不修改有问题的插件来绑定命名空间事件,以便在重新绑定更改的参数之前,它们都可以在开始时正确解除绑定。
我forked your jsFiddle显示完整代码。
它的内容是在插件IIFE的顶部声明以下函数:
var ns = function (event) {
return (event || '') + '.intlKeyboard';
}
然后我更改了所有.bind()
和.on()
调用以使用此函数,如下所示:
this.bind(ns("keydown"), ...
然后解开所有内容,我刚开始使用.off(ns())
和.unbind(ns())
。
jsFiddle代码也会复制到以下代码段/ demo中。
/*!
* jQuery intlKeyboard Plugin v0.1
*
* Copyright 2013 Ashwin Purohit and other contributors
* Released under the MIT license
*
* Date: 24 Aug 2013
*/
(function($) {
var ns = function(event) {
return (event || '') + '.intlKeyboard';
}
// Cross-browser set caret position function
// From http://stackoverflow.com/a/512542/100208
var setCaretPosition = function(el, caretPos) {
if (el != null) {
if (el.createTextRange) {
var range = el.createTextRange();
range.move("character", caretPos);
range.select();
} else {
if (el.selectionStart) {
el.focus();
el.setSelectionRange(caretPos, caretPos);
} else {
el.focus();
}
}
}
};
// Cross-browser get caret position function
// From http://stackoverflow.com/a/4931963/100208
var getInputSelection = function(el) {
var start = 0,
end = 0,
normalizedValue, range, textInputRange, len, endRange;
if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
start = el.selectionStart;
end = el.selectionEnd;
} else {
range = document.selection.createRange();
if (range && range.parentElement() == el) {
len = el.value.length;
normalizedValue = el.value.replace(/\r\n/g, "\n");
// Create a working TextRange that lives only in the input
textInputRange = el.createTextRange();
textInputRange.moveToBookmark(range.getBookmark());
// Check if the start and end of the selection are at the very end
// of the input, since moveStart/moveEnd doesn't return what we want
// in those cases
endRange = el.createTextRange();
endRange.collapse(false);
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
start = end = len;
} else {
start = -textInputRange.moveStart("character", -len);
start += normalizedValue.slice(0, start).split("\n").length - 1;
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
end = len;
} else {
end = -textInputRange.moveEnd("character", -len);
end += normalizedValue.slice(0, end).split("\n").length - 1;
}
}
}
}
return {
start: start,
end: end
};
};
// Usage: call this on any input or textarea:
// $('input.french').intlKeyboard({
// language: 'fra',
// replacements: '#suggestions' // Only makes sense for IMEs
// numResults: 5 // Only makes sense for IMEs
// });
// This will listen for changes, and replace certain key sequences with
// international versions, for people who don't want to install a keyboard.
$.fn.intlKeyboard = function(options) {
// Keys that don't change caret position in input, but that
// are used in key combinations
var silentKeys = {
16: true
};
// A reversed version of http://www.selfcontained.us/2009/09/16/getting-keycode-values-in-javascript/
var keysToCodes = {
"backspace": 8,
"tab": 9,
"return": 13,
"shift": 16,
"ctrl": 17,
"alt": 18,
"pausebreak": 19,
"capslock": 20,
"escape": 27,
" ": 32,
"pageup": 33,
"pagedown": 34,
"end": 35,
"home": 36,
"left": 37,
"up": 38,
"right": 39,
"down": 40,
"+": 43,
"printscreen": 44,
"insert": 45,
"delete": 46,
"0": 48,
"1": 49,
"2": 50,
"3": 51,
"4": 52,
"5": 53,
"6": 54,
"7": 55,
"8": 56,
"9": 57,
";": 59,
"=": 61,
"a": 65,
"b": 66,
"c": 67,
"d": 68,
"e": 69,
"f": 70,
"g": 71,
"h": 72,
"i": 73,
"j": 74,
"k": 75,
"l": 76,
"m": 77,
"n": 78,
"o": 79,
"p": 80,
"q": 81,
"r": 82,
"s": 83,
"t": 84,
"u": 85,
"v": 86,
"w": 87,
"x": 88,
"y": 89,
"z": 90,
// Numpad codes -- TODO keys that, depending on if hit from numpad
// or keyboard, can have different codes, like: "0": [48, 96]
//"0":96, "1":97, "2":98, "3":99, "4":100, "5":101, "6":102, "7":103, "8":104, "9":105,
"*": 106,
"+": 107,
"-": 109,
".": 110,
"/": 111,
"f1": 112,
"f2": 113,
"f3": 114,
"f4": 115,
"f5": 116,
"f6": 117,
"f7": 118,
"f8": 119,
"f9": 120,
"f10": 121,
"f11": 122,
"f12": 123,
"numlock": 144,
"scrolllock": 145,
";": 186,
"=": 187,
",": 188,
"-": 189,
".": 190,
"/": 191,
"`": 192,
"[": 219,
"\\": 220,
"]": 221,
"'": 222
};
var stack = [];
var self = this;
// Ideographic languages that we'd prefer to use Google suggest for.
var languageToGoogleITC = {
zh: "zh-t-i0-pinyin",
hi: "hi-t-i0-und"
};
self.unbind(ns());
// We define most Latin keyboard mappings ourselves.
var langReplacements = {
fra: [ // French | Français
// C cedille
[
[",", "c"], "ç"
],
[
[",", "shift", "c"], "Ç"
],
// Accent grave
[
["`", "a"], "à"
],
[
["`", "e"], "è"
],
[
["`", "u"], "ù"
],
[
["`", "shift", "a"], "À"
],
[
["`", "shift", "e"], "È"
],
[
["`", "shift", "u"], "Ù"
],
// Accent aigu
[
["'", "e"], "é"
],
[
["'", "shift", "e"], "É"
],
// But, differentiate between C'est and Céline
// by allowing a user to put a space after the ' to not accent
[
["'", " ", "e"], "'e"
],
[
["'", " ", "shift", "e"], "'E"
],
// Circonflexe (^ = [Shift] + 6)
[
["shift", "6", "a"], "â"
],
[
["shift", "6", "e"], "ê"
],
[
["shift", "6", "i"], "î"
],
[
["shift", "6", "o"], "ô"
],
[
["shift", "6", "shift", "a"], "Â"
],
[
["shift", "6", "shift", "e"], "Ê"
],
[
["shift", "6", "shift", "i"], "Î"
],
[
["shift", "6", "shift", "o"], "Ô"
],
// Le tréma
[
["shift", "'", "a"], "ä"
],
[
["shift", "'", "e"], "ë"
],
[
["shift", "'", "i"], "ï"
],
[
["shift", "'", "o"], "ö"
],
[
["shift", "'", "u"], "ü"
],
[
["shift", "'", "shift", "a"], "Ä"
],
[
["shift", "'", "shift", "e"], "Ë"
],
[
["shift", "'", "shift", "i"], "Ï"
],
[
["shift", "'", "shift", "o"], "Ö"
],
[
["shift", "'", "shift", "u"], "Ü"
]
],
es: [ // Spanish | Español
// El acento
[
["'", "a"], "á"
],
[
["'", "e"], "é"
],
[
["'", "i"], "í"
],
[
["'", "o"], "ó"
],
[
["'", "u"], "ú"
],
[
["'", "shift", "a"], "Á"
],
[
["'", "shift", "e"], "É"
],
[
["'", "shift", "i"], "Í"
],
[
["'", "shift", "o"], "Ó"
],
[
["'", "shift", "u"], "Ú"
],
// La crema o diéresis
[
["shift", "'", "u"], "ü"
],
[
["shift", "'", "shift", "u"], "Ü"
],
// La ñ
[
["shift", "`", "n"], "ñ"
],
[
["shift", "`", "shift", "n"], "Ñ"
],
// Signos de interrogación y exclamación invertidos
// Handles [Shift]-[?]-[?], and [Shift]-[?], [Shift]-[?]
[
["shift", "/", "/"], "¿"
],
[
["shift", "/", "shift", "/"], "¿"
],
[
["shift", "1", "1"], "¡"
],
[
["shift", "1", "shift", "1"], "¡"
],
],
deu: [ // German | Deutsch
// Umlaut
[
["shift", "'", "a"], "ä"
],
[
["shift", "'", "o"], "ö"
],
[
["shift", "'", "u"], "ü"
],
[
["shift", "'", "shift", "a"], "Ä"
],
[
["shift", "'", "shift", "o"], "Ö"
],
[
["shift", "'", "shift", "u"], "Ü"
],
// Eszett
[
[",", "s"], "ß"
],
],
tur: [ // Turkish | Türkçe
// Yumuşak ge
[
[",", "g"], "ğ"
],
[
[",", "shift", "g"], "Ğ"
],
// ı
[
[".", "i"], "ı"
],
[
[".", "shift", "i"], "I"
],
// Capital i becomes İ
[
["shift", "i"], "İ"
],
// â, î, û
[
["shift", "6", "a"], "â"
],
[
["shift", "6", "i"], "î"
],
[
["shift", "6", "u"], "û"
],
[
["shift", "6", "shift", "a"], "Â"
],
[
["shift", "6", "shift", "i"], "Î"
],
[
["shift", "6", "shift", "u"], "Û"
],
// çe
[
[",", "c"], "ç"
],
[
[",", "shift", "c"], "Ç"
],
// şe
[
[",", "s"], "ş"
],
[
[",", "shift", "s"], "Ş"
],
// ö, ü
[
["shift", "'", "o"], "ö"
],
[
["shift", "'", "u"], "ü"
],
[
["shift", "'", "shift", "o"], "Ö"
],
[
["shift", "'", "shift", "u"], "Ü"
],
],
en: []
};
// Builds a reverse trie for key combinations, keyed on keyCode,
// from the passed human-readable array of arrays.
// If the combo "," (188) then "c" (67), should be replaced with ç,
// then the trie would look like: {67: {188: {r: ç}}}
var reverseTrieForLang = function(language) {
var tree = {};
var combos = langReplacements[language];
for (var i = 0; i < combos.length; i += 1) {
var node = tree;
var keys = combos[i][0];
var replacement = combos[i][1];
for (var j = keys.length - 1; j >= 0; j -= 1) {
var key = keys[j];
var code = keysToCodes[key];
if (!node.hasOwnProperty(code)) {
node[code] = {};
}
node = node[code];
if (j == 0) {
node.r = replacement;
}
}
}
return tree;
};
// If this language is Pinyin, the IME is completely different.
if (languageToGoogleITC.hasOwnProperty(options.language)) {
// Default number of results.
options = $.extend({
numResults: 5
}, options);
var strokeBuffer = [];
var replacementDiv = $(options.suggestions);
var replacementUl = replacementDiv.find(".suggestions").unbind(ns());
var replacementTyped = replacementDiv.find(".typed");
var replacements = [];
var mouseOnReplacement = null;
// When a user selects a replacement. We're guaranteed that
// index is valid for a replacement.
var selectReplacement = function(index) {
var decodedReplacement = decodeURIComponent(replacements[index]);
var caret = getInputSelection(self[0]);
var pos = caret.end;
var text = self.val();
// Insert the chosen suggestion at the current position.
var replacementText = text.substr(0, pos) + decodedReplacement + text.substr(pos);
self.val(replacementText);
// When you replace text, the cursor auto-jumps to the end.
// If you were in the middle of a string, that's annoying.
// This puts the cursor back to the character you were editing.
setCaretPosition(self[0], pos + decodedReplacement.length);
clearSelection();
};
// Hide and clear the replacement divs and suggestions.
var clearSelection = function() {
mouseOnReplacement = null;
strokeBuffer.length = 0;
replacements = [];
replacementUl.empty();
replacementTyped.empty();
//replacementDiv.hide();
};
// Sends a request to Google to get IME suggestions
var getReplacements = function() {
// Show or hide the replacement div (in case called backspace)
if (strokeBuffer.length > 0) {
replacementDiv.show();
} else {
clearSelection();
return;
}
var encodedText = encodeURIComponent(strokeBuffer.join(""));
replacementTyped.html(encodedText + ":");
$.ajax({
type: "GET",
url: "https://inputtools.google.com/request",
cache: false,
dataType: "json",
data: {
text: encodedText,
itc: languageToGoogleITC[options.language],
num: options.numResults,
// Google sets these values in its own AJAX calls, but they're
// cryptic and undocumented, so I'm passing them along.
cp: 0,
cs: 1,
// Input and output encoding
ie: "utf-8",
oe: "utf-8",
// Doesn't seem to matter what this is.
app: "test"
}
}).done(function(result) {
// The Google JSON result is terribly nested.
replacements = result[1][0][1];
var listElements = "";
// Ordered lists don't retain numbering when making the
// list horizontal with li{display:inline}
for (var i = 0; i < replacements.length; i += 1) {
listElements += "<li><span class='number'>" + (i + 1) + ".</span> " + replacements[i] + "</li>";
}
replacementUl.html(listElements);
});
};
// On delete/backspace, drop the last char from strokeBuffer,
// and update replacements
this.bind(ns("keydown"), function(e) {
if (e.which === 8 || e.which === 46) {
if (strokeBuffer.length !== 0) {
e.preventDefault();
strokeBuffer.pop();
getReplacements();
}
}
});
// Keypress on input gets more Google Input Tools suggestions
this.bind(ns("keypress"), function(e) {
var charCode = String.fromCharCode(e.charCode);
var index = parseInt(charCode, 10) - 1;
// Hit a number from 1 to replacements.length
if (!isNaN(index)) {
e.preventDefault();
if (index >= 0 && index < replacements.length) {
selectReplacement(index);
}
return;
}
// Hit [Space] or [Enter] -- just pick the first replacement.
if (charCode === "" || charCode === " ") {
if (strokeBuffer.length !== 0) {
e.preventDefault();
selectReplacement(0);
}
return;
}
// Hit any a-z character. Don't show the
// character in the input.
if (charCode >= "a" && charCode <= "z") {
e.preventDefault();
strokeBuffer.push(charCode);
getReplacements();
}
});
// When a user clicks a replacement with the mouse
replacementUl.on(ns("click"), "li", function(e) {
selectReplacement($(e.target).index());
});
// If the user focuses out of the input element, kill
// the suggestion box. But if they clicked on a suggestion,
// which also triggers an input.focusout event, set
// set the replacement and re-focus the input.
this.bind(ns("focusout"), function() {
if (mouseOnReplacement !== null) {
selectReplacement(mouseOnReplacement);
$(this).focus();
} else {
clearSelection();
}
});
replacementUl.on(ns("mouseover"), "li", function(e) {
var index = $(e.target).index();
mouseOnReplacement = index;
});
// Make it chainable.
return this;
}
// If the language is Latin-extended, we can use keystroke replacement
var reverseTrie = reverseTrieForLang(options.language);
this.bind(ns("keydown"), function(e) {
var text = self.val();
var code;
// The trie of replacements for this language.
var node = reverseTrie;
// The current caret start and end position.
var caret = getInputSelection(this);
var replacement = null;
// Number of keystrokes to 'erase' when replacing.
var sequenceLength = 0;
// On every keydown, add the keycode to the stack.
stack.push(e.which);
for (var i = stack.length - 1; i >= 0; i -= 1) {
code = stack[i];
// Don't count silent keys like [Shift] in sequence length.
if (!silentKeys.hasOwnProperty(code)) {
sequenceLength += 1;
}
node = node[code];
// Couldn't "recurse" because the sequence trail ends here.
if (node === undefined) {
break;
}
// Found a character replacement.
// Peek one more character, and if the sequence continues,
// don't use the replacement yet.
if (i > 0 && node.hasOwnProperty(stack[i - 1])) {
continue;
}
if (node.hasOwnProperty("r")) {
replacement = node.r;
break;
}
}
// Found a replacement sequence.
// Use it to replace the (sequenceLength) chars before current caret position
if (replacement !== null) {
e.preventDefault();
// TODO: Use a stack of length [max combo length for language];
// this one grows ad infinitum (er, ad successus), before clearing.
stack.length = 0;
var pos = caret.end;
var replacementText = text.substr(0, pos - sequenceLength + 1) + replacement + text.substr(pos);
self.val(replacementText);
// When you replace text, the cursor auto-jumps to the end.
// If you were in the middle of a string, that's annoying.
// This puts the cursor back to the character you were editing.
setCaretPosition(this, pos);
}
});
// Make it chainable
return this;
};
})(jQuery);
$(function() {
var lang;
function setLanguage(t) {
lang = t;
$("input#chatMessage").intlKeyboard({
language: t,
suggestions: "#suggestions",
numResults: 5 // default
});
}
$('#change').click(function() {
setLanguage(lang === 'es' ? 'en' : 'es');
$('#change').text($('#change').text().replace(/(English|Spanish)/g, lang === 'es' ? 'English' : 'Spanish'));
return false;
});
setLanguage('en');
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="chatMessage"></input>
<ul id="suggestions"></ul>
<button id="change">Change to Spanish</button>
&#13;
答案 1 :(得分:0)
我假设您的代码实际上初始化了#chatmessage元素上的插件。
要重新初始化,您可以调用代码以在事件上执行。在这种情况下,当用户单击#someElementID元素时,我将重新初始化它。您可以将其设置为您想要的任何元素或任何类型的事件。
$('#someElementID').off('click').on('click', function(){
$("input#chatMessage").intlKeyboard({
language: t,
suggestions: "#suggestions",
numResults: 5 // default
});
}
您可能还需要从页面中删除当前插件,在这种情况下,您可以使用类似
的内容$("input#chatMessage").html("");
之前打电话
$("input#chatMessage").intlKeyboard( ....
删除chatMessage元素中的所有内容。