Viết tắt Javascript cho getElementById


93

Có cách viết tắt nào cho JavaScript document.getElementById không? Hoặc là có cách nào tôi có thể xác định một? Nó được gõ lại lặp đi lặp lại rằng trêntrên .


6
Tôi không biết ai đã từ chối chúng, nhưng một người không quen với Javascript mà anh ta không biết cách tạo các phím tắt như thế này cũng có khả năng gặp sự cố khi anh ta cố gắng sử dụng nó với jQuery, và nhận thấy rằng biến $ không nhất quán. Câu trả lời đúng là "Không, Javascript nguyên bản không cung cấp cách viết tắt, nhưng có một số khuôn khổ giúp việc chọn các nút DOM dễ dàng hơn."
kojiro

Câu trả lời:


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

$( 'someID' )

Ở đây tôi đã sử dụng $, nhưng bạn có thể sử dụng bất kỳ tên biến hợp lệ nào.

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

byId( 'someID' )

6
@patrick dw Tôi thích điều đó. Đặc biệt là với vô số tên biến hợp lệ ngoài kia :)
Fox Wilson

4
"với vô số tên biến hợp lệ" - ý bạn là "ít nhất hai khuôn khổ JS chính đã được sử dụng $, chúc mừng bạn cũng đã chọn điều đó?"
Piskvor rời tòa nhà vào

47
Sẽ không có gì khác biệt so với việc sử dụng bao nhiêu thư viện $nếu bạn không bao giờ tải chúng.
user113716

7
Chỉ đối với bản ghi, tôi đã từng làm var $ = document.getElementById.bind(document), nhưng bindkhông có sẵn trong tất cả các trình duyệt. Có lẽ nó nhanh hơn, bởi vì tôi chỉ sử dụng các phương pháp gốc. Chỉ muốn thêm điều này.
pimvdb

7
@Piskvor: Tôi không bao giờ viết mã để điều chỉnh sự thiếu hiểu biết. Sự thiếu hiểu biết dẫn đến mã bị hỏng. Mã bị hỏng dẫn đến nghiên cứu. Nghiên cứu dẫn đến thông tin. Sự ngu dốt được chữa khỏi.
user113716

85

Để lưu thêm một ký tự, bạn có thể bỏ qua nguyên mẫu Chuỗi như thế này:

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);
    }
}

Nó hoạt động trong một số trình duyệt và bạn có thể truy cập các phần tử theo cách này:

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

Tôi đã chọn tên của tài sản gần như ngẫu nhiên. Nếu bạn thực sự muốn sử dụng tốc ký này, tôi khuyên bạn nên nghĩ ra một thứ gì đó dễ nhập hơn.


12
绎 (Yì) - Làm sáng tỏ (Tiếng Trung giản thể)
AnnanFay

8
Bạn nhận ra rằng điều này có hiệu quả hợp lý. getter / setters được xác định trên nguyên mẫu chậm hơn.
Raynos

5
cũng có, sức mạnh đó chỉ là một thể nhìn thấy nhân vật, nhưng nó sẽ mất nhiều hơn một byte trong file ...
Alnitak

@Alnitak: ồ đúng rồi, tôi chưa nghĩ đến điều đó. Hơn nữa, một số người (như tôi) không có phím 绎 trên bàn phím của họ, vì vậy họ sẽ mất nhiều thời gian để sao chép và dán nó. Nhưng cái tên không thực sự quan trọng. Ban đầu tôi đặt tên thuộc tính là 'e' (phần tử giống như) nhưng tôi nghĩ rằng tên này có thể được yêu cầu bởi một số thư viện rồi.
Robert

@Raynos: Vâng, trong điểm chuẩn của tôi, nó chậm gấp ba lần so với một chức năng thông thường. 0,4µs * 3 = 1,2µs
Robert

18

Bạn có thể dễ dàng tự tạo tốc ký một cách dễ dàng:

function getE(id){
   return document.getElementById(id);
}

@Sarfraz Tốt nhất nên khai báo nó dưới dạng một biến hay một hàm? Nó thậm chí không quan trọng?
user1431627

@ user1431627: Nếu theo biến mà bạn có nghĩa là biểu thức hàm thì nó thực sự quan trọng về mặt phạm vi. Hàm được đăng trong câu trả lời của tôi sẽ có sẵn ở mọi nơi trong ngữ cảnh thực thi của nó. Xem: stackoverflow.com/questions/1013385/… hoặc kangax.github.io/nfe
Sarfraz

@Sarfraz Ok, cảm ơn :) jQuery xử lý điều này trong một phạm vi thay đổi, phải không? Lý do tại sao tôi hỏi là vì câu trả lời hàng đầu được viết với một phạm vi biến, nhưng bạn đã viết nó dưới dạng một biểu thức hàm thông thường.
user1431627

13

Một thay thế nhanh chóng để đóng góp:

HTMLDocument.prototype.e = document.getElementById

Sau đó, chỉ cần làm:

document.e('id');

Có một điểm khó khăn, nó không hoạt động trong các trình duyệt không cho phép bạn mở rộng các nguyên mẫu (ví dụ: IE6).


2
@ walle1357: Bài viết này có thể bạn quan tâm.
dùng113716

5
@ThiefMaster "Đừng bao giờ làm X" là về lời khuyên tồi tệ nhất mà bạn có thể đưa ra. Biết các lựa chọn thay thế, ưu và nhược điểm và chọn câu trả lời tốt nhất cho mọi vấn đề cụ thể. Không có hại trong việc mở rộng các nguyên mẫu trong trường hợp này (Mặc dù tôi nên nói rằng câu trả lời khác là một sự phù hợp tốt hơn, một trong những điều này là trái chỉ để hoàn thành)
Pablo Fernandez

Làm thế nào để bạn biết nó sẽ không phá vỡ bất cứ điều gì trong một số trình duyệt hoặc trong tương lai?
ThiefMaster

@PabloFernandez: Bạn vẫn không muốn mở rộng các đối tượng máy chủ. Nếu có ít nhất hai thư viện muốn mở rộng một đối tượng máy chủ với các thuộc tính được đặt tên giống hệt nhau thì chỉ thư viện cẩn thận đầu tiên hoặc thư viện bất cẩn cuối cùng mới thành công.
Robert

1
@Robert rõ ràng đây không phải là lựa chọn tốt nhất, nhưng nó một lựa chọn. Bạn cần phải xem xét những ưu và khuyết điểm của mọi thứ. Hãy nhớ rằng các thư viện javascript phía máy khách bắt đầu prototype.jsthực hiện chính xác điều này.
Pablo Fernandez

8

(Viết tắt để không chỉ nhận phần tử theo ID mà còn nhận phần tử theo lớp: P)

Tôi sử dụng một cái gì đó như

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;
    }
}

Công dụng: _(".test")trả về tất cả các phần tử có tên lớp test_("#blah")trả về một phần tử có id blah.


6
Tốt hơn bạn nên tạo một lối tắt cho document.querySelectorAll, thay vì cố gắng mô phỏng một phần của querySelectorAllphương thức trong một hàm tùy chỉnh.
Rob W

7
<script>
var _ = function(eId)
{
    return getElementById(eId);
}
</script>

<script>
var myDiv = _('id');
</script>

7

id được lưu vào window.

HTML

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

JS

logo.innerHTML;

cũng giống như viết:

document.getElementById( 'logo' ).innerHtml;

Tôi không đề nghị sử dụng phương pháp cũ vì nó không phải là phương pháp phổ biến.


Bạn có thể giải thích tại sao bạn không đề xuất sử dụng phương pháp này?
Okku

Tôi không thấy nó được sử dụng bao giờ vì tôi không nghĩ nó là thực hành đặt cược. Nhưng nó là cách ngắn nhất để tìm ra nó.
im_benton

@Okku bởi vì <div id="location"></div>và gọi window.locationsẽ không hoạt động.
Alex

6

Có một số câu trả lời tốt ở đây và một số câu trả lời đang nhảy xung quanh cú pháp giống jQuery, nhưng không có câu trả lời nào thực sự đề cập đến việc sử dụng jQuery. Nếu bạn không phản đối việc thử nó, hãy xem jQuery . Nó cho phép bạn chọn các phần tử siêu dễ dàng như thế này ..

Theo ID :

$('#elementId')

Theo lớp CSS :

$('.className')

Theo loại phần tử :

$('a')  // all anchors on page 
$('inputs')  // all inputs on page 
$('p a')  // all anchors within paragaphs on page 

3
Tôi đã thử jQuery, nhưng tôi có thực sự cần toàn bộ thư viện chỉ dành cho viết tắt getElementById không?
Fox Wilson

Là gì "jQuery giống như cú pháp" trong câu trả lời khác? Hầu hết chúng chỉ là các hàm cũ đơn giản được tham chiếu bởi các biến. Không có gì giống jQuery duy nhất về điều đó. ; o)
user113716

3
@patrick dw, Đúng vậy, câu trả lời của bạn $ ('someID') trông không giống công cụ chọn ID jQuery $ ('# someID') :)
Kon

5

Không có cài sẵn nào.

Nếu bạn không ngại làm ô nhiễm không gian tên chung, tại sao không:

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

CHỈNH SỬA - Tôi đã thay đổi tên hàm thành một cái gì đó bất thường , nhưng ngắn và không đụng độ với jQuery hoặc bất kỳ thứ gì khác sử dụng $dấu trần .


3

Vâng, nó được lặp đi lặp lại để sử dụng các chức năng tương tự trênqua mỗi lần với một lập luận khác nhau:

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

Vì vậy, một điều thú vị sẽ là một hàm nhận tất cả các đối số đó cùng một lúc:

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

Sau đó, bạn sẽ có các tham chiếu đến tất cả các phần tử của bạn được lưu trữ trong một đối tượng:

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

Nhưng bạn vẫn phải liệt kê tất cả các id đó.

Bạn có thể đơn giản hóa nó hơn nữa nếu bạn muốn tất cả các phần tử có id:

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;
}

Nhưng sẽ khá tốn kém khi gọi hàm này nếu bạn có nhiều yếu tố.


Vì vậy, về mặt lý thuyết, nếu bạn sử dụng withtừ khóa, bạn có thể viết mã như sau:

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

Nhưng tôi không muốn quảng bá việc sử dụng with. Có lẽ có một cách tốt hơn để làm điều đó.


2

Chà, bạn có thể tạo một hàm tốc ký, đó là những gì tôi làm.

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

và sau đó khi bạn muốn lấy nó, bạn chỉ cần làm

$('yourid')

Ngoài ra, một thủ thuật hữu ích khác mà tôi đã tìm thấy, đó là nếu bạn muốn nhận giá trị hoặc innerHTML của ID mục, bạn có thể tạo các hàm như sau:

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

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

Hy vọng bạn thích nó!

Tôi thực sự đã tạo một loại thư viện javascript nhỏ dựa trên toàn bộ ý tưởng này. Đây rồi.


Tôi vừa xem lại câu hỏi này, và tìm thấy điều này. Đây là một thư viện khá gọn gàng nếu bạn không muốn bao gồm tất cả jQuery.
Fox Wilson

2

Tôi thường xuyên sử dụng:

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


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

Tôi nghĩ nó tốt hơn một hàm bên ngoài (ví dụ $()hoặc byId()) vì bạn có thể làm những việc như sau:

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


Btw, không sử dụng jQuery cho việc này, jQuery chậm hơn rất nhiều so với document.getElementById()một hàm bên ngoài như $()or byId(), hoặc phương pháp của tôi: http://jsperf.com/document-getelementbyid-vs-jquery/5


1

Nếu đây là trên trang web của riêng bạn, hãy xem xét sử dụng một thư viện như jQuery để cung cấp cho bạn điều này và nhiều phím tắt hữu ích khác cũng giúp loại bỏ sự khác biệt của trình duyệt. Cá nhân tôi, nếu tôi viết đủ mã để bị làm phiền bởi tay dài, tôi sẽ bao gồm jQuery.

Trong jQuery, cú pháp sẽ là $("#someid"). Sau đó, nếu bạn muốn phần tử DOM thực sự chứ không phải trình bao bọc jQuery $("#someid")[0], nhưng bạn rất có thể làm bất cứ điều gì bạn muốn với trình bao bọc jQuery.

Hoặc, nếu bạn đang sử dụng tính năng này trong bảng điều khiển dành cho nhà phát triển trình duyệt, hãy nghiên cứu các tiện ích tích hợp của chúng. Như ai đó đã đề cập, bảng điều khiển JavaScript của Chrome bao gồm một $("someid")phương thức và bạn cũng có thể nhấp vào một phần tử trong chế độ xem "Phần tử" của công cụ nhà phát triển và sau đó tham chiếu nó $0từ bảng điều khiển. Phần tử đã chọn trước đó trở thành $1và như vậy.


1

Nếu vấn đề duy nhất ở đây là đánh máy, có lẽ bạn nên kiếm cho mình một trình soạn thảo JavaScript với intellisense.

Nếu mục đích là để lấy mã ngắn hơn, thì bạn có thể xem xét một thư viện JavaScript như jQuery hoặc bạn chỉ có thể viết các hàm viết tắt của riêng mình, như:

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

Tôi đã từng làm những điều trên để có hiệu suất tốt hơn. Những gì tôi đã học được vào năm ngoái là với kỹ thuật nén, máy chủ sẽ tự động làm điều đó cho bạn, vì vậy kỹ thuật rút gọn của tôi thực sự đã làm cho mã của tôi nặng hơn. Bây giờ tôi chỉ hài lòng với việc nhập toàn bộ document.getElementById.


1

Nếu bạn đang yêu cầu một hàm viết tắt ...

<!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>

hoặc là

<!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

Hàm mũi tên thực hiện ngắn hơn.

var $id = (id) => document.getElementById(id);

Bạn có thể rút ngắn nó hơn nữa bằng cách loại bỏ các dấu ngoặc đơn bao quanh idđối số.
Shaggy

1

quấn document.querySelectorAll ... một jquery như select

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

// usage: $('$myId')

Ồ, nhưng điều này có vẻ hơi khó làm việc. Hàm có thể trả về undefined, HTMLElement hoặc NodeList. Tất nhiên khi bạn sử dụng nó để lấy một phần tử theo id của nó $('#myId')thì nó thường sẽ trả về HTMLElement đó, vì bạn hy vọng đã chỉ định id đó chính xác một lần. Nhưng nếu bạn sử dụng nó với các truy vấn có thể khớp với nhiều phần tử, nó sẽ trở nên cồng kềnh.
Robert

0

Vâng, nếu id của phần tử không cạnh tranh với bất kỳ thuộc tính nào của đối tượng toàn cục, bạn không cần phải sử dụng bất kỳ hàm nào.

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

chỉnh sửa: Nhưng bạn không muốn sử dụng 'tính năng' này.


:( Đó âm thanh như lạm dụng trình duyệt với tôi Chỉ cho tôi nơi đây là hợp lệ trong spec HTML5..
Raynos

1
@Raynos: dev.w3.org/html5/spec/… Nhưng: "Có thể điều này sẽ thay đổi. Các nhà cung cấp trình duyệt đang xem xét giới hạn hành vi này ở chế độ quirks." Tuy nhiên, hoạt động trong FF4 và IE8 của tôi.
Robert

2
vâng nó hoạt động ngay bây giờ nhưng nó cảm thấy bẩn và tôi sẽ không ngạc nhiên nếu nó không còn được dùng nữa vào cuối năm nay.
Raynos

@Raynos Tôi hy vọng vậy. Tôi không thích các trình duyệt gây ô nhiễm không gian tên chung. Nhưng mặt khác, đây không phải là một điều tồi tệ khi nó được phát minh. (khi trang web đã html trung tâm và javascript là một tính năng tuyệt vời)
Robert

0

Một trình bao bọc khác:

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>

Điều này, trong trường hợp bạn không muốn sử dụng không thể tưởng tượng , hãy xem ở trên.


-1

Tôi đã viết điều này ngày hôm qua và thấy nó khá hữu ích.

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

Đây là cách bạn sử dụng nó.

// 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');

Đây không phải là một cách sử dụng tốt của eval. Không có gì về việc lấy phần tử cần eval và bạn có thể lấy động một thuộc tính với ký hiệu ngoặc. Xem developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
ThatsNoMoon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.