【问题标题】:'Translation from jQuery to JavaScript''从 jQuery 到 JavaScript 的翻译'
【发布时间】:2015-02-27 20:48:59
【问题描述】:

我是一个自学并玩弄 javascript 的菜鸟,我偶然发现了那个叫做“正则表达式”的噩梦......我对它们有点了解,我一直在做一些花哨的事情,但是我被困住了,我希望你向我澄清这一点:

我一直在阅读并寻找一种创建匹配的方法,并且我得到了很好的答案:

/////////////////////////////////////// ///////////////////////////////////////// ///////////////////////////////////////// /////////////////

var $rows = $('#table tr');
$('#search').keyup(function() {

var val = '^(?=.*\\b' + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ').*$',
    reg = RegExp(val, 'i'),
    text;

$rows.show().filter(function() {
    text = $(this).text().replace(/\s+/g, ' ');
    return !reg.test(text);
}).hide();

});

/////////////////////////////////////// ///////////////////////////////////////// ///////////////////////////////////////// /////////////////

我有点明白那里发生了什么,但有人可以为我分解它并“用 javascript 翻译”,这样我就可以更好地理解这个想法,我几乎不能用 jquery 做很酷的事情,因为我还在学习 javascript,我知道一些关于 jqueries 的事情,但不足以完全理解他在那里做了什么,也不足以知道编写 taht 代码的人是个天才

这是我的理解,请纠正我:

var $rows = $('#table tr'); 

这是范围,是要在其中寻找匹配的“目标”

pd:那是我第一次看到'$' 来声明变量,而对于我所看到的,它将它设置为一个 jQuery 对象..是这样吗?

var val = '^(?=.*\\b' + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ').*$',
    reg = RegExp(val, 'i'),
    text;

'$.trim($(this).val()' 等于 $.trim($("#user_input").val()); ..... ..对吗?

reg = RegExp(val, 'i')

reg 变量作为构造函数来查找不区分大小写的匹配项,但它不应该是 'reg = new RegExp(val, 'i')' 或者我也可以设置吗?

这是我最困惑的时候

$rows.show().filter(function() {
        text = $(this).text().replace(/\s+/g, ' ');
        return !reg.test(text);
}).hide();

我能理解的是,只有通过 text 变量设置的过滤器才会显示匹配项,而没有通过的匹配项将被隐藏,我对 $ 的含义一无所知(this) 相当于....在 text 变量中.. 从那里我不知道发生了什么,我发现 .test() 返回 true 或 false当它在正则表达式对象中找到匹配项时,为什么它的开头有 !

【问题讨论】:

  • 大多数情况下,正则表达式字符串构造将一些字符串拆分为单词,然后通过断言将它们连接在一起。生成的字符串类似于 ^(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3).*$,在 word3 之后有点缺少 \b。正则表达式本身是对来自!reg.test(text);text 不包含任何 的验证(否定)。除此之外,我对JS不够了解。

标签: javascript jquery html regex


【解决方案1】:

$ 是 jQuery 对象,它只是一个指向 jQuery 的变量名。不用担心 $rows,这只是另一个变量名。

var $rows = $('#table tr'); 

右侧基本上是将选择器传递给 jQuery 并告诉它查找所有匹配它的 DOM 元素。如果您知道 CSS,这是相同的原理,#table 是一个带有 id="table" 的元素,并与 tr 结合表示选择该元素内的所有行(tr 是表格行 html 标记)。

在纯 javascript 中,这可以写成

var $rows = document.querySelectorAll("#table tr");

结果是一个元素列表。

然后你找到另一个元素,并附加一个事件监听器:

$('#search').keyup(function() { ... });

请注意,这是将另一个选择器传递给 jQuery,它返回所需的元素,并在其上附加一个 keyup 事件。在 JavaScript 中,这可能是:

document.getElementById("search").addEventListener("keyup", function() { ... });

当在元素上触发 keyup 事件时,函数将被执行,并且您正在构建一个字符串 val,其中包含:

... + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ...

$(this).val() 中的this 求值为#search 选择器找到的元素,在本例中为输入字段。

这可能是纯 javascript 中的以下内容:

... + document.getElementById("search").value.trim().split(/\s+/).join('\\b)(?=.*\\b') + ...

如果您评估该表达式,它会 1) 修剪空格,2) 将结果拆分为每个空格字符上的字符串数组,以及 3) 将该数组与分隔符 \\b)(?=.*\\b 连接起来

步骤 2) 和 3) 基本上是 String.replace(/\s+/, '\\b)(?=.*\\b') 但更快。

移到最后一点,jQuery show() 方法应用于 $rows 中的每个元素,这是在开头找到的元素列表(表格行)。这使得每一行都可见。

然后将过滤器方法应用于该列表,这是一个遍历元素列表的循环,调用每个元素上定义的函数。请注意,过滤器函数中的this 现在指的是正在测试的表格行,而不是搜索字段。

如果该过滤器函数在列表项上返回 true,则该项目保留在结果列表中,如果为 false,则将其删除。这里应用了准备好的 RegExp,如果它匹配,则函数返回 false。所以在过滤之后你有一个不匹配的元素/行列表,最后.hide()被应用,这是一个jQuery方法来隐藏所有调用它的元素。所以你隐藏了不匹配的行。

代码在“纯”javascript 中可能看起来像这样(它现在应该可以工作了,我修复了 cjsmith 在 cmets 中写的问题)。

var $rows = document.querySelectorAll("#table tr");
document.getElementById("search").addEventListener("keyup", function(e) {

  var val = '^(?=.*\\b' + e.target.value.trim().split(/\s+/).join('\\b)(?=.*\\b') + ').*$';
  var reg = RegExp(val, 'i');

  Array.prototype.forEach.call($rows, function(row) {
    var text = row.textContent.replace(/\s+/g, ' ');
    row.style.display = reg.test(text) ? 'table-row' : 'none';
  });

});

PS。新年快乐!

【讨论】:

  • 效果很好,我只需要将显示行更改为 elem.style.display = reg.test(text) ? “表行”:“无”;
【解决方案2】:

var $rows = $('#table tr');

这是范围,“目标”将在其中寻找 匹配

pd:那是我第一次看到'$'来声明变量和for 我看过它把它设置为一个 jquery 对象..是这样吗?

是的,$rows 是目标,但是符号的'$'实际上是没有意义的,这是jquery程序员的一种做法。最好记住一个 jquery 对象,“hımmm,这个开头有一个 '$',所以它一定是一个 jquery 对象”。

实际上var $rows = $('#table tr');var rows = $('#table tr'); -> 它们是相同的,$rowsrows 之间没有任何区别。

------------------------------------------ ----------------------------------------------

var val = '^(?=.\b' + $.trim($(this).val()).split(/\s+/).join('\b)(?=.\b') + ').*$', reg = RegExp(val, 'i'),

text; the '$.trim($(this).val()' is equal to $.trim($("#user_input").val()); .......right?

在 javascript 中,this 指的是事件的所有者。对于您分享的示例,this 用于$('#search') 的 keyup 回调函数,这意味着this 指的是$("#search")

------------------------------------------ ----------------------------------------------

reg = RegExp(val, 'i') reg 变量作为构造函数来查找 不区分大小写的匹配,但不应该是 'reg = new RegExp(val, 'i')' 或者我也可以设置?

this question对Javascript的新关键字有很好的解释,你可以查看。

------------------------------------------ ----------------------------------------------

$rows.show().filter(function() {
        text = $(this).text().replace(/\s+/g, ' ');
        return !reg.test(text);
}).hide();

我们一步一步来解释

var $rows = $('#table tr');
  • $rows 是一个 tr 对象数组
  • $rows.show() 表示显示表中的所有 tr 标签,其 id 为 #table。
  • jQuery is chainable,这意味着$rows.show() 再次返回$rows
  • 所以$rows.show().filter() = $rows.filter
  • 同样$rows仍然是一个tr对象的数组,所以$rows.filter()像for循环一样循环这个对象,为$rows中的每个对象处理回调函数。
  • 在回调函数中 this 指的是所有者,在本例中所有者是当时的对象,而过滤器正在循环 $rows。
  • 正如你所说,test() 返回一个布尔值。
  • !是逆变器,

    !true = false

    !false = true

【讨论】:

  • 感谢大家抽出宝贵的时间,我非常感谢您向我澄清这一点
【解决方案3】:

我会去的!古腾标签,尼禄!

我会从头到尾回答您的问题,看看我们是否可以解决问题。首先,您对 rows 变量的理解是正确的。它是一个 jquery 对象,其中包含与您的搜索字符串匹配的 DOM 对象数组。在这种情况下,tr 在一个表中。

您还正确设置了#user_input 部分。 keyup 函数中的 $(this) 是对最初引发事件的 DOM 对象的引用。在这种情况下,用户输入。

但不应该是 'reg = new RegExp(val, 'i')' 还是我也可以设置?

使用 new 关键字似乎更安全。如需进一步参考,请参阅此处:http://zeekat.nl/articles/constructors-considered-mildly-confusing.html。如果您仅依赖于类的“静态”部分,这可能没有必要 - 但我会说这比抱歉更安全。

现在是最难的部分:

$rows.show().filter(function() {
        text = $(this).text().replace(/\s+/g, ' ');
        return !reg.test(text);
}).hide();

$rows.show() 将使行 jquery 对象中的所有 DOM 对象可见。

然后在同一组对象上,它将“过滤”,这意味着它将根据返回布尔值的函数减少 var rows 中的 DOM 对象。在这种情况下,该函数是:

text = $(this).text().replace(/\s+/g, ' ');
return !reg.test(text);

用单个空格替换所有空格,然后测试它是否与您的正则表达式匹配。所以在这里,如果它没有通过你的正则表达式(!=逻辑NOT)它会留在集合中。

最后 - 此函数将隐藏通过过滤器的所有内容。

所以它会显示所有内容,然后隐藏与您的正则表达式不匹配的内容。

希望对您有所帮助! Habst ein guten neue Jahre(我的德语怎么样?)

【讨论】:

    猜你喜欢
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 2011-04-23
    • 2016-10-27
    • 1970-01-01
    • 2018-09-12
    • 1970-01-01
    相关资源
    最近更新 更多