getElementById a XBL bound XUL element

2019-04-16 09:59发布

问题:

I'm trying to access a XUL element which was XBL bound. I want to controll it from the javascript.

This is the binding.

<binding id="imip-throbber">
    <resources>
          <stylesheet src="chrome://lightning/skin/lightning-widgets.css"/>
    </resources>
    <content pack="center" align="center">
        <xul:image anonid="loading-throbber" src="chrome://global/skin/icons/loading_16.png" hidden="false"/>
    </content>
</binding>

This is the CSS binding

imip-throbber {
  -moz-binding: url(chrome://lightning/content/lightning-widgets.xml#imip-throbber);
}

this is the xul implementation

<

lightning-notification-bar id="imip-bar"
                                    collapsed="true"
                                    insertbefore="msgHeaderView"
                                    label="&lightning.imipbar.description;">

          <button id="imip-button1"
                  class="imip-button"
                  hidden="true"/>
          <button id="imip-button2"
                  class="imip-button"
                  hidden="true"/>
          <button id="imip-button3"
                  class="imip-button"
                  hidden="true"/>

    <imip-throbber id="loading-lbl">
</lightning-notification-bar>

This is the javascript access

let imipThrobble = document.getElementById("loading-lbl");

code below that javascript line not seemed to be executed. Do I need to add something at the binding to access the element?

回答1:

Can't easily...

The documentation on XBL at MDN says this about the "anonymous" content automatically added by XBL:

The elements within the content tag [of the XBL binding xml file] are added to the scroll bar anonymously. Although anonymous content is displayed on screen, you cannot get to it through a script in the normal way. To the XUL, it's as if there was only one single element, even though it is really made up of a number of elements.

(Emphasis mine).

In any case...

The XBL 1.0 reference at MDN goes on to say

In effect the anonymous content exists in its own insulated pocket within the document. Using parentNode, anonymous content nodes can refer to their explicit parents, but explicit parents have no knowledge of their anonymous children. The anonymous content is not accessible via the childNodes list for the bound element, nor is it accessible using firstChild/nextSibling to iterate over the children of the bound element. The anonymous content is accessible only through special methods like getAnonymousNodes and getAnonymousElementByAttribute.

So you can use getAnonymousNodes / getAnonymousElementByAttribute to get at the anonymous content auto-inserted by the XBL binding. These methods are primarily used by the JavaScript code in (or related to) bindings themselves, however, you can use them from JavaScript bound to the XUL DOM. Some examples at MDN.

But why?

A better question would be, why do you want to access these elements from JavaScript bound to the XUL DOM?

A good reason might be that you didn't write the bindings and you wish to "upgrade" them with some different content/behaviour on the fly. If, on the other hand, you did write the XBL bindings in question, why not accomplish what you're trying to do within the JavaScript bound to the XBL element? You can add JavaScript methods to your elements which already have access to the anonymous content (and the rest of the XUL DOM too).