2011-11-14 6 views
13

Digamos que tengo una lista <ul>:Cómo agregar funciones a algunos objetos jQuery, pero no a otros?

<ul class="products"> 
    ... 
</ul> 

Quiero seleccionarlo con jQuery, a continuación, añadir algunas funciones a ese objeto. Por ejemplo, me gustaría agregar una función addProduct(productData) y una función deleteProduct(productId). Sin embargo, me gustaría que las funciones solo se agreguen al objeto que devuelve el selector. Entonces, por ejemplo, algo como esto:

var productList = $.extend($('ul.products'), { 
    addProduct: function(productData) { 
     // add a new li item 
    }, 
    deleteProduct: function(productId) { 
     // delete li with id 
    } 
}); 

¿Cómo haré esto usando jQuery? El punto clave aquí es que solo quiero agregar las funciones a una instancia devuelta por un selector jQuery. En otras palabras, no quiero modificar el prototipo de jQuery o crear un complemento, ya que eso hará que las funciones estén disponibles en todo, mientras que solo quiero agregar las funciones a una instancia específica.

+1

¿Puedo preguntar cuál es el objetivo final de esta metodología? –

+0

Me gustaría poder encadenar el método, por ejemplo '$ ('ul.products'). FadeIn(). AddProduct (data);'. Además, lo mantiene coherente con la forma en que se llaman otros métodos jQuery. –

Respuesta

9

Si sólo desea los métodos addProduct y que cuentan en esa sola objeto jQuery, entonces lo que tienes no tendrán ningún problema; pero deberá mantener una referencia a ese objeto jQuery/solo usarlo una vez, para preservar la existencia de los métodos addProduct y .

Sin embargo, estos métodos addProduct y son exclusivos de ese objeto jQuery en particular; los métodos no existirán en ningún otro objeto jQuery que cree;

var productList = $.extend($('ul.products'), { 
    addProduct: function(productData) { 
     // add a new li item 
    }, 
    deleteProduct: function(productId) { 
     // delete li with id 
    } 
}); 

// Using this particular jQuery object (productList) will work fine. 
productList.addProduct(); 
productList.removeProduct(); 

// However, addProduct() does not exist on new jQuery objects, even if they use 
// the same selector. 
$('ul.products').addProduct(); // error; [object Object] has no method 'addProduct' 

La mejor manera de hacer que esto sería para ir de regreso a lo básico y definir separados addProduct y funciones, que aceptan un objeto jQuery. Si desea restringir estas funciones a que solo funcionaron en el selector ul.products, podría hacerlo;

function addProduct(obj) { 
    obj = obj.filter('ul.products'); 

    // do something with `obj` (its a jQuery object) 
} 

Este enfoque sería recomendable, ya que mantiene la jQuery.fn API consistente; de lo contrario, estaría agregando addProduct y removeProduct a algunas instanciasjQuery.fn pero no a otras, o haciendo que su uso sea redundante en otras. Con este enfoque, sin embargo, addProduct y removeProduct siempre están ahí, pero no los entierren de ninguna manera si no los quieren usar.


Notas históricas

Esta respuesta fue escrito originalmente en noviembre de 2011, cuando jQuery 1.7 fue lanzado. Desde entonces, la API ha cambiado considerablemente. La respuesta anterior es relevante para la versión actual 2.0 de jQuery.

Antes de 1,9, un método poco usado llama jQuery.sub solía existir, que es relacionado a lo que estamos tratando de hacer (pero no le ayudará a menos que cambie su enfoque). Esto crea un nuevo constructor jQuery, por lo que podrías hacer;

var newjQuery = jQuery.sub(); 
newjQuery.fn.addProduct = function() { 
    // blah blah 
}; 
newjQuery.fn.deleteProduct = function() { 
    // blah blah 
}; 

var foo = newjQuery('ul.products'); 
foo.deleteProduct(); 
foo.addProduct(); 

var bar = jQuery('ul.products'); 
bar.deleteProduct(); // error 
bar.addProduct(); // error 

tener cuidado sin embargo, el alias $ método haría referencia a la antigua jQuery objeto, en lugar de la newjQuery ejemplo.

jQuery.sub se eliminó de jQuery en 1.9.Ahora está disponible as a plugin.

1

Usted puede hacer sus propios métodos de jQuery de la siguiente manera:

$.fn.addProduct = function(){ 
    var myObject = $(this); 
    // do something 
} 

// Call it like: 
$("ul.products").addProduct(); 

Esto es un poco complicado, porque aunque usted está haciendo métodos que son muy específicos para las listas. Por lo tanto, para asegurarse de que al menos debe agregar alguna comprobación en el tipo de objeto y manejar el código correctamente si el objeto actual es, digamos un elemento de entrada.

Una alternativa es hacer un método de Javascript normal que reciba la lista como parámetro. De esa forma puedes hacer un método más específico de la lista.

+0

Esto es lo que estaba buscando y funcionó como esperaba/debería ... Parece responder a la pregunta original muy bien. ¿Por qué se votó negativamente? – wasatchwizard

+0

Me gana ... No veo por qué está mal tampoco. Pero puedes votar si gustas. En todo caso. Me alegro de que podría ser de alguna ayuda;) –

+0

Un poco tarde para la fiesta que conozco, pero el OP dijo en su pregunta; * Sin embargo, me gustaría que las funciones solo se agreguen al objeto que devuelve el selector. *, En lugar de todos los objetos jQuery, que es lo que hace esta respuesta ... tal vez esa es la razón del voto en negativo (aunque yo ' m no es el que menosprecia) – Matt

1

Creo que desea agregar una función a ese objeto DOM.

$(function(){ 
    // [0] gets the first object in array, which is your selected element, you can also use .get(0) in jQuery 
    $("#test")[0].addProduct = function(info){ 
     alert("ID: " + this.id + " - Param: " + info); 
    }; 


    $("#test")[0].addProduct("productid"); 
}); 

Por encima de la escritura Wil alerta "ID: Prueba - Param: ProductID"

Un ejemplo vivo: http://jsfiddle.net/jJ65A/1/

o normal Javascript

$(function(){ 
    document.getElementById("test").addProduct = function(info){ 
     alert(info); 
    }; 
}); 
-1

creo que puede ser simplemente usando delegado en jQuery:

$(".parentclass").delegate("childclass","eventname",function(){}); 
+0

O ha respondido la pregunta incorrecta, o no ha leído la pregunta ... esto no es relevante para lo que la pregunta está haciendo. – Matt

Cuestiones relacionadas