ID заканчивается на чистом Javascript

Я работаю в библиотеке Javascript, которая приносит jQuery для одной вещи:селектор" заканчивается". Выглядит это так:

$('[id$=foo]')

Он найдет элементы, в которых id заканчивается на "foo".

Я хочу сделать это без jQuery (прямой JavaScript). Как ты можешь это сделать? Я также хотел бы, чтобы он был максимально эффективным.

6 ответов


использовать querySelectorAll, не доступен во всех браузерах (например, IE 5/6/7/8), хотя. Она в основном работает как jQuery:

http://jsfiddle.net/BBaFa/2/

console.log(document.querySelectorAll("[id$=foo]"));

вам нужно будет перебрать все элементы на странице, а затем использовать строковые функции для его проверки. Единственная оптимизация, о которой я могу думать, - это изменение начальной точки, т. е. не document.body но какой - то другой элемент, где вы знаете, что ваш элемент будет дочерним-или вы можете использовать document.getElementsByTagName() чтобы получить список элементов, если вы знаете имя тега элементов.

однако, ваша задача будет много проще, если вы можете использовать какой-то сторонний javascript, например шипеть (4K minified, тот же селектор двигателя jQuery использует).


Так, используя все, что было сказано, я собрал этот код. Если мой элемент inputs, то следующий код, вероятно, лучший, который я собираюсь получить?

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('*') , а затем повторите их.