javascript 在 jquery 插件中获取初始选择器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5477394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting initial selector inside jquery plugin
提问by eek meek
I got some help earlier regarding selectors, but I'm stuck with the following.
我之前得到了一些关于选择器的帮助,但我坚持以下几点。
Lets say you have a plugin like this
假设你有一个这样的插件
$('#box').customplugin();
how can I get the #box as a string in the plugin? Not sure if that's the correct way of doing it, and any other solution would be great as well.
如何在插件中将#box 作为字符串获取?不确定这是否是正确的做法,任何其他解决方案也会很棒。
Considering #box is a select dropdown,
考虑到#box 是一个选择下拉菜单,
The problem I'm having is if I do the regular javascript
我遇到的问题是,如果我使用常规的 javascript
$('#box').val(x);
The correct option value gets selected,
选择了正确的选项值,
but if i try the same inside a plugin
但如果我在插件中尝试同样的方法
.....
this.each(function() {
var $this = $(this);
$this.val(x);
the last code doesn't really do anything.
最后的代码并没有真正做任何事情。
I notice I'm having trouble targeting #box inside the plugin because it's a object and not a string...
我注意到我在插件中定位 #box 时遇到问题,因为它是一个对象而不是字符串......
Any help would be appreciated.
任何帮助,将不胜感激。
Thanks!
谢谢!
Edit:: Putting in the code I'm working in for better understanding
编辑::放入我正在使用的代码以便更好地理解
(function($){
$.fn.customSelect = function(options) {
var defaults = {
myClass : 'mySelect'
};
var settings = $.extend({}, defaults, options);
this.each(function() {
// Var
var $this = $(this);
var thisOpts = $('option',$this);
var thisSelected = $this[0].selectedIndex;
var options_clone = '';
$this.hide();
options_clone += '<li rel=""><span>'+thisOpts[thisSelected].text+'</span><ul>'
for (var index in thisOpts) {
//Check to see if option has any text, and that the value is not undefined
if(thisOpts[index].text && thisOpts[index].value != undefined) {
options_clone += '<li rel="' + thisOpts[index].value + '"><span>' + thisOpts[index].text + '</span></li>'
}
}
options_clone += '</ul></li>';
var mySelect = $('<ul class="' + settings.myClass + '">').html(options_clone); //Insert Clone Options into Container UL
$this.after(mySelect); //Insert Clone after Original
var selectWidth = $this.next('ul').find('ul').outerWidth(); //Get width of dropdown before hiding
$this.next('ul').find('ul').hide(); //Hide dropdown portion
$this.next('ul').css('width',selectWidth);
//on click, show dropdown
$this.next('ul').find('span').first().click(function(){
$this.next('ul').find('ul').toggle();
});
//on click, change top value, select hidden form, close dropdown
$this.next('ul').find('ul span').click(function(){
$(this).closest('ul').children().removeClass('selected');
$(this).parent().addClass("selected");
selection = $(this).parent().attr('rel');
selectedText = $(this).text();
$(this).closest('ul').prev().html(selectedText);
$this.val(selection); //This is what i can't get to work
$(this).closest('ul').hide();
});
});
// returns the jQuery object to allow for chainability.
return this;
}
回答by BGerrissen
Just a heads-up: .selector() is deprecated in jQuery 1.7 and removed in jQuery 1.9: api.jquery.com/selector. – Simon Steinberger
提醒一下: .selector() 在 jQuery 1.7 中已弃用,并在 jQuery 1.9 中删除:api.jquery.com/selector。——西蒙·斯坦伯格
Use the .selector
property on a jQuery collection.
.selector
在 jQuery 集合上使用该属性。
var x = $( "#box" );
alert( x.selector ); // #box
In your plugin:
在你的插件中:
$.fn.somePlugin = function() {
alert( this.selector ); // alerts current selector (#box )
var $this = $( this );
// will be undefined since it's a new jQuery collection
// that has not been queried from the DOM.
// In other words, the new jQuery object does not copy .selector
alert( $this.selector );
}
However this following probably solves your real question?
但是,以下内容可能会解决您的真正问题?
$.fn.customPlugin = function() {
// .val() already performs an .each internally, most jQuery methods do.
// replace x with real value.
this.val(x);
}
$("#box").customPlugin();
回答by Craig
回答by curveball
That's how I get selector strings inside my plugins in 2017:
这就是我在 2017 年在插件中获取选择器字符串的方式:
(function($, window, document, undefined) {
$.fn._init = $.fn.init
$.fn.init = function( selector, context, root ) {
return (typeof selector === 'string') ? new $.fn._init(selector, context, root).data('selector', selector) : new $.fn._init( selector, context, root );
};
$.fn.getSelector = function() {
return $(this).data('selector');
};
$.fn.coolPlugin = function() {
var selector = $(this).getSelector();
if(selector) console.log(selector); // outputs p #boldText
}
})(jQuery, window, document);
// calling plugin
$(document).ready(function() {
$("p #boldText").coolPlugin();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>some <b id="boldText">bold text</b></p>
The idea is to conditionally wrap jQuery's init()
function based on whether a selector string is provided or not. If it is provided, use jQuery's data()
method to associate the selector string with the original init()
which is called in the end. Small getSelector()
plugin just takes previously stored value. It can be called later inside your plugin. It should work well with all jQuery versions.
这个想法是init()
根据是否提供选择器字符串有条件地包装 jQuery 的函数。如果提供,则使用 jQuery 的data()
方法将选择器字符串与init()
最终调用的原始字符串相关联。小getSelector()
插件只需要先前存储的值。稍后可以在您的插件中调用它。它应该适用于所有 jQuery 版本。
回答by Studocwho
Because of the deprecation and removal of jQuery's .selector
, I have experimented with javascript's DOM Nodes
and came up with a 2017 and beyond solution until a better way comes along...
由于 jQuery 的弃用和删除.selector
,我尝试了 javascriptDOM Nodes
并提出了 2017 年及以后的解决方案,直到出现更好的方法......
//** Get selector **//
// Set empty variables to work with
var attributes = {}, // Empty object
$selector = ""; // Empty selector
// If exists...
if(this.length) {
// Get each node attribute of the selector (class or id)
$.each(this[0].attributes, function(index, attr) {
// Set the attributes in the empty object
// In the form of name:value
attributes[attr.name] = attr.value;
});
}
// If both class and id exists in object
if (attributes.class && attributes.id){
// Set the selector to the id value to avoid issues with multiple classes
$selector = "#" + attributes.id
}
// If class exists in object
else if (attributes.class){
// Set the selector to the class value
$selector = "." + attributes.class
}
// If id exists in object
else if (attributes.id){
// Set the selector to the id value
$selector = "#" + attributes.id
}
// Output
// console.log($selector);
// e.g: .example #example
So now we can use this for any purpose. You can use it as a jQuery selector... eg. $($selector)
所以现在我们可以将它用于任何目的。您可以将其用作 jQuery 选择器...例如。$($selector)
EDIT: My original answer would only get the attribute that appears first on the element. So if we wanted to get the idthat was placed after the class on the element, it wouldn't work.
编辑:我原来的答案只会得到第一个出现在元素上的属性。因此,如果我们想获取元素上放在 class 之后的id,那是行不通的。
My new solution uses an object to store the attribute information, therefore we can check if both or just one exists and set the required selector accordingly. With thanks to ManRo's solutionfor the inspiration.
我的新解决方案使用一个对象来存储属性信息,因此我们可以检查两者是否存在或仅存在一个,并相应地设置所需的选择器。感谢ManRo 的解决方案的启发。