JavaScript: 如何处理不断增长的数组中的内存?
JavaScript: How to handle memory in growing arrays?
我有一个相当简单的函数,它会在每次按下键盘时触发。它所做的是在一定条件下(句子很长)标记来自TinyMCE的输入文本,然后在TinyMCE编辑器中显示突出显示的文本。
乍一看,这很有魅力。但是随着文本数组的增长,函数的执行时间越来越长。
有没有什么绝妙的方法可以检测输入光标在文本中的位置,然后只分析周围的单词(例如可以是当前句子)并重用其余部分文字?
代码是这样的。
HTML
<div id="myTextArea" contenteditable="true">
Just put lorem ipsum here.
</div>
JavaScript (jQuery)
tinymce.init({
selector: '#myTextArea',
height: 300,
setup: function(ed) {
ed.on('change', myCustomInitInstance);
ed.on('keyup', myCustomInitInstance);
ed.on('paste', myCustomInitInstance);
ed.on('cut', myCustomInitInstance);
},
init_instance_callback: "myCustomInitInstance",
});
function myCustomInitInstance(inst) {
var rawText = tinyMCE.get('myTextArea').getContent({
format: 'text'
});
var sentenceArray = rawText.split(".");
var matchWarning = [];
var longSentence = 16;
var words;
var wordCounter;
var output;
for (var i in sentenceArray) {
words = sentenceArray[i].split(" ");
wordCounter = words.length;
if (wordCounter > longSentence) {
matchWarning.push(sentenceArray[i]);
}
}
var editor = tinyMCE.activeEditor;
// Store the selection
var bookmark = editor.selection.getBookmark();
// Remove previous marks and add new ones
$(editor.getBody()).unmark().mark(matchWarning, {
acrossElements: true,
"separateWordSearch": false,
});
// Restore the selection
editor.selection.moveToBookmark(bookmark);
}
欢迎就如何提高速度提出任何建议:)
我发现您的代码存在一个问题。每次写下一个字母时,使用 onchange
和 onkeyup
函数会触发回调两次。
您可以尝试以下几种方法:
- 如果您只是拆分成句子,为什么不等到“.”呢?写下来然后触发你的循环?
- 如果使用长度缓存,循环应该会更快,但如果数组很长,循环应该会更高效。
for (var i = 0, len = sentenceArray.length; i < len; i++)
你应该使用去抖功能。通过这种方式,您可以在定义的时间或每次键入或更改时触发循环一次。检查这个 David Walsh 的去抖功能:https://davidwalsh.name/javascript-debounce-function
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
这样,如果已经有另一个循环在执行,您的循环将不会执行,我认为这会耗尽您的性能。
干杯!
我有一个相当简单的函数,它会在每次按下键盘时触发。它所做的是在一定条件下(句子很长)标记来自TinyMCE的输入文本,然后在TinyMCE编辑器中显示突出显示的文本。
乍一看,这很有魅力。但是随着文本数组的增长,函数的执行时间越来越长。
有没有什么绝妙的方法可以检测输入光标在文本中的位置,然后只分析周围的单词(例如可以是当前句子)并重用其余部分文字?
代码是这样的。
HTML
<div id="myTextArea" contenteditable="true">
Just put lorem ipsum here.
</div>
JavaScript (jQuery)
tinymce.init({
selector: '#myTextArea',
height: 300,
setup: function(ed) {
ed.on('change', myCustomInitInstance);
ed.on('keyup', myCustomInitInstance);
ed.on('paste', myCustomInitInstance);
ed.on('cut', myCustomInitInstance);
},
init_instance_callback: "myCustomInitInstance",
});
function myCustomInitInstance(inst) {
var rawText = tinyMCE.get('myTextArea').getContent({
format: 'text'
});
var sentenceArray = rawText.split(".");
var matchWarning = [];
var longSentence = 16;
var words;
var wordCounter;
var output;
for (var i in sentenceArray) {
words = sentenceArray[i].split(" ");
wordCounter = words.length;
if (wordCounter > longSentence) {
matchWarning.push(sentenceArray[i]);
}
}
var editor = tinyMCE.activeEditor;
// Store the selection
var bookmark = editor.selection.getBookmark();
// Remove previous marks and add new ones
$(editor.getBody()).unmark().mark(matchWarning, {
acrossElements: true,
"separateWordSearch": false,
});
// Restore the selection
editor.selection.moveToBookmark(bookmark);
}
欢迎就如何提高速度提出任何建议:)
我发现您的代码存在一个问题。每次写下一个字母时,使用 onchange
和 onkeyup
函数会触发回调两次。
您可以尝试以下几种方法:
- 如果您只是拆分成句子,为什么不等到“.”呢?写下来然后触发你的循环?
- 如果使用长度缓存,循环应该会更快,但如果数组很长,循环应该会更高效。
for (var i = 0, len = sentenceArray.length; i < len; i++)
你应该使用去抖功能。通过这种方式,您可以在定义的时间或每次键入或更改时触发循环一次。检查这个 David Walsh 的去抖功能:https://davidwalsh.name/javascript-debounce-function
// Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the // leading edge, instead of the trailing. function debounce(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; };
这样,如果已经有另一个循环在执行,您的循环将不会执行,我认为这会耗尽您的性能。
干杯!