我有一个看起来像这样的脚本:
function autoCorrect(searchString, replaceString) {
$("body").on("keyup", "textarea", function() {
// finds current cursor position
var pos = $(this).prop("selectionStart");
// this turns the textarea in a string
var text = $(this).val();
//only search for strings just typed
var stringToSearch = text.substring(pos - searchString.length, pos);
if (searchString == stringToSearch) {
//if there is a match put the replaceString in the right place
var newText = text.substring(0, pos - searchString.length) + replaceString + text.substring(pos);
$(this).val(newText);
//adjust the cursor position to the new text
var newpos = pos - searchString.length + replaceString.length;
this.setSelectionRange(newpos, newpos);
}
});
}
autoCorrect("=>", '⇒');
autoCorrect("->", "→");
autoCorrect("+-", "±");
autoCorrect("<=", "≤");
autoCorrect(">=", "≥");
现在,我想稍微改变它,我想改变函数运行的顺序。像这样:
$("body").on("keyup", "textarea", function() {
function autoCorrect(searchString, replaceString) {
// finds current cursor position
var pos = $(this).prop("selectionStart");
// this turns the textarea in a string
var text = $(this).val();
//only search for strings just typed
var stringToSearch = text.substring(pos - searchString.length, pos);
if (searchString == stringToSearch) {
//if there is a match put the replaceString in the right place
var newText = text.substring(0, pos - searchString.length) + replaceString + text.substring(pos);
$(this).val(newText);
//adjust the cursor position to the new text
var newpos = pos - searchString.length + replaceString.length;
this.setSelectionRange(newpos, newpos);
}
}
autoCorrect("=>", '⇒');
autoCorrect("->", "→");
autoCorrect("+-", "±");
autoCorrect("<=", "≤");
autoCorrect(">=", "≥");
});
但是这个脚本不再像这样了。我只是不明白为什么这会破坏我的代码。
这是我的jsfiddle:http://jsfiddle.net/4SWy6/4/
答案 0 :(得分:2)
新功能会创建一个新范围:
$("body").on("keyup", "textarea", function () {
autoCorrect("=>", '⇒', this);
autoCorrect("->", "→", this);
autoCorrect("+-", "±", this);
autoCorrect("<=", "≤", this);
autoCorrect(">=", "≥", this);
});
function autoCorrect(searchString, replaceString, elem) {
var acList = {
"=>": '⇒',
"->": "→",
"+-": "±",
"<=": "≤",
">=": "≥"
},
pos = elem.selectionStart,
text = elem.value,
stringToSearch = text.substring(pos - searchString.length, pos);
if (searchString == stringToSearch) {
var newpos = pos - searchString.length + replaceString.length;
elem.value = text.substring(0, pos - searchString.length) + replaceString + text.substring(pos);
this.setSelectionRange(newpos, newpos);
}
}
修改强>
基于评论,询问你是否可以传递一个键/值对的对象与元素一起被替换,我做了这个,这应该适用于你传递的任何对象:
$("body").on("keyup", "textarea", function () {
var acList = {
"=>": '⇒',
"->": "→",
"+-": "±",
"<=": "≤",
">=": "≥"
};
autoCorrect(acList, this);
});
function autoCorrect(acList, elem) {
var regstr = Object.keys(acList).join("|").replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$]/g, "\\$&"),
reg = new RegExp('('+ regstr +')', "gi"),
pos = elem.selectionStart,
diff = 0;
elem.value = elem.value.replace(reg, function(x) {
diff += x.length - acList[x].length;
return acList[x];
});
elem.setSelectionRange(pos-diff, pos-diff);
}
作为旁注,这不是真正的跨浏览器,因为selectionStart
和setSelectionRange
在所有浏览器中都不起作用,Object.keys
也不起作用,因此根据您的浏览器而定需要支持,你可能需要填充这些方法。
答案 1 :(得分:1)
在内部函数中,$(this)
实际上并不是您正在寻找的jQuery对象。那是因为this
被设置为窗口对象。观察:
function outer() {
function inner() {
return this;
}
console.log(this, inner());
}
outer.call({ this: "is an object" });
这将记录:
{ this: "is an object" }
[Object Window]
JS的范围界定行为很奇怪。
this
非常神奇,你只能在它设置的地方真正信任它的价值。否则,它可能是window
。
.call
调用函数,并将this
设置为第一个参数,在本例中为{ this: "is an object" }
。这称为“绑定”。
这就是为什么在outer
中,this
指的是我们的对象。我们说outer
绑定到该对象。在inner
中,我们应该不信任this
,因为它没有明确地绑定到任何东西 - 所以它可能是window
。
与该例子类似:
$('body').on('click', function clickCallback() {
// `this` refers to the element that jQuery set it to,
// as it called the `clickCallback` function with .call(element)
$(this).css({ 'background-color': '#f00' });
// We now have a bright red background!
function changeColor() {
// `this` refers to `window`!!!
// We didn't bind it :(
$(this).css({ color: '#0f0' });
// Text color will not be changed!
}
changeColor();
});
在内部,jQuery使用.call
方法调用clickCallback
,将回调的this
绑定到被单击的元素。因此,我们面临与outer
和inner
函数完全相同的情况。
问题的解决方案是:1)将内部函数绑定到外部this
或2)保存外部this
以便在内部函数中使用。
通常你想要选择后者。首先,您需要始终.call
您的函数(autoCorrect.call(this, "=>", '⇒');
),这是丑陋的,或者使用.bind
一次(autoCorrect = autoCorrect.bind(this);
),但是也不酷,因为并非所有浏览器都支持函数的.bind
方法,而且它看起来更慢。
在你的情况下,选择后一种选择:
$("body").on("keyup", "textarea", function() {
// Store `this` for use in the inner function
var self = this;
function autoCorrect(searchString, replaceString) {
// `self` will now be the element we're looking for!
// finds current cursor position
var pos = $(self).prop("selectionStart");
// this turns the textarea in a string
var text = $(self).val();
// [...]
}
autoCorrect("=>", '⇒');
autoCorrect("->", "→");
autoCorrect("+-", "±");
autoCorrect("<=", "≤");
autoCorrect(">=", "≥");
});
答案 2 :(得分:0)
$("body").on("keyup", "textarea", function () {
$(this).val($(this).val()
.replace(/=>/g, "⇒")
.replace(/=>/g, "⇒")
.replace(/->/g, "→")
.replace(/\+-/g, "±")
.replace(/<=/g, "≥")
.replace(/>=/g, "≥"));
});