เมื่อใดที่จะใช้ setAttribute vs .attribute = ใน JavaScript


234

มีการพัฒนาแนวปฏิบัติที่ดีที่สุดเกี่ยวกับการใช้setAttributeแทนเครื่องหมายจุด dot ( .) หรือไม่?

เช่น:

myObj.setAttribute("className", "nameOfClass");
myObj.setAttribute("id", "someID");

หรือ

myObj.className = "nameOfClass";
myObj.id = "someID";

1
เมื่อฉันเปลี่ยนจาก.setAttribute()เป็น[key] = valueทุกอย่างก็เริ่มทำงานได้อย่างน่าอัศจรรย์
แอนดรู

คำตอบ:


73

คุณควรใช้.attributeแบบฟอร์มโดยตรง(แต่เห็นลิงค์ quirksmode ด้านล่าง) หากคุณต้องการเข้าถึงแบบเป็นโปรแกรมใน JavaScript ควรจัดการแอตทริบิวต์ประเภทต่างๆ (คิดว่า "onload") อย่างถูกต้อง

ใช้getAttribute/ setAttributeเมื่อคุณต้องการจัดการกับ DOM เหมือนเดิม (เช่นข้อความตัวอักษรเท่านั้น) เบราว์เซอร์ที่แตกต่างกันสร้างความสับสนให้ทั้งสอง ดูโหมด Quirks: แอตทริบิวต์ (ใน)


127
คำตอบนี้ยังไม่ชัดเจนพอ ... ฉันยังไม่เข้าใจเลย
temporary_user_name

1
@Aerovistae - เห็นด้วยกับคุณเกี่ยวกับเรื่องนี้ เพิ่มคำตอบใหม่ซึ่งหวังว่าชัดเจนขึ้น
โอฬาร

1
แต่ถ้าคุณต้องการส่งผลต่อส่วนใน HTML ขององค์ประกอบคุณจะต้องใช้ setAttribute ...
Michael

3
คุณหมายถึง outterHTML * :)
megawac

4
ฉันพบว่า a.href ส่งคืน URL แบบเต็ม แต่ getAttribute ('href') จะส่งคืนสิ่งที่อยู่ในแอตทริบิวต์นั้น (<a href = "/ help" ... )
กระต่ายพลาสติก

144

จากJavascript: The Definitive Guideจะอธิบายสิ่งต่าง ๆ มันตั้งข้อสังเกตว่าวัตถุHTMLElementของเอกสาร HTML กำหนดคุณสมบัติ JS ที่สอดคล้องกับคุณลักษณะ HTML มาตรฐานทั้งหมด

ดังนั้นคุณจะต้องใช้setAttributeสำหรับแอตทริบิวต์ที่ไม่ได้มาตรฐานเท่านั้น

ตัวอย่าง:

node.className = 'test'; // works
node.frameborder = '0'; // doesn't work - non standard attribute
node.setAttribute('frameborder', '0'); // works

2
และยิ่งไปกว่านั้นมันจะปรากฏขึ้นหลังจาก setAttribute สุดท้ายในตัวอย่างของคุณnode.frameborderไม่ได้ถูกกำหนดดังนั้นคุณต้อง getAttribute เพื่อรับค่ากลับมา
Michael

5
@Michael ถูกต้อง - หากคุณใช้ setAttribute เพื่อตั้งค่าคุณต้องใช้ getAttribute เพื่อดึงข้อมูล
ลัน

3
ไม่มีอะไรผิดปกติกับการตั้งค่าframeBorderโดยตรง แต่ให้สังเกตว่าตัวพิมพ์ใหญ่ มีคนคิดว่ามันเป็นความคิดที่ดีที่จะ camelCase เทียบเท่า JavaScript ของแอตทริบิวต์ HTML ฉันไม่สามารถหาข้อมูลจำเพาะใด ๆ สำหรับเรื่องนี้ได้ แต่เน็ตดูเหมือนจะยอมรับว่าเป็นเรื่องเฉพาะ 12 เรื่อง (สำหรับ HTML 4 อย่างน้อย) ดูตัวอย่างโพสต์ต่อไปนี้: drupal.org/node/1420706#comment-6423420
aaaaaaaaaaaa

1
usemapแอตทริบิวต์ไม่สามารถตั้งค่าการใช้สัญกรณ์จุดเมื่อมีการสร้างแผนที่แบบไดนามิกสำหรับภาพ มันต้องมีimg.setAttribute('usemap', "#MapName");คำตอบของคุณหมายความว่าusemap"ไม่ได้มาตรฐาน" หรือไม่?
mseifert

1
สิ่งนี้ผิดมาก คุณลักษณะบางอย่างมีคุณสมบัติที่กำหนดดังนั้นอย่า มันเกี่ยวกับวิธีที่พวกเขาเขียนสเป็ค มันไม่มีส่วนเกี่ยวข้องใด ๆ กับคุณสมบัติที่เป็นมาตรฐานหรือไม่ อย่างไรก็ตามมันเป็นความจริงที่ว่าคุณสมบัติมาตรฐานใด ๆ สามารถเข้าถึงได้ด้วย getAttribute ()
Ben

79

ไม่มีคำตอบก่อนหน้านี้ที่สมบูรณ์และส่วนใหญ่ประกอบด้วยข้อมูลที่ผิด

การเข้าถึงแอตทริบิวต์ขององค์ประกอบ DOM ใน JavaScript มีสามวิธี ทั้งสามทำงานได้อย่างน่าเชื่อถือในเบราว์เซอร์สมัยใหม่ตราบใดที่คุณเข้าใจวิธีการใช้งาน

1 element.attributes

องค์ประกอบที่มีคุณสมบัติคุณลักษณะที่ส่งกลับสดNamedNodeMapของattrวัตถุ ดัชนีของคอลเลกชันนี้อาจแตกต่างจากเบราว์เซอร์ ดังนั้นไม่รับประกันการสั่งซื้อ NamedNodeMapมีวิธีการเพิ่มและลบแอตทริบิวต์ ( getNamedItemและsetNamedItemตามลำดับ)

โปรดสังเกตว่าแม้ว่า XML จะคำนึงถึงขนาดตัวพิมพ์อย่างชัดเจน แต่ข้อมูลจำเพาะ DOM เรียกชื่อสตริงให้เป็นมาตรฐานดังนั้นชื่อที่ส่งผ่านgetNamedItemจะไม่ตรงตามตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก

ตัวอย่างการใช้งาน:

var div = document.getElementsByTagName('div')[0];

//you can look up specific attributes
var classAttr = div.attributes.getNamedItem('CLASS');
document.write('attributes.getNamedItem() Name: ' + classAttr.name + ' Value: ' + classAttr.value + '<br>');

//you can enumerate all defined attributes
for(var i = 0; i < div.attributes.length; i++) {
  var attr = div.attributes[i];
  document.write('attributes[] Name: ' + attr.name + ' Value: ' + attr.value + '<br>');
}

//create custom attribute
var customAttr = document.createAttribute('customTest');
customAttr.value = '567';
div.attributes.setNamedItem(customAttr);

//retreive custom attribute
customAttr = div.attributes.getNamedItem('customTest');
document.write('attributes.getNamedItem() Name: ' + customAttr.name + ' Value: ' + customAttr.value + '<br>');
<div class="class1" id="main" data-test="stuff" nonStandard="1234"></div>

2. element.getAttribute&element.setAttribute

วิธีการเหล่านี้มีอยู่โดยตรงบนElementโดยไม่จำเป็นต้องเข้าถึงattributesและวิธีการ แต่ทำหน้าที่เดียวกัน

โปรดสังเกตอีกครั้งว่าชื่อสตริงเป็นแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่

ตัวอย่างการใช้งาน:

var div = document.getElementsByTagName('div')[0];

//get specific attributes
document.write('Name: class Value: ' + div.getAttribute('class') + '<br>');
document.write('Name: ID Value: ' + div.getAttribute('ID') + '<br>');
document.write('Name: DATA-TEST Value: ' + div.getAttribute('DATA-TEST') + '<br>');
document.write('Name: nonStandard Value: ' + div.getAttribute('nonStandard') + '<br>');


//create custom attribute
div.setAttribute('customTest', '567');

//retreive custom attribute
document.write('Name: customTest Value: ' + div.getAttribute('customTest') + '<br>');
<div class="class1" id="main" data-test="stuff" nonStandard="1234"></div>

3. คุณสมบัติบนวัตถุ DOM เช่น element.id

คุณลักษณะมากมายสามารถเข้าถึงได้โดยใช้คุณสมบัติที่สะดวกสบายในวัตถุ DOM คุณลักษณะใดที่มีอยู่ขึ้นอยู่กับชนิดของโหนด DOM ไม่ใช่คุณลักษณะที่กำหนดไว้ใน HTML คุณสมบัติถูกกำหนดที่ใดที่หนึ่งในห่วงโซ่ต้นแบบของวัตถุ DOM ที่เป็นปัญหา คุณสมบัติเฉพาะที่กำหนดจะขึ้นอยู่กับประเภทขององค์ประกอบที่คุณกำลังเข้าถึง ตัวอย่างเช่นclassNameและidมีการกำหนดElementและมีอยู่ในโหนด DOM ทั้งหมดที่เป็นองค์ประกอบ (เช่นไม่ใช่ข้อความหรือโหนดความคิดเห็น) แต่valueแคบกว่า มันกำหนดไว้HTMLInputElementและอาจไม่มีอยู่ในองค์ประกอบอื่น ๆ

ขอให้สังเกตว่าคุณสมบัติ JavaScript เป็นกรณี ๆ ไป แม้ว่าคุณสมบัติส่วนใหญ่จะใช้ตัวพิมพ์เล็ก แต่บางตัวก็เป็น camelCase ดังนั้นโปรดตรวจสอบข้อมูลจำเพาะเพื่อให้แน่ใจเสมอ

"แผนภูมิ" นี้จับส่วนของต้นแบบลูกโซ่สำหรับวัตถุ DOM เหล่านี้ มันไม่ได้ใกล้จะเสร็จสมบูรณ์ แต่รวบรวมโครงสร้างโดยรวม

                      ____________Node___________
                      |               |         |
                   Element           Text   Comment
                   |     |
           HTMLElement   SVGElement
           |         |
HTMLInputElement   HTMLSpanElement

ตัวอย่างการใช้งาน:

var div = document.getElementsByTagName('div')[0];

//get specific attributes
document.write('Name: class Value: ' + div.className + '<br>');
document.write('Name: id Value: ' + div.id + '<br>');
document.write('Name: ID Value: ' + div.ID + '<br>'); //undefined
document.write('Name: data-test Value: ' + div.dataset.test + '<br>'); //.dataset is a special case
document.write('Name: nonStandard Value: ' + div.nonStandard + '<br>'); //undefined
<div class="class1" id="main" data-test="stuff" nonStandard="1234"></div>

Caveat: นี่คือคำอธิบายว่า HTML spec กำหนดและเบราว์เซอร์ที่ทันสมัยจัดการกับคุณลักษณะอย่างไร ฉันไม่ได้พยายามที่จะจัดการกับข้อ จำกัด ของเบราว์เซอร์โบราณที่เสียหาย หากคุณต้องการสนับสนุนเบราว์เซอร์รุ่นเก่านอกเหนือจากข้อมูลนี้คุณจะต้องทราบว่าเบราว์เซอร์ใดที่เสียหาย


ขอบคุณที่ล้างข้อมูลนี้ ฉันอยากรู้อยากเห็น IE เวอร์ชันใดที่ถือว่า 'ทันสมัย' และเป็นไปตามข้อกำหนด HTML
jkdev

3
@jkdev IE ไม่เคยทันสมัย สิ่งที่เคยเป็นแก่แล้ว
Suraj Jain

ขอบคุณสำหรับคำตอบแบบละเอียดฉันอ่านมากเกี่ยวกับ DOM และการสืบทอดเช่น HTMLElement ที่สืบทอดจาก Element และอื่น ๆ คำตอบของคุณเหมาะสมอย่างยิ่ง
Suraj Jain

16

กรณีหนึ่งที่ฉันพบว่าsetAttributeสิ่งที่จำเป็นคือเมื่อเปลี่ยนคุณลักษณะ ARIA เนื่องจากไม่มีคุณสมบัติที่สอดคล้องกัน ตัวอย่างเช่น

x.setAttribute('aria-label', 'Test');
x.getAttribute('aria-label');

ไม่มีx.arialabelหรืออะไรทำนองนั้นดังนั้นคุณต้องใช้ setAttribute

แก้ไข: x [ "เพลงป้าย"] ไม่ทำงาน คุณต้องการ setAttribute จริงๆ

x.getAttribute('aria-label')
null
x["aria-label"] = "Test"
"Test"
x.getAttribute('aria-label')
null
x.setAttribute('aria-label', 'Test2')
undefined
x["aria-label"]
"Test"
x.getAttribute('aria-label')
"Test2"

จริง ๆ แล้วไม่ได้อยู่ใน Javascript คุณสามารถทำได้ x ["aria-label"]
Fareed Alnamrouti

@fareednamrouti ไม่ทำงาน ฉันเพิ่งทดสอบมัน คุณสมบัติ JS ไม่ส่งผลกระทบต่อแอตทริบิวต์ html คุณต้องการ setAttribute ที่นี่จริงๆ
พลวง

@Antimony นี่แปลก แต่ใช่คุณถูกต้อง 100% ฉันจะโหวต
Fareed Alnamrouti

2
คุณแน่ใจหรือว่าไม่มี ariaLabel?
jgmjgm

8

คำตอบเหล่านี้ไม่ได้จริงๆที่อยู่ความสับสนระหว่างขนาดใหญ่ที่มีคุณสมบัติและคุณลักษณะ นอกจากนี้ขึ้นอยู่กับต้นแบบ Javascript บางครั้งคุณสามารถใช้คุณสมบัติขององค์ประกอบเพื่อเข้าถึงแอตทริบิวต์และบางครั้งคุณไม่สามารถทำได้

ก่อนอื่นคุณต้องจำไว้ว่าHTMLElementเป็นวัตถุ Javascript เช่นเดียวกับวัตถุทั้งหมดพวกมันมีคุณสมบัติ แน่นอนว่าคุณสามารถสร้างสถานที่ที่เรียกว่าเกือบทุกอย่างที่คุณต้องการภายในHTMLElementแต่ไม่ต้องทำอะไรกับ DOM (มีอะไรในหน้า) สัญกรณ์จุด ( .) สำหรับคุณสมบัติ ตอนนี้มีคุณสมบัติพิเศษบางอย่างที่ถูกแมปกับแอตทริบิวต์และในเวลาหรือการเขียนมีเพียง 4 ที่รับประกัน (เพิ่มเติมในภายหลัง)

ทั้งหมดHTMLElements attributesรวมถึงคุณสมบัติที่เรียกว่า HTMLElement.attributesเป็นวัตถุถ่ายทอดสด NamedNodeMapที่เกี่ยวข้องกับองค์ประกอบใน DOM "สด" หมายความว่าเมื่อโหนดเปลี่ยนใน DOM พวกเขาเปลี่ยนในด้าน JavaScript และในทางกลับกัน แอตทริบิวต์ DOM ในกรณีนี้คือโหนดที่เป็นปัญหา A Nodeมี.nodeValueคุณสมบัติที่คุณสามารถเปลี่ยนได้ NamedNodeMapวัตถุมีฟังก์ชั่นที่เรียกว่าsetNamedItemที่คุณสามารถเปลี่ยนโหนดทั้งหมด คุณสามารถเข้าถึงโหนดได้โดยตรงโดยใช้กุญแจ ตัวอย่างเช่นคุณสามารถพูดได้ว่า.attributes["dir"]สิ่งใดที่เหมือนกัน.attributes.getNamedItem('dir');(หมายเหตุด้านข้างNamedNodeMapไม่ตรงตามตัวพิมพ์ใหญ่ - เล็กดังนั้นคุณสามารถผ่านได้'DIR')

มีฟังก์ชั่นที่คล้ายกันโดยตรงในHTMLElementที่คุณก็สามารถโทรsetAttributeซึ่งจะสร้างโดยอัตโนมัติโหนดnodeValueถ้ามันไม่ได้อยู่และการตั้งค่า นอกจากนี้ยังมีบางส่วนแอตทริบิวต์คุณสามารถเข้าถึงโดยตรงเป็นคุณสมบัติในการHTMLElementผ่านคุณสมบัติพิเศษdirเช่น นี่คือการทำแผนที่คร่าวๆของสิ่งที่ดูเหมือนว่า:

HTMLElement {
  attributes: {
    setNamedItem: function(attr, newAttr) { 
      this[attr] = newAttr;
    },    
    getNamedItem: function(attr) {
      return this[attr];
    },
    myAttribute1: {
      nodeName: 'myAttribute1',
      nodeValue: 'myNodeValue1'
    },
    myAttribute2: {
      nodeName: 'myAttribute2',
      nodeValue: 'myNodeValue2'
    },
  }
  setAttribute: function(attr, value) { 
    let item = this.attributes.getNamedItem(attr);
    if (!item) {
      item = document.createAttribute(attr);
      this.attributes.setNamedItem(attr, item);
    }
    item.nodeValue = value;
  },
  getAttribute: function(attr) { 
    return this.attributes[attr] && this.attributes[attr].nodeValue;
  },
  dir: // Special map to attributes.dir.nodeValue || ''
  id:  // Special map to attributes.id.nodeValue || ''
  className: // Special map to attributes.class.nodeValue || '' 
  lang: // Special map to attributes.lang.nodeValue || ''

}

ดังนั้นคุณสามารถเปลี่ยนdirคุณสมบัติได้ 6 วิธี:

  // 1. Replace the node with setNamedItem
  const newAttribute = document.createAttribute('dir');
  newAttribute.nodeValue = 'rtl';
  element.attributes.setNamedItem(newAttribute);

  // 2. Replace the node by property name;
  const newAttribute2 = document.createAttribute('dir');
  newAttribute2.nodeValue = 'rtl';
  element.attributes['dir'] = newAttribute2;
  // OR
  element.attributes.dir = newAttribute2;

  // 3. Access node with getNamedItem and update nodeValue
  // Attribute must already exist!!!
  element.attributes.getNamedItem('dir').nodeValue = 'rtl';

  // 4. Access node by property update nodeValue
  // Attribute must already exist!!!
  element.attributes['dir'].nodeValue = 'rtl';
  // OR
  element.attributes.dir.nodeValue = 'rtl';

  // 5. use setAttribute()  
  element.setAttribute('dir', 'rtl');
  
  // 6. use the UNIQUELY SPECIAL dir property
  element["dir"] = 'rtl';
  element.dir = 'rtl';

คุณสามารถปรับปรุงคุณสมบัติทั้งหมดที่มีวิธีการ # 1-5 แต่เพียงdir, id, langและclassNameด้วยวิธีการ # 6

ส่วนขยายของ HTMLElement

HTMLElementมีคุณสมบัติพิเศษทั้งสี่ องค์ประกอบบางอย่างเป็นคลาสที่ขยายของHTMLElementมีคุณสมบัติที่แมปมากขึ้น ตัวอย่างเช่นHTMLAnchorElementมีHTMLAnchorElement.href, และHTMLAnchorElement.rel HTMLAnchorElement.targetแต่ระวังถ้าคุณตั้งค่าคุณสมบัติเหล่านั้นในองค์ประกอบที่ไม่มีคุณสมบัติพิเศษเหล่านั้น (เช่นบนHTMLTableElement) แล้วแอตทริบิวต์จะไม่เปลี่ยนแปลงและพวกเขาเป็นเพียงคุณสมบัติที่กำหนดเองปกติ เพื่อความเข้าใจที่ดีขึ้นนี่เป็นตัวอย่างของการสืบทอด:

HTMLAnchorElement extends HTMLElement {
  // inherits all of HTMLElement
  href:    // Special map to attributes.href.nodeValue || ''
  target:  // Special map to attributes.target.nodeValue || ''
  rel:     // Special map to attributes.ref.nodeValue || '' 
}

คุณสมบัติที่กำหนดเอง

ตอนนี้คำเตือนครั้งใหญ่: เช่นเดียวกับวัตถุ Javascript ทั้งหมดคุณสามารถเพิ่มคุณสมบัติที่กำหนดเองได้ แต่สิ่งเหล่านี้จะไม่เปลี่ยนแปลงอะไรเลยใน DOM คุณทำได้:

  const newElement = document.createElement('div');
  // THIS WILL NOT CHANGE THE ATTRIBUTE
  newElement.display = 'block';

แต่นั่นก็เหมือนกับ

  newElement.myCustomDisplayAttribute = 'block';

ซึ่งหมายความว่าการเพิ่มคุณสมบัติที่กำหนดเองจะไม่ได้รับการเชื่อมโยงกับ.attributes[attr].nodeValue

ประสิทธิภาพ

ฉันได้สร้างกรณีทดสอบ jsperf เพื่อแสดงให้เห็นความแตกต่าง: https://jsperf.com/set-attribute-comparison โดยทั่วไปในการสั่งซื้อ:

  1. คุณสมบัติแบบกำหนดเองเพราะพวกเขาไม่ส่งผลกระทบต่อ DOM และมีไม่แอตทริบิวต์
  2. แมปพิเศษให้โดยเบราว์เซอร์ ( dir, id, className)
  3. หากคุณลักษณะที่มีอยู่แล้ว ,element.attributes.ATTRIBUTENAME.nodeValue =
  4. setAttribute ();
  5. หากคุณลักษณะที่มีอยู่แล้ว ,element.attributes.getNamedItem(ATTRIBUTENAME).nodeValue = newValue
  6. element.attributes.ATTRIBUTENAME = newNode
  7. element.attributes.setNamedItem(ATTRIBUTENAME) = newNode

สรุป (TL; DR)

  • ใช้แมปคุณสมบัติพิเศษHTMLElement: element.dir, element.id, หรือelement.classNameelement.lang

  • หากคุณมั่นใจ 100% องค์ประกอบนั้นเป็นส่วนขยายที่HTMLElementมีคุณสมบัติพิเศษให้ใช้การจับคู่พิเศษนั้น (คุณสามารถตรวจสอบได้if (element instanceof HTMLAnchorElement))

  • หากคุณเป็น 100% element.attributes.ATTRIBUTENAME.nodeValue = newValueว่าแอตทริบิวต์ที่มีอยู่แล้วการใช้งาน

  • setAttribute()ถ้าไม่ได้ใช้


คุณพูดถึงการแม็พคุณสมบัติสี่เหล่านี้: dir, id, className และ lang สิ่งที่เกี่ยวกับ classList? classList การแม็พคุณสมบัติที่รับประกันว่ามีอยู่จริงหรือไม่?
Barzee

classListรับประกันได้ 100% ว่ามีอยู่จริง แต่ไม่ใช่คุณสมบัติสตริง แต่เป็นDOMTokenListวัตถุจริง การตั้งค่า.classNameโดยตรงนั้นเร็วกว่าการปรับเปลี่ยนclassListแต่คุณจะเขียนทับสิ่งทั้งหมด
ShortFuse

วิธีการเกี่ยวกับ. value ใน <input> และ <textarea> แท็ก พวกเขาเป็นคนแบบไหน?
Daniel Williams

สิ่งที่กล่าวถึงในคำตอบคือสิ่งที่เรียก W3C "สะท้อนคุณลักษณะ IDL" เมื่อคุณเปลี่ยน.valueคุณกำลังเปลี่ยนค่าภายในของHTMLInputElementซึ่งจะสะท้อนให้เห็นถึงคุณลักษณะ stringพวกเขายังไม่จำเป็นต้องเป็น .valueAsNumberจะเปลี่ยนvalue ภายในและstringแบบฟอร์มนั้นจะปรากฏในvalueแอตทริบิวต์ developer.mozilla.org/en-US/docs/Web/HTML/Attributes
ShortFuse

3

"เมื่อใดที่จะใช้ setAttribute vs .attribute = ใน JavaScript?"

กฎทั่วไปคือการใช้.attributeและตรวจสอบว่ามันทำงานบนเบราว์เซอร์

.. ถ้ามันทำงานได้บนเบราว์เซอร์คุณก็สบายดี

..If มันไม่ได้ใช้.setAttribute(attribute, value)แทน.attributeสำหรับที่แอตทริบิวต์

ล้างซ้ำสำหรับคุณลักษณะทั้งหมด

.setAttributeดีถ้าคุณขี้เกียจคุณก็สามารถใช้ ควรทำงานได้ดีบนเบราว์เซอร์ส่วนใหญ่ (แม้ว่าเบราว์เซอร์ที่รองรับ.attributeสามารถปรับแต่งได้ดีกว่า.setAttribute(attribute, value))


0

ดูเหมือนว่ากรณีหนึ่งที่ควรใช้ setAttribute:

Dev.Opera - จาวาสคริปต์ที่มีประสิทธิภาพ

var posElem = document.getElementById('animation');
var newStyle = 'background: ' + newBack + ';' +
'color: ' + newColor + ';' +
    'border: ' + newBorder + ';';
if(typeof(posElem.style.cssText) != 'undefined') {
    posElem.style.cssText = newStyle;
} else {
    posElem.setAttribute('style', newStyle);
}

2
ขอบคุณที่แบ่งปัน tomo7 นี้ขอให้ช่วยอธิบายอีกหน่อยได้ไหม ใช้งานไม่posElem.style = newStyleได้กับเบราว์เซอร์ทั้งหมด (ใช้งานได้กับฉันใน Firefox)? มันเป็นเพียงเหตุผลด้านประสิทธิภาพที่setAttributeเป็นที่ต้องการหลีกเลี่ยงการทาสี? คือposElem.style.cssText = newStyleperfomrant มากขึ้นแล้วposElem.style = newStyle?
Noitidart

0

วิธีการสำหรับการตั้งค่าคุณลักษณะ (ตัวอย่างเช่นคลาส) บนองค์ประกอบ: 1. el.className = string 2. el.setAttribute ('class', string) 3. el.attributes.setNamedItem (วัตถุ) 4. el.setAttributeNode (โหนด)

ฉันทำแบบทดสอบเกณฑ์มาตรฐาน ( ที่นี่ )

และดูเหมือนว่า setAttributeNode จะเร็วกว่าประมาณ 3 เท่าจากนั้นใช้ setAttribute

ดังนั้นหากประสิทธิภาพเป็นปัญหาให้ใช้ "setAttributeNode"


ฉันคิดว่าคุณทำการทดสอบกับโครเมี่ยม ฉันใช้ mac กับ chrome, safari และ firefox บนคอมพิวเตอร์ของฉัน คาดว่า 3 ของพวกเขาแสดงให้เห็น 3 ผลลัพธ์ที่แตกต่าง
Olgun Kaya

0

ซื้อกลับบ้านที่น่าสนใจจากสคริปต์ Google APIเกี่ยวกับเรื่องนี้:

พวกเขาทำเช่นนี้:

var scriptElement = document.createElement("script");
scriptElement = setAttribute("src", "https://some.com");
scriptElement = setAttribute("nonce", "https://some.com");
scriptElement.async = "true";

แจ้งให้ทราบว่าพวกเขาใช้setAttributeสำหรับ "src" และ "nonce" แต่แล้ว.async = ...สำหรับแอตทริบิวต์ "async"

ฉันไม่แน่ใจ 100% แต่อาจเป็นเพราะ "async" รองรับเฉพาะเบราว์เซอร์ที่รองรับการ.attr =กำหนดโดยตรง ดังนั้นจึงไม่มีเหตุผลที่จะลองsestAttribute("async")เพราะหากเบราว์เซอร์ไม่เข้าใจ.async=...- จะไม่เข้าใจแอตทริบิวต์ "async"

หวังว่านี่เป็นข้อมูลเชิงลึกที่เป็นประโยชน์จากโครงการวิจัย"Un-Minify GAPI" ที่กำลังดำเนินอยู่ ช่วยแก้ให้ด้วยนะถ้าฉันผิด.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.