ID заканчивается на чистом Javascript
Я работаю в библиотеке Javascript, которая приносит jQuery для одной вещи:селектор" заканчивается". Выглядит это так:
$('[id$=foo]')
Он найдет элементы, в которых id
заканчивается на "foo".
Я хочу сделать это без jQuery (прямой JavaScript). Как ты можешь это сделать? Я также хотел бы, чтобы он был максимально эффективным.
6 ответов
использовать querySelectorAll
, не доступен во всех браузерах (например, IE 5/6/7/8), хотя. Она в основном работает как jQuery:
console.log(document.querySelectorAll("[id$=foo]"));
вам нужно будет перебрать все элементы на странице, а затем использовать строковые функции для его проверки. Единственная оптимизация, о которой я могу думать, - это изменение начальной точки, т. е. не document.body
но какой - то другой элемент, где вы знаете, что ваш элемент будет дочерним-или вы можете использовать document.getElementsByTagName()
чтобы получить список элементов, если вы знаете имя тега элементов.
однако, ваша задача будет много проще, если вы можете использовать какой-то сторонний javascript, например шипеть (4K minified, тот же селектор двигателя jQuery использует).
Так, используя все, что было сказано, я собрал этот код. Если мой элемент input
s, то следующий код, вероятно, лучший, который я собираюсь получить?
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
function getInputsThatEndWith(text) {
var result = new Array();
var inputs = document.getElementsByTagName("input");
for(var i=0; i < inputs.length; i++) {
if(inputs[i].id.endsWith(text))
result.push(inputs[i]);
}
return result;
}
Я поставил его на JsFiddle:http://jsfiddle.net/MF29n/1/
@ThiefMaster коснулся того, как вы можете сделать проверку, но вот фактический код:
function idEndsWith(str)
{
if (document.querySelectorAll)
{
return document.querySelectorAll('[id$="'+str+'"]');
}
else
{
var all,
elements = [],
i,
len,
regex;
all = document.getElementsByTagName('*');
len = all.length;
regex = new RegExp(str+'$');
for (i = 0; i < len; i++)
{
if (regex.test(all[i].id))
{
elements.push(all[i]);
}
}
return elements;
}
}
Это можно улучшить несколькими способами. В настоящее время он проходит через весь dom, но было бы более эффективно, если бы у него был контекст:
function idEndsWith(str, context)
{
if (!context)
{
context = document;
}
...CODE... //replace all occurrences of "document" with "context"
}
нет проверки / экранирования на str
переменная в этой функции предполагается, что она будет только принимать строку символов.
изменение ваш ответ:
RegExp.quote = function(str) {
return str.replace(/([.?*+^$[\]\(){}-])/g, "\");
}; // from https://stackoverflow.com/questions/494035/#494122
String.prototype.endsWith = function(suffix) {
return !!this.match(new RegExp(RegExp.quote(suffix) + '$'));
};
function getInputsThatEndWith(text) {
var results = [],
inputs = document.getElementsByTagName("input"),
numInputs = inputs.length,
input;
for(var i=0; i < numInputs; i++) {
var input = inputs[i];
if(input.id.endsWith(text)) results.push(input);
}
return results;
}
http://jsfiddle.net/mattball/yJjDV/
реализация String.endsWith
используя регулярное выражение вместо indexOf()
в основном это вопрос предпочтения, но я решил, что стоит включить для разнообразия. Если вы не беспокоитесь об экранировании специальных символов в суффиксе, вы можете удалить RegExp.quote()
- чуть, и просто использоватьnew RegExp(suffix + '$')
.
Если вы знаете тип элементов DOM, на которые вы нацелены,
затем получите список ссылок на них, используя getElementsByTagName
, а затем повторите их.
вы можете использовать эту оптимизацию для закрепления итераций:
игнорировать элементы, не имеющие id.
target ближайший известный родитель элементов, которые вы хотите искать, скажем, ваш элемент находится внутри div с id= 'myContainer', тогда вы можете получить ограниченное подмножество, используя
document.getElementById('myContainer').getElementsByTagName('*')
, а затем повторите их.