Одной из распространенных причин того, что переменная не существует после отправки HTML-формы, является то, что элемент формы не содержится в теге <form>
:
Пример: элемент не содержится в <form>
<form action="example.php" method="post">
<p>
<input type="text" name="name" />
<input type="submit" value="Submit" />
</p>
</form>
<select name="choice">
<option value="choice1">choice 1</option>
<option value="choice2">choice 2</option>
<option value="choice3">choice 3</option>
<option value="choice4">choice 4</option>
</select>
Пример: Элемент теперь содержится в <form>
<form action="example.php" method="post">
<select name="choice">
<option value="choice1">choice 1</option>
<option value="choice2">choice 2</option>
<option value="choice3">choice 3</option>
<option value="choice4">choice 4</option>
</select>
<p>
<input type="text" name="name" />
<input type="submit" value="Submit" />
</p>
</form>
Вот экспериментальная реализация, позволяющая заставить jQuery работать с объектами. С помощью оболочки объекта ( FakeNode
) вы можете обманом заставить jQuery использовать его встроенный механизм выбора (Sizzle) для простых объектов JavaScript:
function FakeNode(obj, name, parent) {
this.obj = obj;
this.nodeName = name;
this.nodeType = name ? 1 : 9; // element or document
this.parentNode = parent;
}
FakeNode.prototype = {
documentElement: { nodeName: "fake" },
getElementsByTagName: function (tagName) {
var nodes = [];
for (var p in this.obj) {
var node = new FakeNode(this.obj[p], p, this);
if (p === tagName) {
nodes.push(node);
}
Array.prototype.push.apply(nodes,
node.getElementsByTagName(tagName));
}
return nodes;
}
};
function $$(sel, context) {
return $(sel, new FakeNode(context));
}
И использование будет следующим:
var obj = {
foo: 1,
bar: 2,
child: {
baz: [ 3, 4, 5 ],
bar: {
bar: 3
}
}
};
function test(selector) {
document.write("Selector: " + selector + "<br>");
$$(selector, obj).each(function () {
document.write("- Found: " + this.obj + "<br>");
});
}
test("child baz");
test("bar");
Получение вывода:
Selector: child baz - Found: 3,4,5 Selector: bar - Found: 2 - Found: [object Object] - Found: 3
Конечно, для поддержки более сложных селекторов вам придется реализовать гораздо больше, чем указано выше.
Кстати, вы видели jLinq ?
У объекта массива есть несколько методов, которые вы можете использовать:
last = obj.child.baz.slice(-1)[0];
Некоторые другие примеры:
first = obj.child.baz.slice(0,1)[0];
allExceptFirst = obj.child.baz.slice(1);
allExceptLast = obj.child.baz.(0,-1);
Лично я бы сказал, что доступ к чистым объектам выглядит лучше, чем запросы, подобные jQuery. Одна вещь, которая была бы опрятной, - это нарезка и другие методы фильтрации.
Если вы действительно хотите поиграть с запросами доступа к объектам, следующие возможности будут некоторыми (подумайте о XPath):
var obj = {
foo: 1,
bar: 2,
child: {
foo: {
baz: [3, {a: 1}, {a: 2, b: 3}]},
bar: {
baz: [42, {a: 123}, {a: -1}]},
baz: null}};
// Implicitly start in the Global object, unless a context is provided.
// Keys in JavaScript objects are essentially stored in order (not valid for
// *all* flavors, but it's close to standard. So you could do slicing on keys.)
// Selects (does not return them)
// obj.child.foo.baz[1].a
// obj.child.foo.baz[2].a
// obj.child.bar.baz[1].a
// obj.child.bar.baz[2].a
// Then performs an aggregate that returns value 125.
$('obj.child[:2].baz[1:].a').sum()
// Selects obj.foo, obj.bar, obj.child.foo.baz[0] and obj.child.bar.baz[0]
$('obj *[typeof(number)]')
// Selects obj.foo and obj.child.foo
$('obj foo')
// Other possible methods: delete(), set(), get() (as an array of values),
// min(), max(), avg(), merge() etc etc.
В конце концов, я не не вижу, как это очень полезно. Но да, думаю, это идея =)