Сокращение Javascript для getElementById

94

Есть ли какое-нибудь сокращение для JavaScript document.getElementById? Или я могу как-то его определить? Это повторяется снова и снова .

Фокс Уилсон
источник
6
Я не знаю, кто их проголосовал против, но тот, кто недостаточно знаком с Javascript и не знает, как создавать такие ярлыки, также может столкнуться с проблемами, когда он попытается использовать его, скажем, с jQuery, и обнаружит, что переменная $ несовместима. Правильный ответ: «Нет, изначально Javascript не предлагает сокращений, но есть несколько фреймворков, которые упрощают выбор узлов DOM».
kojiro

Ответы:

126
var $ = function( id ) { return document.getElementById( id ); };

$( 'someID' )

Здесь я использовал $, но вы можете использовать любое допустимое имя переменной.

var byId = function( id ) { return document.getElementById( id ); };

byId( 'someID' )
user113716
источник
6
@patrick dw Мне это нравится. Особенно с обилием допустимых имен переменных :)
Fox Wilson
4
"с множеством допустимых имен переменных" - вы имеете в виду, что "по крайней мере два основных JS-фреймворка уже используют $, поздравляем с выбором этого тоже?"
Писквор вышел из здания
47
Не имеет значения, сколько библиотек используется, $если вы их никогда не загружаете.
user113716
7
Для записи, я делал это раньше var $ = document.getElementById.bind(document), но bindдоступен не во всех браузерах. Возможно, это быстрее, потому что я использую только собственные методы. Просто хотел добавить это.
pimvdb
7
@Piskvor: Я никогда не кодирую, чтобы приспособиться к незнанию. Незнание ведет к нарушению кода. Неработающий код требует исследования. Исследования приводят к информации. Невежество излечивается.
user113716
85

Чтобы сохранить лишний символ, вы можете загрязнить прототип String следующим образом:

pollutePrototype(String, '绎', {
    configurable: false, // others must fail
    get: function() {
        return document.getElementById(this);
    },
    set: function(element) {
        element.id = this;
    }
});

function pollutePrototype(buildIn, name, descr) {
    var oldDescr = Object.getOwnPropertyDescriptor(buildIn.prototype, name);
    if (oldDescr && !oldDescr.configurable) {
        console.error('Unable to replace ' + buildIn.name + '.prototype.' + name + '!');
    } else {
        if (oldDescr) {
            console.warn('Replacing ' + buildIn.name + '.prototype.' + name + ' might cause unexpected behaviour.');
        }
        Object.defineProperty(buildIn.prototype, name, descr);
    }
}

Он работает в некоторых браузерах, и вы можете получить доступ к элементам следующим образом:

document.body.appendChild(
    'footer'.绎 = document.createElement('div')
);
'footer'.绎.textContent = 'btw nice browser :)';

Я выбрал название объекта почти случайно. Если вы действительно хотите использовать это сокращение, я бы предложил придумать что-нибудь более простое для набора.

Роберт
источник
12
绎 (Yì) - Unravel (упрощенный китайский)
AnnanFay,
8
Вы понимаете, что это требует значительного снижения эффективности. геттеры / сеттеры, определенные в прототипе, на порядок медленнее.
Raynos
5
кроме того, это может быть только один видимый символ, но он займет более одного байта в файле ...
Алнитак
@Alnitak: да ладно, я не думал об этом. Кроме того, у некоторых людей (например, меня) нет клавиши 绎 на клавиатуре, поэтому они тратили бы много времени на ее копирование и вставку. Но имя на самом деле не важно. Первоначально я назвал свойство «e» (как элемент), но я думал, что это имя уже может быть заявлено какой-то библиотекой.
Роберт
@Raynos: Да, в моем тесте это примерно в три раза медленнее, чем обычная функция. 0,4 мкс * 3 = 1,2 мкс
Роберт
18

Вы можете легко создать стенографию самостоятельно:

function getE(id){
   return document.getElementById(id);
}
Сарфраз
источник
@Sarfraz Лучше всего объявить его как переменную или как функцию? Это вообще имеет значение?
user1431627
@ user1431627: Если под переменной вы имели в виду выражение функции, то это имеет значение с точки зрения объема. Функция, опубликованная в моем ответе, будет доступна везде в контексте ее выполнения. См: stackoverflow.com/questions/1013385/... или kangax.github.io/nfe
Сарфраза
@Sarfraz Хорошо, спасибо :) jQuery обрабатывает это в переменной области, верно? Причина, по которой я спрашиваю, заключается в том, что верхний ответ был написан с переменной областью видимости, но вы написали его как выражение регулярной функции.
user1431627
13

Быстрая альтернатива для внесения вклада:

HTMLDocument.prototype.e = document.getElementById

Тогда просто сделайте:

document.e('id');

Есть одна загвоздка: это не работает в браузерах, которые не позволяют расширять прототипы (например, IE6).

Пабло Фернандес
источник
2
@ walle1357: Эта статья может вас заинтересовать.
user113716
5
@ThiefMaster «Никогда не делай Х» - худший совет, который ты можешь дать. Знайте альтернативы, плюсы и минусы и выбирайте лучший ответ для каждой конкретной проблемы. В этом случае нет ничего плохого в расширении прототипа (хотя я должен сказать, что другие ответы подходят лучше, этот остался только для завершения)
Пабло Фернандес
Откуда вы знаете, что он ничего не сломает ни в каком браузере или в будущем?
ThiefMaster
@PabloFernandez: Вы все еще не хотите расширять объекты хоста. Если по крайней мере две библиотеки хотят расширить основной объект с помощью идентично названных свойств, то только первая осторожная библиотека или последняя небрежная библиотека будут успешными.
Роберт
1
@Robert это явно не лучший вариант, но это вариант. Вы должны учитывать плюсы и минусы каждого. Помните, что вначале библиотеки javascript на стороне клиента prototype.jsвыполняли то же самое.
Пабло Фернандес,
8

(Сокращение не только для получения элемента по идентификатору, но и для получения элемента по классу: P)

Я использую что-то вроде

function _(s){
    if(s.charAt(0)=='#')return [document.getElementById(s.slice(1))];
    else if(s.charAt(0)=='.'){
        var b=[],a=document.getElementsByTagName("*");
        for(i=0;i<a.length;i++)if(a[i].className.split(' ').indexOf(s.slice(1))>=0)b.push(a[i]);
        return b;
    }
}

Использование: _(".test")возвращает все элементы с именем класса testи _("#blah")возвращает элемент с идентификатором blah.

JiminP
источник
6
Лучше создать ярлык для document.querySelectorAllвместо того, чтобы пытаться имитировать часть querySelectorAllметода в пользовательской функции.
Rob W
8

идентификаторы сохраняются в window.

HTML

 <div id='logo'>logo</div>

JS

logo.innerHTML;

то же самое, что писать:

document.getElementById( 'logo' ).innerHtml;

Я не предлагаю использовать первый метод, так как это не обычная практика.

im_benton
источник
Не могли бы вы пояснить, почему вы не предлагаете использовать этот метод?
Okku
Я никогда не видел, чтобы это использовалось, потому что я не думаю, что это практика ставок. Но это кратчайший способ его найти.
im_benton
@Okku потому что <div id="location"></div>и позвонить window.locationне получится.
Alex
7
<script>
var _ = function(eId)
{
    return getElementById(eId);
}
</script>

<script>
var myDiv = _('id');
</script>
генезис
источник
6

Здесь есть несколько хороших ответов, и некоторые из них танцуют вокруг синтаксиса, подобного jQuery, но ни один из них не упоминает фактическое использование jQuery. Если вы не против попробовать, попробуйте jQuery . Это позволяет вам очень легко выбирать элементы вот так ..

По ID :

$('#elementId')

По классу CSS :

$('.className')

По типу элемента :

$('a')  // all anchors on page 
$('inputs')  // all inputs on page 
$('p a')  // all anchors within paragaphs on page 
Кон
источник
3
Я пробовал jQuery, но действительно ли мне нужна вся библиотека только для сокращения getElementById?
Fox Wilson
Что такое «синтаксис, подобный jQuery» в других ответах? В основном это просто старые функции, на которые ссылаются переменные. В этом нет ничего уникального jQuery. ; o)
user113716
3
@patrick dw, верно, ваш ответ $ ('someID') совсем не похож на селектор идентификаторов jQuery $ ('# someID') :)
Кон
5

Встроенного нет.

Если вы не против загрязнения глобального пространства имен, почему бы и нет:

function $e(id) {
    return document.getElementById(id);
}

РЕДАКТИРОВАТЬ - я изменил имя функции на что-то необычное , но короткое и не противоречащее jQuery или чему-либо еще, в котором используется пустой $знак.

Альнитак
источник
3

Да, он получает повторяющийся использовать ту же функцию в течение и через каждый раз с другим аргументом:

var myImage = document.getElementById("myImage");
var myDiv = document.getElementById("myDiv");

Так что хорошей вещью была бы функция, которая принимает все эти аргументы одновременно:

function getElementsByIds(/* id1, id2, id3, ... */) {
    var elements = {};
    for (var i = 0; i < arguments.length; i++) {
        elements[arguments[i]] = document.getElementById(arguments[i]);
    }
    return elements;
}

Тогда у вас будут ссылки на все ваши элементы, хранящиеся в одном объекте:

var el = getElementsByIds("myImage", "myDiv");
el.myImage.src = "test.gif";

Но вам все равно придется перечислить все эти идентификаторы.

Вы можете упростить его еще больше, если хотите, чтобы все элементы имели идентификаторы:

function getElementsWithIds() {
    var elements = {};
    var elementList = document.querySelectorAll("[id]");
    for (var i = 0; i < elementList.length; i++) {
        elements[elementList[i].id] = elementList[i];
    }
    return elements;
}

Но было бы довольно дорого вызывать эту функцию, если у вас много элементов.


Итак, теоретически, если бы вы использовали withключевое слово, вы могли бы написать такой код:

with (getElementsByIds('myButton', 'myImage', 'myTextbox')) {
    myButton.onclick = function() {
        myImage.src = myTextbox.value;
    };
}

Но я не хочу продвигать использование with. Наверное, есть способ лучше.

Роберт
источник
2

Ну, вы можете создать сокращенную функцию, вот что я делаю.

function $(element) {
    return document.getElementById(element);
}

а затем, когда вы захотите это получить, вы просто сделаете

$('yourid')

Кроме того, я обнаружил еще один полезный трюк: если вы хотите получить значение или innerHTML идентификатора элемента, вы можете создавать такие функции:

function $val(el) {
    return $(el).value;
}

function $inner(el) {
    return $(el).innerHTML;
}

Надеюсь, вам понравится!

Я фактически сделал своего рода мини-библиотеку javascript, основанную на всей этой идее. Вот оно.

пользователь3385777
источник
Я просто снова смотрел на этот вопрос и нашел вот это. Это довольно удобная библиотека, если вы не хотите включать весь jQuery.
Fox Wilson
2

Я часто использую:

var byId='getElementById'
var byClass='getElementsByClass'
var byTag='getElementsByTag'


var mydiv=document[byId]('div') 
/* as document["getElementById"] === document.getElementById */

Я думаю, это лучше, чем внешняя функция (например, $()или byId()), потому что вы можете делать такие вещи, как это:

var link=document[byId]('list')[byClass]('li')[0][byTag]('a')[0]


Кстати, не используйте для этого jQuery, jQuery намного медленнее, чем document.getElementById()внешняя функция, например $()или byId(), или мой метод: http://jsperf.com/document-getelementbyid-vs-jquery/5

Жиль Кастель
источник
1

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

В jQuery синтаксис будет $("#someid"). Если вам нужен фактический элемент DOM, а не оболочка jQuery, это возможно $("#someid")[0], но вы, скорее всего, сможете делать все, что вам нужно, с оболочкой jQuery.

Или, если вы используете это в консоли разработчика браузера, изучите их встроенные утилиты. Как уже упоминалось, консоль Chrome JavaScript включает в себя$("someid") метод, и вы также можете щелкнуть элемент в представлении «Элементы» инструментов разработчика, а затем ссылаться на него с $0консоли. Выбранный ранее элемент становится $1и так далее.

Хенрик Н
источник
1

Если единственная проблема здесь - это ввод текста, возможно, вам стоит просто обзавестись редактором JavaScript с intellisense.

Если цель состоит в том, чтобы получить более короткий код, вы можете рассмотреть библиотеку JavaScript, такую ​​как jQuery, или вы можете просто написать свои собственные сокращенные функции, например:

function byId(string) {return document.getElementById(string);}

Раньше я делал это для лучшей производительности. В прошлом году я узнал, что с помощью методов сжатия сервер делает это автоматически за вас, поэтому мой метод сокращения фактически утяжелил мой код. Теперь я просто доволен вводом всего document.getElementById.

Кристоф
источник
1

Если вы запрашиваете сокращенную функцию ...

<!DOCTYPE html>
<html>

<body>
The content of the body element is displayed in your browser.
<div id="d1">DIV</div>
<script>
var d=document;
d.g=document.getElementById;
d.g("d1").innerHTML = "catch";
</script>
</body>

</html>

или

<!DOCTYPE html>
<html>

<body>
The content of the body element is displayed in your browser.
<div id="d1">DIV</div>
<script>
var w=window;
w["d1"].innerHTML = "catch2";
</script>
</body>

Люмический
источник
1

Стрелочные функции делают короче.

var $id = (id) => document.getElementById(id);
Виктор
источник
Вы можете сократить его еще больше, удалив круглые скобки, заключающие idаргумент.
Shaggy
1

оберните document.querySelectorAll ... jquery, например select

function $(selector){
   var s = document.querySelectorAll(selector); 
   return s.length > 1 ? s : s[0];
}

// usage: $('$myId')

источник
О, но с этим немного сложно работать. Функция может возвращать undefined, HTMLElement или NodeList. Конечно, когда вы используете его для получения элемента по его идентификатору, $('#myId')он обычно должен возвращать этот HTMLElement, потому что вы, надеюсь, назначили этот идентификатор ровно один раз. Но если вы будете использовать его с запросами, которые могут соответствовать нескольким элементам, это станет громоздким.
Роберт
0

Что ж, если идентификатор элемента не конкурирует с какими-либо свойствами глобального объекта, вам не нужно использовать какую-либо функцию.

myDiv.appendChild(document.createTextNode("Once I was myDiv. "));
myDiv.id = "yourDiv";
yourDiv.appendChild(document.createTextNode("But now I'm yourDiv."));

edit: Но вы не хотите использовать эту «функцию».

Роберт
источник
:( Для меня это звучит как злоупотребление браузером. Покажи мне, где это допустимо в спецификации HTML5.
Рейнос,
1
@Raynos: dev.w3.org/html5/spec/… Но: «Возможно, это изменится. Поставщики браузеров рассматривают возможность ограничения этого поведения режимом причуд». Хотя работает в моих FF4 и IE8.
Роберт
2
да, он работает прямо сейчас, но кажется грязным, и я не удивлюсь, если он устареет к концу года.
Raynos
@Raynos Надеюсь. Я не люблю, когда браузеры загрязняют глобальное пространство имен. Но с другой стороны, когда это было изобретено, это было не так уж и плохо. (когда веб-страницы были ориентированы на HTML, а javascript был хорошей функцией)
Роберт
0

Еще одна обертка:

const IDS = new Proxy({}, { 
    get: function(target, id) {
        return document.getElementById(id); } });

IDS.camelCaseId.style.color = 'red';
IDS['dash-id'].style.color = 'blue';
<div id="camelCaseId">div 1</div>
<div id="dash-id">div 2</div>

Это на случай, если вы не хотите использовать немыслимое , см. Выше.

Майк К.
источник
0

Вы можете использовать функцию-оболочку, например:

const byId = (id) => document.getElementById(id);

Или

Присвойте document.getElementById переменной, связав ее с documentобъектом.

const byId = document.getElementById.bind(document);

Примечание: Во втором подходе Если вы не связываться document.getElementByIdс documentвами получите сообщение об ошибке:

Uncaught TypeError: Illegal invocation

Что Function.bindделает, так это создание новой функции с thisключевым словом, установленным на значение, которое вы указываете в качестве аргумента Function.bind.

Прочтите документацию для Function.bind

Омкар76
источник
-1

Я написал это вчера и нашел его весьма полезным.

function gid(id, attribute) {
    var x = 'document.getElementById("'+id+'")';
    if(attribute) x += '.'+attribute;
    eval('x =' + x);
    return x;
}

Вот как вы это используете.

// Get element by ID
   var node = gid('someID'); //returns <p id='someID' class='style'>Hello World</p>

// returns 'Hello World'
// var getText = document.GetElementById('someID').innerText; 
   var getText = gid('someID', 'innerText'); 

// Get parent node
   var parentNode = gid('someID', 'parentNode');
Born2die007
источник
Это не очень хорошее использование eval. Нет ничего о том, чтобы получить элемент, которому требуется eval, и вы можете динамически получить свойство с обозначением скобок. См developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
ThatsNoMoon