我试图为 HTML设置一个点击回调,导致另一个节点变得可见.一路上,我惊讶地发现,以下两个语句不是等效的:
$("#title").click($("#content").toggle);
$("#title").click(function() {
    $("#content").toggle();
}

第一个语句最终导致一个TypeError,当元素最终被点击时,消息“undefined不是一个函数”,我猜测说,无论我被分配给onclick回调最终都是未定义的,不知何故坚持记忆

解决方法很简单(只需使用第二种形式的语句),但是我真正想要了解的是为什么在切换函数最终被调用时,将toggle函数作为对象传递不起作用.我可以看到两者在语义上是不同的:第一个在绑定事件时执行$(“#content”)调用,另一个在事件发生时执行它,但是我不明白为什么这么重要.

在与答案相关的情况下,所涉及的代码位于函数内部(假定用户可以点击任何内容的时候返回).

解决方法

jQuery函数,就像这样 – > $(),只是一个功能,认为它是
var $= function(selector,context) {
   // do stuff with selector etc
}

这真的很简单,但是当您使用有效的选择器调用jQuery函数(如$())时,它会获取DOM节点并返回此类.

[
    0        : <div id="title"></div>,context  : document,selector : "#title",jquery   : "1.11.0",.....
    etc
]

这是jQuery返回的数组样对象,你可以看到0是本机的DOM节点,这就是为什么我们可以做$(‘#title’)[0]得到本机DOM节点的原因.

然而,有一个真正从一个简单的console.log看不到的东西,这是原型到这个数组的对象的方法,但是我们可以使用一个for..in循环来在控制台中看到它们.

var title = $('#title');

for (var key in title) 
    console.log(key)

FIDDLE

这将返回该对象上可用的所有原型和非原型方法的长列表

get
each
map
first
last
eq
extend
find
filter
not
is
has
closest
....
etc

请注意,这些都是使用$.prototype添加到$()函数中的所有jQuery方法,但jQuery使用较短的名称$.fn,但它也是一样的.

所以我们知道的所有jQuery函数都被添加到主要的$()函数作为属性,而new关键字在内部使用返回一个新的实例的$()函数与这些原型属性,这就是为什么我们可以使用点符号,或者对于这个事情,括号符号和链接到$()函数的方法,像这样

$().find()
// or
$()[find]()

当使用这样的原型属性扩展对象时,它的值也在方法中设置,所以现在我们了解一下它的工作原理,我们可以重新创建一个非常简单的jQuery版本

var $= function(selector,context) {
    if (this instanceof $) {

        this.context = context || document;
        this[0]      = this.context.querySelector(selector);

        return this;

    }else{

        return new $(selector,context);

    }
}

这很简单,jQuery的工作原理很多,但原则上它是一样的,当$()被调用时,它会检查它是否是一个自身的实例,否则它会使用新的关键字创建一个新的实例并再次调用一个新的实例.
当它是一个新的实例时,它会获取所需的元素和其他属性,并返回它们.

如果我们以某种方式对该实例进行原型化,那么我们可以像jQuery那样将其链接起来,所以让我们尝试一下

$.prototype.css = function(style,value) {
    this[0].style[style] = value;
}

现在我们可以做到这一点

$('#title').css('color','red');

我们几乎创建了jQuery,只有10000行代码去.

FIDDLE

注意我们如何使用这个[0]来获取元素,当我们使用像点击这样的东西时,我们不必在jQuery中这样做,我们可以使用这个,那么这样做是如何工作的?

让我们简化这一点,因为了解为什么问题中的代码不起作用至关重要

$.prototype.click = function(callback) {
    var element = this[0]; // we still need [0] to get the element

    element.addEventListener('click',callback.bind(element),false);
    return this;
}

我们在这里做的是使用bind()来设置回调函数中的值,所以我们不必使用这个[0],我们可以简单的使用这个.

FIDDLE

现在这很酷,但现在我们不能再使用我们创建和原型化对象的任何其他方法,因为这不再是对象,它是DOM节点,所以这样做失败

$('#element').click(function() {
     this.css('color','red'); // error,<div id="element".. has no css()

     // however this would work,as we Now have the DOM node
     this.style.color = 'red';
 });

它失败的原因是因为我们现在拥有本机DOM节点,而不是jQuery对象.

所以最后回答问题.
这样做的原因…

$("#title").click(function() {
    $("#content").toggle();
});

…是因为你调用了toggle()函数,并且设置了正确的值,在这种情况下,它将是包含#content的jQuery对象作为toggle()没有使用bind()的回调,简单地传递jQuery对象,一个类似于我们可以在这个答案的顶部看到的对象

内部toggle()

$.prototype.toggle = function() {
    this.animate();
}

看看它如何直接使用它,除了调用另一个jQuery函数之外,还需要它是一个jQuery对象,而不是本机的DOM元素.

让我们重复一遍,toggle()要求在函数内部是一个jQuery对象,它不能是jQuery对象以外的任何东西.

现在让我们再次点击,再次点击

$("#title").click(function() {
     console.log(this)
});

控制台将显示本机DOM元素,类似于< div id =“title”>< / div>

现在我们可以引用一个命名函数

$("#title").click(myClickHandler);

function myClickHandler() {
     console.log(this)
});

并且结果将完全一样,我们将在控制台中获取本机DOM元素 – > < div id =“title”>< / div>,这不是惊奇的,因为这与使用匿名功能的上述完全相同.

你正在做的是引用这样的toggle()函数

$("#title").click($("#content").toggle);

它与上面的例子完全一样,但是现在你引用了toggle(),当被调用时,它将使用该集合的值被调用到点击函数中的本机DOM元素,它将像这样

$("#title").click($("#content").toggle);

    $.prototype.toggle = function() {
        console.log(this); // would still be <div id="title"></div>

        this.animate(); // fails as <div id="title"></div> has no animate()
    }

这是正在发生的事情,toggle()期待这是一个jQuery对象,而是它获取了点击处理程序中元素的本机DOM节点.

再次阅读,这里面的toggle()函数将是本机的#title元素,这甚至不是正确的元素,因为这是javascript和jQuery的工作原理,请参阅上面关于如何在原型方法中设置的长的解释等等

JavaScript – 持久化的JQuery函数的更多相关文章

  1. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS 10 Safari问题在DOM中不再包含元素

    使用此链接,您可以重现该错误.https://jsfiddle.net/pw7e2j3q/如果您点击元素并从dom中删除它,然后单击链接测试.你应该看到旧的元素弹出选择.是否有一些黑客来解决这个问题?解决方法我能够重现这个问题.问题是,每当您尝试删除其更改事件上的选择框时,iOS10都无法正确解除对选择框的绑定.要解决此问题,您需要将代码更改事件代码放在具有一些超时

  3. ios – Cordova 3.7在每个本机通话中复制iframe

    由于我已升级到Cordova3.7,每个本地调用都将一个新的iframe附加到DOM,如下所示.为了排除我现有的代码影响cordova的可能性,我尝试使用cordovaCLI创建一个新的代码,添加控制台插件,并在设备控制台中的setInterval循环中调用console.log().因此,我在DOM中收到了大量的iframe.我在iPad3,iOS7上尝试过使用xCode6构建应用程序.有没有人遇到这个问题?

  4. ios – AFNetworking自动持久化Cookie

    在ThisQuestion中说,AFNetworking在后台自动处理cookies,但是在Previous问题中,我遇到麻烦,在登录时在PHP服务器上保持会话.一旦关闭的应用程序,并回到会议已经没了.答案是保持像这样的cookie来解决问题:当我尝试做这样的事情时,这给我一个应用程序崩溃.当我登录时,我设置了NSUserDefault:这是错误的使用方法吗?谢谢.解决方法使用以下内容,这是保存和加载适用于我的Cookie的正确方法:希望有帮助!

  5. 在IOS9中的Cordova应用程序使用JQuery / Javascript的window.history问题

    在两个测试用例中唯一改变的是Cordova.js.解决方法我看到这是几个星期前,但我会发布这个,以防其他人遇到它.听起来它可能与iOS9中的哈希更改生成的导航事件有关.如果是这样,可以将其添加到index.html以禁用哈希侦听:

  6. iOS 5上的jQuery事件

    解决方法在Apple开发论坛上由一个人回答:我需要在将元素添加到DOM之后才绑定(),如下所示:

  7. android – 区别:SAX Parser,XPath,DOM,XMLPullParser

    ,但Dom允许您访问xml文件的任何部分,因为它将整个文件/文档保存在内存中.看到这个article,你可以通过阅读摘要得到你想要的.另请查看此link以查看不同xml解析器的性能

  8. android – Phonegap本地构建 – jquery ajax错误:readystate 0 responsetext status 0 statustext error

    解决方法您是否在索引文件中包含了内容安全元标记?

  9. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  10. 设置焦点到输入框和显示Android键盘使用jquery手机在pageshow

    我正在设置焦点到输入框,并显示Android键盘使用jquery手机网页显示.我从Web上尝试过很多选项.但是没有一个在模拟器和移动设备中都能按预期工作.这是代码:查找屏幕截图以供参考请咨询…解决方法对我有用的解决方案

随机推荐

  1. jquery-plugins – 是否可以使用猫头鹰旋转木马实现循环/无限轮播?

    我正在使用猫头鹰旋转木马,它的工作完美,除了它不支持循环/无限滚动.我没有搜索google和stackoverflow的想法,没有运气.有没有人在猫头鹰旋转木马上实现圆形/无限滚动?

  2. jQuery动态输入字段焦点

    我想使用以下jQuery向我的页面动态添加一个输入字段:在这样做之后,我希望输入字段具有闪烁的文本光标的焦点,所以我想在创建后立即输入.有人可以告诉我我该怎么办?

  3. jquery – 为什么$(window).height()这样错了?

    我试图获取当前浏览器的视口高度,使用但我得到的价值观太低了.当视口高度高达850px时,我从height()获取大约350或400像素的值.这是怎么回事?

  4. jquery – 如果在此div之外和其他draggables内部(使用无效和有效的还原选项),则可拖动恢复

    例如这样但是由于明显的原因,这不行.我可以说这个吗?

  5. 创建一个jQueryUI 1.8按钮菜单

    现在jQueryUI1.8已经出来了,我正在浏览更新,并且遇到了新的Buttonwidget,特别是SplitButtonwithadropdown的演示之一.这个演示似乎表明Buttonwidget可以在这里创建一个下拉菜单.作为讨论的问题,我想知道使用这个新的Button小部件来创建一个下拉菜单有什么方法.干杯.解决方法您必须在按钮下方列出一个列表,方式类似于此处为自动完成提供的演示:http

  6. 灰色divs使用JQuery

    我试图使用这个代码:为了淡出一大堆名为MySelectorDiv的div,唯一的是,它只会淡出第一个而不是所有的div,为什么呢?

  7. 使用jQuery动态插入到列表中

    我有两个订单列表在彼此旁边.当我从一个列表中选出一个节点时,我想按照字母顺序插入到另一个列表中.抓住的是我想要把一个元素放在另一个列表中,而不刷新整个列表.奇怪的是,当我插入到右边的列表中,它工作正常,但是当我插入到左边的列表中时,顺序永远不会出来.我也尝试将所有内容读入数组,并将其排序在一起,以防止children()方法没有按照显示顺序返回任何东西,但是我仍然得到相同的结果.这是我的jQuer

  8. 没有回应MediaWiki API使用jQuery

    我试图从维基百科获取一些内容作为JSON:但我没有回应.如果我粘贴到浏览器的地址栏,就像我得到预期的内容.怎么了?解决方法您需要通过添加&callback=?来触发具有$.getJSON()的JSONP行为?在querystring上,像这样:Youcantestithere.没有使用JSONP,你正在击中same-originpolicy,阻止XmlHttpRequest获取任何数据.

  9. jQuery Ajax请求每30秒

    我有这段代码,但是有些人在我的网站上的值可能会改变.我需要每30秒钟更新一次#financediv.这可以做吗解决方法您可以将代码放在单独的函数中,如下所示:然后每30秒建立一个定时器调用该函数:祝你好运!总结以上是DEVMAX为你收集整理的jQueryAjax请求每30秒全部内容。如果觉得DEVMAX网站内容还不错,欢迎将DEVMAX网站推荐给好友。

  10. jquery – keypress事件在IE和Chrome中不工作,但在FF工作

    任何想法为什么会这样发生?我通常认为Chrome会更加宽容代码?这是我的按键键.我错过了什么吗?右图();和leftimage();是应该工作的功能,因为我在其他地方使用这些功能谢谢您的帮助!

返回
顶部