在 jQuery 插件中实现 $(this)
Posted
技术标签:
【中文标题】在 jQuery 插件中实现 $(this)【英文标题】:Implementing $(this) in a jQuery plugin 【发布时间】:2014-07-17 05:59:36 【问题描述】:我一直在寻找在 jQuery 中开发一个长点击插件来处理这样的事件,经过大量研究,我找到了最好的方法。我在下面创建了插件。它不是一个大文件,但它涵盖了我需要的内容。不过还是有一些问题...
$(function($)
var holdTimer;
$.fn.longclick = function( handler, time )
if(time == undefined) time = 500;
return this.mouseup(function()
clearTimeout(holdTimer);
).mousedown(function()
holdTimer = window.setTimeout(handler, time);
);
;
$.fn.longclick.defaultTime = 500;
(jQuery));
下面,我有测试它的页面:
// some markup
<input type="button" name="button3" id="button3" value="1500ms">
// and... the script itself
$("#button3").longclick( function()
var initial_text = $("#button3").val();
console.log( $(this) );
var initial_id = $(this).attr("id"); console.log( initial_id);
var initial_html = $(this).html(); console.log(initial_html);
$("#button3").replaceWith('<input type="textbox" id="" value=' + initial_text + '>');
, 1500);
现在,我的插件的问题似乎是它不知道$(this)
是什么意思。当我 console.log
$(this)
它返回窗口本身,而不是我需要的按钮......另外,initial_id
和 initial_html
是 undefined
。 我怎样才能完成这项工作?
更新:initial_html
变量在我的例子中应该是 <input type="button" name="button3" id="button3" value="1500ms">
。 jQuery.html()
不会像我预期的那样工作,说 $(this).html()
。 如何获取元素的 HTML?
【问题讨论】:
将控制台日志更改为警报。即 alert(initial_id) 和 alert(initial_html) 这将如何改变任何事情? 这会在警告框中显示一个准确的值。 除非我遗漏了什么,否则您的方法存在严重问题。如果我在按钮上mousedown
然后将鼠标从该按钮上移开并mouseup
怎么办?这不会在不应该触发的情况下触发长按吗?
如果你知道的话,你可以想出一个更好的方法:)
【参考方案1】:
在setTimeout
内部,this
的值始终是窗口,而您正在从 setTimeout 函数的范围内调用回调。
$(function ($)
var holdTimer;
$.fn.longclick = function (handler, time)
return this.on(
mouseup : function ()
clearTimeout(holdTimer);
,
mousedown : function ()
var self = this;
holdTimer = window.setTimeout(function()
handler.call(self);
, time || $.fn.longclick.defaultTime);
);
;
$.fn.longclick.defaultTime = 500;
(jQuery));
您必须获取事件处理程序正在处理的元素,否则回调将应用于所有元素,请参阅此FIDDLE 以获取有关不如何工作的示例。
【讨论】:
不一样,这在点击元素的回调中设置this
,你在整个集合的回调中设置this
,而你的只是一个编码转储,直到你更新它,我在小提琴中进行了一些缓慢的测试,以确保这是问题所在,并写了一个正确的答案。
@adeneo 在mousedown
的回调中设置self
的用例是什么?
@IonicãBizãu - 嗯,只影响当前元素,并不是所有的元素都是我想的用例?【参考方案2】:
当您执行setTimeout(handler, time)
时,将从window
调用handler
(this
将等于window
)。
因此,当您初始化插件实例时,您必须将 this
保存到 $self
(它是一个 jQuery 对象)中。然后你必须这样做,而不是 setTimeout(handler, time)
:
holdTimer = window.setTimeout(function ()
handler.call($self);
, time);
编辑后的插件是:
$(function($)
var holdTimer;
$.fn.longclick = function( handler, time )
var $self = this;
if(time == undefined) time = 500;
return this.mouseup(function()
clearTimeout(holdTimer);
).mousedown(function()
holdTimer = window.setTimeout(function ()
handler.call($self);
, time);
);
;
$.fn.longclick.defaultTime = 500;
(jQuery));
关于旧元素的 HTML,jQuery.html()
采用内部 HTML。您需要outerHTML
。所以,你可以这样理解:$(this)[0].outerHTML
。
var initial_html = $(this)[0].outerHTML;
console.log(initial_html); // <input type="button" name="button3" id="button3" value="1500ms">
JSFIDDLE
【讨论】:
以上是关于在 jQuery 插件中实现 $(this)的主要内容,如果未能解决你的问题,请参考以下文章