在实现ECMAScript 5 insertAjacentHTML()函数时,用户定义的函数不是函数错误

user defined function is not a function error when implementing ECMAScript 5 insertAjacentHTML() function

本文关键字:函数 定义 用户 错误 ECMAScript insertAjacentHTML 实现      更新时间:2023-09-26

我正在做的是使用纯javascript生成后期导航。但它显示beforeCloseTag不是一个函数

在下面的工具函数中,它应该是一个函数,因为我在CloseTag作为函数之前做了代码。在这个片段中,它可以生成ul列表,但如果你通过web检查器查看,你仍然可以找到:

**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.foreCloseTag)

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;
    },
}}());
这是因为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>