【问题标题】:Beating jQuery addiction: Which jQuery methods are easily translated into pure javascript? [closed]战胜 jQuery 上瘾:哪些 jQuery 方法很容易翻译成纯 javascript? [关闭]
【发布时间】:2010-10-23 17:28:08
【问题描述】:

被 jQuery 宠坏了,我现在将它包含到每个项目中,即使我只需要调用一次 $("#div).hide()$("#link").click()

我知道 jQuery 经常为您处理跨浏览器问题,但有时它只是原生 javascript 方法的便捷包装器。

所以我的问题是哪些 jQuery 方法可以很容易地被原生 javascript 替换?

【问题讨论】:

  • 要了解特定方法有多“简单”,您可以随时查看jquery source code。它不会咬你的。
  • 你应该完全放弃它并尝试使用 jQuery。哦,等等……$(this).hide();
  • @serg:元相关链接:meta.stackexchange.com/questions/392/…
  • 小心。 jQuery 的目的(作为包装 API)是为您提供跨浏览器兼容性。放弃 jQuery 会将兼容性的重担重新推给您。我觉得不值得……
  • @Piskvor "复制和粘贴不注明出处" 非常正确。遵守许可证是必不可少的。我总是归因,即使代码非常通用。

标签: javascript jquery


【解决方案1】:

这里是一些我使用的例子而不是 jQuery 方法(如果我不使用 jQuery):

  • $(node).css(values):

    function css(node, style) {
      if(node && node.style) {
        for(var key in style) {
            node.style[key] = style[key];
        }
      }
    }
    
  • $(node).show(): jQuery 在这里更加复杂,因为它还可以将显示值设置为例如inline.

    function show(node) {
      if(node && node.style) {
        node.style.display = "";
      }
    }
    
  • $(node).hide():另外,jQuery方法存储了之前的显示值。

    function hide(node) {
      if(node && node.style) {
        node.style.display = "none";
      }
    }
    
  • $(node).addClass(class)

    function addClass(node, cls) {
      if(node) {
        if(!node.className) {
            node.className = cls;
        }
        else if(node.className.indexOf(cls) == -1) {
            node.className = node.className + " " + cls;
        }
      }
    }
    
  • $(node).removeClass(class)

    function removeClass(node, cls) {
      if(node && node.className && node.className.indexOf(cls) >= 0) {
        var pattern = new RegExp('\\s*' + cls + '\\s*');
        node.className = node.className.replace(pattern, ' ');
      }
    }
    

这些方法应该是跨浏览器兼容的。 jQuery 方法通常提供更多选项,例如删除多个类,或者更复杂。
这取决于您的需求,是否需要“高级”功能。更简单的方法可能就足够了。例如,如果我知道我总是要隐藏div 元素,那么hideshow 方法就可以了。

更新:

根据您正在开发的浏览器(例如制作 Firefox 扩展),您甚至可以将 close 发送到 jQuery 的选择器引擎:document.querySelectorAll(selector)

【讨论】:

  • 对于show()hide(),我更喜欢从元素中添加或删除一个类(“隐藏”)。这让我完全不必担心“显示”值。 “.hidden”的 CSS 表示“display: none”,所以当你去掉“hidden”类时,它会恢复到以前的状态。
  • 你的类添加/删除例程也会被类名“apple”和“big-apple”混淆。最好通过在类名字符串的任一侧粘贴“\b”来构建一个正则表达式,并且(如果你的类名可能很古怪)为正则表达式元字符擦洗它。
  • 有许多 CSS 属性会失败,例如 floatopacity。此外,当一个类是另一个类的前缀时,addClass/removeClass 会失败(尽管这很容易修复),并且对于可见性显示失败:隐藏和显示除块之外的任何其他元素的元素。
  • 你的 show 方法会更好:node.style.display = ""; 所以即使它不像 jQuery 那样恢复以前的值,它也会使用元素的默认显示类型。
  • @roasted: 不,className 是一个字符串,而不是一个数组。
【解决方案2】:

最大的 jQuery 滥用之一是创建一个 jQuery 对象,仅用于使用 .attr() 获取元素的属性。

也许最常见的是使用以下方法获取 ID 属性:

$(this).attr("id");

而不是

this.id;

有很多属性可以在不使用 jQuery 的情况下以跨浏览器的方式访问。

或者,如果我需要访问处理程序中元素的父级,而不是:

$(this).parent()...

我更有可能直接用以下方式包装父级:

$(this.parentNode)...

如果您可以规划您的 HTML 以使您的元素之间没有空白,您可以轻松地以跨浏览器的方式使用其他 DOM 遍历方法,例如:

this.nextSibling
this.previousSibling
this.firstChild
this.lastChild

【讨论】:

  • 我不同意。 attr() 仅适用于元素的属性,而不适用于节点的属性,因此它更等同于 setAttribute/getAttribute。此外,它提供了比本地方法更多的功能。遍历方法也有不同的行为,例如(空)文本节点的统一跨浏览器处理。
  • @Dr.Molle - 关于遍历,我通过说 “如果你可以规划你的 HTML 使得你的元素之间没有空格”来限定它。。这消除了空文本节点问题。关于.attr() 仅适用于属性的评论,我认为这是不正确的。我认为这是一种通用的方法,可以抓住任何一个。尝试设置一个 expando 并使用 .attr() 来获取值。它会为您检索它,而getAttribute() 不会。无论如何,这并没有改变我的观点,即您不需要 jQuery 以跨浏览器的方式访问许多属性。
  • 这不是空格的问题,jquery 的遍历方法会忽略 textNodes,这很好(通常你使用元素节点)。你可以看看jsfiddle.net/doktormolle/FWwfs。因此,每次使用 DOM 遍历方法和属性时,您都需要一种绕过文本节点的过滤器功能,...恕我直言,这不再容易了。但是我当然同意你的观点,你不应该只使用 jQuery 来获取某些属性或设置某些东西的颜色。
  • 我经常看到(甚至我自己也这样做过)使用$(this).val() 而不是this.value
  • @Peter - 是的,我花了一段时间才改掉这个习惯。 IE6 对<select> 列表存在问题,其中<option> 元素没有value 属性,但除此之外它是安全的。
【解决方案3】:

找出答案的最简单方法是阅读the source code,了解您感兴趣的方法。可读性很强。

【讨论】:

  • “非常易读”除了最简单的方法之外,您还需要很好地掌握 jQuery 中使用的底层框架,以了解这些方法的实际作用以及它如何确保跨浏览器兼容性。我认为普通的 javascript 编写者会迷路。
【解决方案4】:

(我喜欢“击败 jQuery 上瘾”)

我曾经发布过一个关于width() and height() and animation without jQuery 的问题并回答了自己。如您所见,这并不简单,但无论如何都是可行的。

【讨论】:

    【解决方案5】:

    对我来说,$.each 实用程序通常可以替换为for..in 语句:

    $.each (object, function () {
        // do something with this
    }
    

    对比

    var current;
    for (key in object) {
        current = object[key];
        // do something with current
    }
    

    $.each 的唯一附加功能是它创建了一个新范围,允许您拥有更多本地化变量:

    var someVar = 'original string';
    $.each (object, function () {
        // do something with this
        var someVar = 'new string';
    }
    console.log(someVar); // 'original string'
    

    但是,您可以使用 for..in 使用自执行函数来复制它:

    var someVar = 'original string';
    for (key in object) {
        (function() {
            var current = object[key],
                someVar = 'new string';
        })();
    }
    console.log(someVar); // 'original string'
    

    【讨论】:

    • $.each() 也适用于数组,您应该区分这一点,因为您应该使用for...in 循环来迭代数组。
    • for..in 在使用 Object 原型时会以丑陋的方式失败,而 $.each 不会。
    【解决方案6】:

    .toggle() 可以相对容易地重新创建,尤其是只有 2 个状态的那个(3+ 个状态需要更多的工作:

    $(function() {    
        $(selector).each(function() {
            var counter = 1;
            $(this).click(function() {
                counter++ % 2 ? 
                    (function() { $("div").html("one"); }());  // <== First function
                    (function() { $("div").html("two"); }());  // <== Second function
            });
        });
    });
    

    Try it out with this jsFiddle


    以上等价于

    $(selector).toggle(function() { ... }, function () { ... });
    

    【讨论】:

    • 你的例子并不总是符合预期,它不等同:jsfiddle.net/doktormolle/gquKG/1
    • @Dr.莫勒——没错。已编辑。我只是想展示如何使用条件运算符进行切换。
    【解决方案7】:

    这是一个小型 Miniframework:JavaScript Miniframework

    ;)

    【讨论】:

      【解决方案8】:

      我不知道任何可以轻松替换的 jQuery 方法(而且我认为没有),如果“简单”应该意味着 jQuery 方法与本机方法相同的话另一个名字。

      例如,请参阅 hide() 文档。
      它不只是将显示设置为“无”,它还存储当前的显示属性(如果您想稍后再显示它,这很有用)。 如果没有 jQuery,你可以在哪里存储显示?作为全局变量?...最好不要。

      【讨论】:

      • -1 只是因为你不知道如何做到这一点,不要以为不可能优雅地做到这一点......
      • 给我一个“简单”翻译的例子,它完全可以做相应的jQuery方法可以做的事情!我可以在这里评论每个提供的“简单”解决方法并告诉你,为什么它不一样。只要不一样,就不容易翻译,因为你无法比较。如果你尝试 1:1 翻译它,你很快就会发现你的简单翻译要复杂得多。请记住:我们谈论的是“简单”和“跨浏览器”,而不是“不知何故”。到目前为止,我在这里看到的所有翻译都只翻译了 jQuery 功能的一部分。
      • @Dr.Molle:确实如此。我想说这是(至多)两个选项的选择:{easy,cross-browser,not-framework}。尝试自己做 jQ 容易做的事情是一种很好的学习(和谦卑)的经历。 (在我的例子中,通常以“我想知道我在 2000 年代没有因为无数浏览器怪癖而发疯”而终止)
      • @galambalazs:跨浏览器 JavaScript 很少优雅或简单(尤其是如果它必须在 9 年前的浏览器中工作 - 你为 Netscape Navigator 4.78 编写代码多吗?是的,不这么认为. 然而 IE6 仍然是不死的,尽管是同龄人。)。如果不是因为 OP 对“轻松”的要求,可能会有一些可能性(如在其他答案中所见 - 请注意,提供的 sn-ps 并不完全简单,或者不考虑各种浏览器的脑死问题)跨度>
      • 好吧,你心爱的 jQuery 在里面做了一堆不可模仿的糟糕事情,有时甚至 jresig 都不确定作用域链是如何工作的 bit.ly/9Ucqa6,选择器引擎就是其中之一最糟糕的和“被设计破坏”bit.ly/c0ZliK、bit.ly/c3oiQK、bit.ly/99xQLS 但继续梦想你的圣杯是 100% 防弹的...... Netscape Navigator?让我休息一下。 :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 2018-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多