Automatically insert string while user is typing

时间:2015-05-24 20:57:46

标签: javascript

In Preferences: Code Hints, Dreamweaver has this option:

Close tags: After typing the open tag's ">"

I am teaching html to students and have them write code in a textarea, (which isn't the greatest UI but is at least on my own website).

I'd like to insert the closing tag as soon as the user types the ">" to end the opening tag and keep the position of the cursor between the opening and closing tags.

;(function() {
	var Variables = {}
	Variables.greaterThan = false
	$('[name=GuessName]').keypress(keypress)
	function keypress(myEvent) {
		if (myEvent.which === 62) {
			Variables.greaterThan = true
		}
	}
	$('[name=GuessName]').keyup(keyup)
	function keyup(myEvent) {
		if (Variables.greaterThan) {
			var myTextarea = $(this).val()
			var startingPosition = -1
			var length = myTextarea.length-1
			for (var i=myTextarea.length; i>= 0; i--) {
				if (myTextarea.substr(i,1) === '<') {
					startingPosition = i
					break
				}
			}
			if (startingPosition > -1) {
				myTextarea += '</' + myTextarea.substr(startingPosition+1,length)
				$(this).val(myTextarea)
			}
			Variables.greaterThan = false
			// position the cursor at the appropriate spot
		}
	}
})()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Enter &lt;h1>
<textarea name="GuessName"></textarea>

2 个答案:

答案 0 :(得分:1)

我选择提供一个vanilla javascript响应,现场演示可以在这里找到:https://jsfiddle.net/Tomboyo/f8nLfwmn/6/

首先,我们将一个事件监听器附加到绑定到'keyup'事件的textarea。触发事件时,它使用getStrPos函数找到当前光标位置(实际上只是在下面链接的文章中找到的函数的修改后的剪切)。然后我们将文本放在光标位置的左侧(但是左边只有50个字符,因为我们不希望html标签那么长,坦率地说,我们不希望运行正则表达式搜索一大堆文字。)

此块中的'this'关键字指的是textarea:

    var pos = getStrPos('myArea');
    var retrotext = this.value.slice(Math.max(0, pos - 50), pos);
    var m = retrotext.match(/(?:<\/?)([^<>]+)(?:>)/g);

脚本中接下来定义的blacklist变量列出了不应关闭的标记的名称(例如<br><input>标记)。该清单目前尚未详尽无遗;根据您的需要更新它。

var blacklist = ['input', 'br', 'hr'];

此最后一节修剪与黑名单条目匹配的所有找到的标签,并防止将结束标签插入已关闭的标签。我们假设所有标签在用户输入时都会关闭,因此如果前面的标签是结束标签,则光标放错位置或'&gt;'在这种情况下,字符是错误的。 insertAfterCaret功能是我在网上找到的。我之前提到getStrPos是基于这个函数的,所以从我在这个答案的脚下引用的文章中可以看出对两者的理解。

    } else {
        //blacklist pruning
        for (var i = 0; i < blacklist.length; i++) {
            if (m[m.length - 1] == '<'+blacklist[i]+'>') {
                return;
            }
        }
        insertAfterCaret('myArea', m[m.length - 1].slice(0, 1) + "/" + m[m.length - 1].slice(1));
    }

可以在此处找到Cursor(和衍生物)的插入: http://web.archive.org/web/20110102112946/http://www.scottklarr.com/topic/425/how-to-insert-text-into-a-textarea-where-the-cursor-is/

<强>更新 第六个修订版阻止用户在编辑内部时重新关闭已关闭的标记。它现在进行前向检查(最多50个字符),以找到与左侧开始标记匹配的结束标记。如果有的话,'&gt;'被输入可能是错误的,因此不会插入标签。

        var anterotext = this.value.slice(pos, Math.min(pos + 50, this.value.length));
        var closeTag = m[m.length - 1].slice(0, 1) + "/" + m[m.length - 1].slice(1);
        var n = anterotext.match(closeTag);
        if (n) { return; }
        insertAfterCaret('myArea', closeTag);

答案 1 :(得分:0)

;(function() {
	var Variables = {}
	Variables.greaterThan = false
	$('[name=GuessName]').keypress(keypress)
	function keypress(myEvent) {
		if (myEvent.which === 62) {
			Variables.greaterThan = true
		}
	}
	$('[name=GuessName]').keyup(keyup)
	function keyup(myEvent) {
		if (Variables.greaterThan) {
			selectionStart = this.selectionStart
			var myTextarea = $(this).val()
			var startingPosition = -1
			for (var i=selectionStart; i>= 0; i--) {
				if (myTextarea.substr(i,1) === '<') {
					startingPosition = i
					break
				}
			}
			if (startingPosition > -1) {
				firstHalf = myTextarea.substr(0,selectionStart)
				middle = '</' + myTextarea.substr(startingPosition+1,selectionStart-startingPosition-1)
				secondHalf = myTextarea.substr(selectionStart,999)
				myTextarea = firstHalf + middle + secondHalf
				$(this).val(myTextarea)
			}
			Variables.greaterThan = false
			this.setSelectionRange(selectionStart,selectionStart)
		}
	}
})()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Enter &lt;h1>
<textarea name="GuessName"></textarea>