определяемая пользователем функция не является ошибкой функции при реализации функции ECMAScript 5 insertAjacentHTML()

что я делаю, так это генерирую навигацию по сообщению, используя чистый javascript. Но это показывает, что beforeClosingTag не является функцией

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

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

И кроме того, в моей локальной среде такой же код, но он даже не может показать список ul, я не знаю, почему. Спасибо

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

Спасибо за помощь.

Мой код выглядит следующим образом:

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

     }());

// глобальная функция инструментов (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;
    },

}}());

person franklee    schedule 06.01.2016    source источник


Ответы (1)


Это потому, что insertHTMLString — это функция, а не объект. Вы можете создать объект, например:

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

Вы можете заменить его на 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>';

    
    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>

Реализация 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 — это функция, а не объект. ? Я думал, что возвращаю функции, такие как beforeClosingTag, в insertHTMLString, поэтому я могу получить его с помощью insertHTMLString.beforeClosingTag. Кстати, функция тоже объект. Можете ли вы объяснить этот момент более подробно, большое спасибо. Я изучил js всего несколько месяцев. Просто относитесь ко мне как к новичку, ^_^ . - person franklee; 06.01.2016
comment
Кроме того, кстати, (у меня есть глобальный файл tools.js), нужно ли мне инициализировать весь метод, прежде чем я смогу получить функцию, возвращаемую методом? - person franklee; 06.01.2016
comment
Поскольку функция также является объектом, вы можете обратиться к следующему post. Дело в том, что когда вы пишете функцию, пока вы ее не вызовете, ничего не возвращается. Итак, если вы хотите получить доступ к a.b.c, здесь a и b должны быть объектами. - person Rajesh; 06.01.2016
comment
Вдохновленный вашим комментарием выше, я нашел: greatApp.tools.insertHTMLString().beforeClosingTag(ul, li); может работать на меня. так что это означает, что без инициализации функции я также могу получить желаемое значение? Спасибо. - person franklee; 06.01.2016
comment
greatApp.tools.insertHTMLString().beforeClosingTag Это плохая практика. Вы должны назначить его переменной и использовать ее. Таким образом, вам нужно будет вызвать функцию insertHTMLString() только один раз. - person Rajesh; 06.01.2016
comment
Спасибо за ваш совет.greatApp.tools.insertHTMLString().beforeClosingTag и инициализацию объекта, что вы предлагаете? - person franklee; 06.01.2016