funkcja zdefiniowana przez użytkownika nie jest błędem funkcji podczas implementacji funkcji ECMAScript 5 insertAjacentHTML()

to, co robię, to generowanie nawigacji po postach przy użyciu czystego javascript. Ale pokazuje, że zanimClosingTag nie jest funkcją

w funkcjach narzędzi poniżej powinna to być funkcja, ponieważ kod przedClosingTag został przeze mnie użyty jako funkcja. we fragmencie może wygenerować listę ul, ale jeśli przejrzysz inspektora sieci, nadal możesz znaleźć:

**Uncaught TypeError: greatApp.tools.insertHTMLString.beforeClosingTag is not a function**

A poza tym w moim lokalnym środowisku ten sam kod, ale nie pokazuje nawet listy ul, nie wiem dlaczego. Dziękuję

//global tools function(insertHTMLString.beforeClosingTag)

    var greatApp = greatApp || {};
    
    (function(){
      greatApp.tools = {
    
       insertHTMLString:  function(){
        /*****
            if elements have a native insertAdjacentHTML : use it in four html insertion functions with more sensible names
        *****/
    
            if(document.createElement('div').insertAdjacentHTML){
              return {
                  beforeOpeningTag: function(element,htmlString){
                    element.insertAdjacentHTML('beforebegin',htmlString);
                  },
                  afterOpeningTag:  function(element,htmlString){
                    element.insertAdjacentHTML('afterbegin',htmlString);
                  },
                  beforeClosingTag:  function(element,htmlString){
                    element.insertAdjacentHTML('beforeend',htmlString);
                  },
                  afterClosingTag:  function(element,htmlString){
                    element.insertAdjacentHTML('afterend',htmlString);
                  }
              }
            }//end if 
    
    
        /********
            otherwise, we have no native insertAdjacentHTML : implement the same four insertion functions and then use them to define insertAdjacentHTML
        ******/
    
               function fragment(htmlString){
                    var ele = document.createElement('div');
                    var frag = document.createDocumentFragment();
                    ele.innerHTML = htmlString;
    
                    //move all nodes from ele to frag
                    while(ele.firstChild)
                       frag.appendChild(ele.firstChild);
    
                    return frag;
               }        
               var insertHTMLString = {
                  beforeOpeningTag: function(element,htmlString){
                    element.parentNode.insertBefore(fragment(htmlString),element);
                  },
                  afterOpeningTag:  function(element,htmlString){
                    element.parentNode.insertBefore(fragment(htmlString),element.firstChild);
                  },
                  beforeClosingTag:  function(element,htmlString){
                    element.parentNode.appendChild(fragment(htmlString));
                  },
                  afterClosingTag:  function(element,htmlString){
                    element.parentNode.insertBefore(fragment(htmlString),element.nextSibling);
                  }                
               };
    
               /**
                  now implement insertAdjacentHMTL based on the functions above
              **/
    
              Element.prototype.insertAdjacentHMTL = function(pos, htmlString){
                switch(pos.toLowerCase()){
                  case "beforebegin": return insertHTMLString.beforeOpeningTag(this, htmlString);
                  case "afterbegin": return insertHTMLString.afterOpeningTag(this, htmlString);
                  case "beforeend": return insertHTMLString.beforeClosingTag(this, htmlString);
                  case "afterend": return insertHTMLString.beforeClosingTag(this, htmlString);
    
                }
              };
              return insertHTMLString;
        },
    
    }}());





//post js

(function(){
             var titles = document.querySelectorAll('.sideNav h3');
             var sideList = document.getElementsByClassName('sideList')[0];
             var ul = document.querySelectorAll('.sideList ul')[0];
   
               for(var i = 0; i< titles.length; i++){

                     var aWithhref = '<a href = ' + '#' + titles[i].getAttribute('id') + '>';
                     var titleText = titles[i].textContent || titles[i].innerText;
                     var li = '<li>'+ aWithhref + titleText +'</a>'+ '</li>';
                      
                    (Element.prototype.insertAjacentHTML)? ul.insertAdjacentHTML('beforeend',li) : greatApp.tools.insertHTMLString.beforeClosingTag(ul, li);
                 }   

         }());
<div class="row expanded docHomeDetails sideNav">
 <h3 id="homeCollectionUpdate"># Update</h3>
  <h3 id="homee"># home</h3>
  <h3 id="Update"># forum</h3>
</div>             
<div class="small-12 medium-4 columns sideList" data-sticky-container >
		  	    	 
                   <div class="sticky" data-sticky data-top-anchor="homeCollectionUpdate" data-btm-anchor="homeCollectionMentorWrapper:bottom">
                      <ul>
                      	<p>页面导航</p>
                      </ul>
                   </div>

                    
		  	    </div>

		  	</div>

Dzięki za pomoc.

Mój kod w następujący sposób:

//html

        <div class="small-12 medium-4 columns sideList" data-sticky-container >

           <div class="sticky" data-sticky data-top-anchor="homeCollectionUpdate" data-btm-anchor="homeCollectionMentorWrapper:bottom">
              <ul>
                <p>页面导航</p>
              </ul>
           </div>
        </div>

//javascript

     (function(){
         var titles = document.querySelectorAll('.sideNav h3');
         var sideList = document.getElementsByClassName('sideList')[0];
         var ul = document.querySelectorAll('.sideList ul')[0];

           for(var i = 0; i< titles.length; i++){

                 var aWithhref = '<a href = ' + '#' + titles[i].getAttribute('id') + '>';
                 var titleText = titles[i].textContent || titles[i].innerText;
                 var li = '<li>'+ aWithhref + titleText +'</a>'+ '</li>';

                (Element.prototype.insertAjacentHTML)? ul.insertAdjacentHTML('beforeend',li) : greatApp.tools.insertHTMLString.beforeClosingTag(ul, li);
             }   

     }());

//funkcja narzędzi globalnych (wstaw HTMLString.beforeClosingTag)

var greatApp = greatApp || {};

(function(){
  greatApp.tools = {

   insertHTMLString:  function(){
    /*****
        if elements have a native insertAdjacentHTML : use it in four html insertion functions with more sensible names
    *****/

        if(document.createElement('div').insertAdjacentHTML){
          return {
              beforeOpeningTag: function(element,htmlString){
                element.insertAdjacentHTML('beforebegin',htmlString);
              },
              afterOpeningTag:  function(element,htmlString){
                element.insertAdjacentHTML('afterbegin',htmlString);
              },
              beforeClosingTag:  function(element,htmlString){
                element.insertAdjacentHTML('beforeend',htmlString);
              },
              afterClosingTag:  function(element,htmlString){
                element.insertAdjacentHTML('afterend',htmlString);
              }
          }
        }//end if 


    /********
        otherwise, we have no native insertAdjacentHTML : implement the same four insertion functions and then use them to define insertAdjacentHTML
    ******/

           function fragment(htmlString){
                var ele = document.createElement('div');
                var frag = document.createDocumentFragment();
                ele.innerHTML = htmlString;

                //move all nodes from ele to frag
                while(ele.firstChild)
                   frag.appendChild(ele.firstChild);

                return frag;
           }        
           var insertHTMLString = {
              beforeOpeningTag: function(element,htmlString){
                element.parentNode.insertBefore(fragment(htmlString),element);
              },
              afterOpeningTag:  function(element,htmlString){
                element.parentNode.insertBefore(fragment(htmlString),element.firstChild);
              },
              beforeClosingTag:  function(element,htmlString){
                element.parentNode.appendChild(fragment(htmlString));
              },
              afterClosingTag:  function(element,htmlString){
                element.parentNode.insertBefore(fragment(htmlString),element.nextSibling);
              }                
           };

           /**
              now implement insertAdjacentHMTL based on the functions above
          **/

          Element.prototype.insertAdjacentHMTL = function(pos, htmlString){
            switch(pos.toLowerCase()){
              case "beforebegin": return insertHTMLString.beforeOpeningTag(this, htmlString);
              case "afterbegin": return insertHTMLString.afterOpeningTag(this, htmlString);
              case "beforeend": return insertHTMLString.beforeClosingTag(this, htmlString);
              case "afterend": return insertHTMLString.beforeClosingTag(this, htmlString);

            }
          };
          return insertHTMLString;
    },

}}());

person franklee    schedule 06.01.2016    source źródło


Odpowiedzi (1)


Dzieje się tak, ponieważ insertHTMLString jest funkcją, a nie obiektem. Możesz stworzyć obiekt taki jak:

var innerHTMLObj = new greatApp.tools.insertHTMLString();    
(Element.prototype.insertAjacentHTML) ?
  ul.insertAdjacentHTML('beforeend', li): 
  innerHTMLObj.beforeClosingTag(ul, li);

Możesz go zastąpić przez IIFE.

Implementacja obiektu

//global tools function(insertHTMLString.beforeClosingTag)

var greatApp = greatApp || {};

(function() {
  greatApp.tools = {

    insertHTMLString: function() {
      /*****
          if elements have a native insertAdjacentHTML : use it in four html insertion functions with more sensible names
      *****/

      if (document.createElement('div').insertAdjacentHTML) {
        return {
          beforeOpeningTag: function(element, htmlString) {
            element.insertAdjacentHTML('beforebegin', htmlString);
          },
          afterOpeningTag: function(element, htmlString) {
            element.insertAdjacentHTML('afterbegin', htmlString);
          },
          beforeClosingTag: function(element, htmlString) {
            element.insertAdjacentHTML('beforeend', htmlString);
          },
          afterClosingTag: function(element, htmlString) {
            element.insertAdjacentHTML('afterend', htmlString);
          }
        }
      } //end if 


      /********
          otherwise, we have no native insertAdjacentHTML : implement the same four insertion functions and then use them to define insertAdjacentHTML
      ******/

      function fragment(htmlString) {
        var ele = document.createElement('div');
        var frag = document.createDocumentFragment();
        ele.innerHTML = htmlString;

        //move all nodes from ele to frag
        while (ele.firstChild)
          frag.appendChild(ele.firstChild);

        return frag;
      }
      var insertHTMLString = {
        beforeOpeningTag: function(element, htmlString) {
          element.parentNode.insertBefore(fragment(htmlString), element);
        },
        afterOpeningTag: function(element, htmlString) {
          element.parentNode.insertBefore(fragment(htmlString), element.firstChild);
        },
        beforeClosingTag: function(element, htmlString) {
          element.parentNode.appendChild(fragment(htmlString));
        },
        afterClosingTag: function(element, htmlString) {
          element.parentNode.insertBefore(fragment(htmlString), element.nextSibling);
        }
      };

      /**
                  now implement insertAdjacentHMTL based on the functions above
              **/

      Element.prototype.insertAdjacentHMTL = function(pos, htmlString) {
        switch (pos.toLowerCase()) {
          case "beforebegin":
            return insertHTMLString.beforeOpeningTag(this, htmlString);
          case "afterbegin":
            return insertHTMLString.afterOpeningTag(this, htmlString);
          case "beforeend":
            return insertHTMLString.beforeClosingTag(this, htmlString);
          case "afterend":
            return insertHTMLString.beforeClosingTag(this, htmlString);

        }
      };
      return insertHTMLString;
    },

  }
}());





//post js

(function() {
  var titles = document.querySelectorAll('.sideNav h3');
  var sideList = document.getElementsByClassName('sideList')[0];
  var ul = document.querySelectorAll('.sideList ul')[0];

  for (var i = 0; i < titles.length; i++) {

    var aWithhref = '<a href = ' + '#' + titles[i].getAttribute('id') + '>';
    var titleText = titles[i].textContent || titles[i].innerText;
    var li = '<li>' + aWithhref + titleText + '</a>' + '</li>';

    
    var innerHTMLObj = new greatApp.tools.insertHTMLString();
    
    (Element.prototype.insertAjacentHTML) ? ul.insertAdjacentHTML('beforeend', li): innerHTMLObj.beforeClosingTag(ul, li);
  }

}());
<div class="row expanded docHomeDetails sideNav">
  <h3 id="homeCollectionUpdate"># Update</h3>
  <h3 id="homee"># home</h3>
  <h3 id="Update"># forum</h3>

  <div class="small-12 medium-4 columns sideList" data-sticky-container>

    <div class="sticky" data-sticky data-top-anchor="homeCollectionUpdate" data-btm-anchor="homeCollectionMentorWrapper:bottom">
      <ul>
        <p>页面导航</p>
      </ul>
    </div>


  </div>

</div>

Implementacja IIFE

//global tools function(insertHTMLString.beforeClosingTag)

var greatApp = greatApp || {};

(function() {
  greatApp.tools = {

    insertHTMLString: (function() {
      /*****
          if elements have a native insertAdjacentHTML : use it in four html insertion functions with more sensible names
      *****/

      if (document.createElement('div').insertAdjacentHTML) {
        return {
          beforeOpeningTag: function(element, htmlString) {
            element.insertAdjacentHTML('beforebegin', htmlString);
          },
          afterOpeningTag: function(element, htmlString) {
            element.insertAdjacentHTML('afterbegin', htmlString);
          },
          beforeClosingTag: function(element, htmlString) {
            element.insertAdjacentHTML('beforeend', htmlString);
          },
          afterClosingTag: function(element, htmlString) {
            element.insertAdjacentHTML('afterend', htmlString);
          }
        }
      } //end if 


      /********
          otherwise, we have no native insertAdjacentHTML : implement the same four insertion functions and then use them to define insertAdjacentHTML
      ******/

      function fragment(htmlString) {
        var ele = document.createElement('div');
        var frag = document.createDocumentFragment();
        ele.innerHTML = htmlString;

        //move all nodes from ele to frag
        while (ele.firstChild)
          frag.appendChild(ele.firstChild);

        return frag;
      }
      var insertHTMLString = {
        beforeOpeningTag: function(element, htmlString) {
          element.parentNode.insertBefore(fragment(htmlString), element);
        },
        afterOpeningTag: function(element, htmlString) {
          element.parentNode.insertBefore(fragment(htmlString), element.firstChild);
        },
        beforeClosingTag: function(element, htmlString) {
          element.parentNode.appendChild(fragment(htmlString));
        },
        afterClosingTag: function(element, htmlString) {
          element.parentNode.insertBefore(fragment(htmlString), element.nextSibling);
        }
      };

      /**
                  now implement insertAdjacentHMTL based on the functions above
              **/

      Element.prototype.insertAdjacentHMTL = function(pos, htmlString) {
        switch (pos.toLowerCase()) {
          case "beforebegin":
            return insertHTMLString.beforeOpeningTag(this, htmlString);
          case "afterbegin":
            return insertHTMLString.afterOpeningTag(this, htmlString);
          case "beforeend":
            return insertHTMLString.beforeClosingTag(this, htmlString);
          case "afterend":
            return insertHTMLString.beforeClosingTag(this, htmlString);

        }
      };
      return insertHTMLString;
    })(),

  }
}());





//post js

(function() {
  var titles = document.querySelectorAll('.sideNav h3');
  var sideList = document.getElementsByClassName('sideList')[0];
  var ul = document.querySelectorAll('.sideList ul')[0];

  for (var i = 0; i < titles.length; i++) {

    var aWithhref = '<a href = ' + '#' + titles[i].getAttribute('id') + '>';
    var titleText = titles[i].textContent || titles[i].innerText;
    var li = '<li>' + aWithhref + titleText + '</a>' + '</li>';
    
    (Element.prototype.insertAjacentHTML) ? ul.insertAdjacentHTML('beforeend', li): greatApp.tools.insertHTMLString.beforeClosingTag(ul, li);
  }

}());
<div class="row expanded docHomeDetails sideNav">
  <h3 id="homeCollectionUpdate"># Update</h3>
  <h3 id="homee"># home</h3>
  <h3 id="Update"># forum</h3>

  <div class="small-12 medium-4 columns sideList" data-sticky-container>

    <div class="sticky" data-sticky data-top-anchor="homeCollectionUpdate" data-btm-anchor="homeCollectionMentorWrapper:bottom">
      <ul>
        <p>页面导航</p>
      </ul>
    </div>


  </div>

</div>

person Rajesh    schedule 06.01.2016
comment
insertHTMLString jest funkcją, a nie obiektem. ? Myślałem, że zwracam funkcje takie jak beforeClosingTag pod insertHTMLString, więc mogę je uzyskać przez insertHTMLString.beforeClosingTag. Nawiasem mówiąc, funkcja też jest przedmiotem. Czy możesz wyjaśnić ten punkt więcej szczegółów, wielkie dzięki. Js uczyłem się zaledwie kilka miesięcy. Po prostu traktuj mnie jak nowego ucznia,^_^. - person franklee; 06.01.2016
comment
Ponadto, przy okazji (mam plik globalny tools.js), czy muszę zainicjować całą metodę, zanim będę mógł uzyskać funkcję zwróconą przez metodę? - person franklee; 06.01.2016
comment
Ponieważ funkcja jest również obiektem, możesz zapoznać się z następującym postem. Punkt jest wtedy, gdy piszesz funkcję, dopóki jej nie wywołasz, nic nie zostanie zwrócone. Jeśli więc chcesz uzyskać dostęp do a.b.c, tutaj a i b muszą być obiektami. - person Rajesh; 06.01.2016
comment
Zainspirowany powyższym komentarzem, znalazłem: greatApp.tools.insertHTMLString().beforeClosingTag(ul, li); może pracować dla mnie. oznacza to, że bez inicjowania funkcji mogę również uzyskać żądaną wartość? Dzięki! - person franklee; 06.01.2016
comment
greatApp.tools.insertHTMLString().beforeClosingTag To zła praktyka. Powinieneś przypisać go do zmiennej i używać go. W ten sposób wystarczy wywołać funkcję insertHTMLString() tylko raz. - person Rajesh; 06.01.2016
comment
Dziękujemy za radę.greatApp.tools.insertHTMLString().beforeClosingTag i inicjowanie obiektu, co sugerujesz? - person franklee; 06.01.2016