当`input`作为单个字母时搜索选择

时间:2015-02-17 08:20:02

标签: jquery html regex

我正在进行搜索并突出显示功能。当用户第一次输入时,一切正常。但是下一个keyup(在文本框中添加其他字母)功能不起作用。

我强烈反对,当我正在做“替换”时。 - 这是在文本上添加""双引号。所以regexp失败了......

如何处理这个问题?

更新

我更新了我的代码。它有点奏效。但问题是,如果有单词匹配,它只会选择one个字母。



var input = $('#keyWord');
	var origional = $('.container');
	var content = $('.container *');

	var highlight = function (str, className) {
	    var regex = new RegExp(str, "gi");

	    if(origional.find('.searchHighlight').length) {
			origional.find('.searchHighlight').replaceWith(function() {
				return $(this).contents();
			});
		}


	    content.each(function () {
	        $(this).contents().filter(function() {
	            return this.nodeType == 3 && regex.test(this.nodeValue);
	        }).replaceWith(function() {
	            return (this.nodeValue || "").replace(regex, function(match) {
	                return "<span class=\"" + className + "\">" + match + "</span>";
	            });
	        });
	    });
	};

	input.on('input', function(event) {
		event.preventDefault();
		var searchWrod = event.target.value;

		if(!searchWrod) {
			origional.find('.searchHighlight').replaceWith(function() {
				return $(this).contents();
			});
			return;
		}
	
		highlight(searchWrod, 'searchHighlight');
	});
&#13;
.searchHighlight{
    border:1px solid red;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
		
	<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolor error sint eaque ratione quasi a, ullam tenetur sed voluptas est nulla adipisci reiciendis libero nesciunt obcaecati! Repellat labore voluptatum numquam.</div>

	<div>Voluptates ipsum a at reiciendis iure nemo, inventore eligendi ut, ex necessitatibus similique dolore quae qui voluptatem, amet iste dolorum reprehenderit cum modi quibusdam unde asperiores. Magni laboriosam porro, repellat.</div>

	<div>Ducimus esse alias odit, ipsa iusto similique unde. Accusantium laudantium temporibus est nobis quaerat impedit facere aut eum quas, cupiditate, dignissimos reprehenderit quia deserunt similique illum unde dolor dolorem harum.</div>

	<div>Culpa rerum optio labore vero reprehenderit nulla laborum ducimus ipsum, animi fugiat, at, ipsa maiores. Consectetur doloremque, quia praesentium excepturi tempore, quisquam delectus dolorum aliquid reprehenderit cumque earum. Distinctio, voluptatibus?</div>

	<div>Quis quos, iste placeat rerum facere dolorum deleniti natus architecto dolores possimus recusandae, alias esse sapiente sequi. Recusandae animi itaque iste, quas, nisi at, deserunt expedita, praesentium veniam numquam adipisci.</div>

	<div>Ducimus itaque corporis perspiciatis consequatur ut saepe unde non voluptates, debitis, eum similique nobis fugiat sunt illum ipsa accusamus asperiores animi? Amet quas animi odit nam accusantium excepturi cum, error.</div>

	<div>Nam mollitia esse eligendi saepe, ipsa soluta, repellat ullam perspiciatis nisi nemo quos quas alias molestiae nulla, obcaecati deleniti asperiores cumque illo dolore! Minus dolorem, voluptate reiciendis, distinctio consequuntur esse?</div>

	<div>Iure blanditiis quis cumque quo rem expedita fugit soluta ullam? Possimus quia ratione alias amet vitae, a voluptatem, repellendus dolor neque? Eos vitae laborum, architecto mollitia temporibus eius maiores nobis?</div>

	<div>Assumenda quod soluta odio harum unde blanditiis ab odit sapiente ducimus quidem recusandae molestias porro placeat corrupti, obcaecati nostrum quasi ex repudiandae earum omnis ipsum architecto neque quas rerum. Maxime.</div>
	
	<div>Amet expedita magnam at alias praesentium, doloremque tenetur facilis dolor itaque necessitatibus eum ducimus repudiandae, nobis corrupti sequi eveniet voluptatum. Enim, id nostrum iste animi cupiditate totam. Voluptas, aliquid, dolorem.</div>

	<div class="row">
		<input type="text" name="keyword" id="keyWord">
	</div>

	</div>
&#13;
&#13;
&#13;

如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

我用原始代码编写了答案,但将CSS border更改为outline,因此文字在输入时不会跳转。

你的问题是当你替换第一个字母的高亮显示时,textNode会被&#34;切断&#34;成为碎片。即使删除你放在它周围的<span>,也不会将textNodes连接回一个大的textNode。

因此,搜索P表示内容PageMaker会被切换为<span>P</span>ageMaker。然后,当您搜索Pa时,会删除<span>,但代码仍会在2个单独的节点PageMaker中进行搜索。它们都不包含Pa,因此不会突出显示任何内容。

只需$("#test").html($("#test").html());解决此问题。

除此之外,我更改了keyup中的顺序,因此当有空搜索查询时,突出显示会被删除。我还添加了一个替换输入字符串,以转义在正则表达式中被解释为特殊字符的任何字符。在原始代码中,搜索y.将被解释为正则表达式,意思是&#34;搜索 y ,然后除了换行符之外的任何字符。&#34; 因为它是正则表达式中.的含义。转义这些字符可以解决这个问题。

&#13;
&#13;
var highLighter = function (str) {
    var regex = new RegExp(str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), "gi");
    $('#test *').each(function () {
        $(this).contents().filter(function() {
            return this.nodeType == 3;
        }).replaceWith(function() {
            return (this.nodeValue || "").replace(regex, function(match) {
                return "<span class='highlight'>" + match + "</span>";
            });
        });
    });
}



$('#keyWord').on('input', function (e) {
    var text = e.target.value;
    $(".highlight").replaceWith(function() { return $(this).text(); });
    $("#test").html($("#test").html()); // concatinates adjacent text-nodes back to a single text-node
    if(!text) return;
    highLighter(text);
});
&#13;
.highlight{
  outline:1px solid red;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
    <div id="test">
    <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
    <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
</div>
</div>


<input type="text" id="keyWord" />
&#13;
&#13;
&#13;

答案 1 :(得分:1)

在这种情况下,一种方法是循环播放儿童主要文字持有人的文字#test,然后用.highlight中包含的搜索文字替换儿童的html

&#13;
&#13;
$('#keyWord').on('input', function (e) {
    var text = $(this).val();
    // escaping string for use in regex
    text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    var re = new RegExp(text, 'gi');
 
    $('#test').children().each(function () {
        // if no text input clear out previous .highlight spans
        if(!text){
            $(this).html($(this).text());
            return;
        }
        // if match for regex insert .highlight class
        $(this).html($(this).text().replace(re, function(match){
            return '<span class="highlight">'+ match   +'</span>';
        })); 
    });
});
&#13;
.highlight{
    border:1px solid red;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
    <div id="test">
    <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
    <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
</div>
</div>


<input type="text" id="keyWord" />
&#13;
&#13;
&#13;