简体   繁体   English

使用动态onclick功能动态创建一个div

[英]Dynamically create a div with dynamic onclick function

Context: I'm lazy, and I'm trying to dynamically/automatically create menu buttons which are hyperlinked to the headers of a page with raw JavaScript.上下文:我很懒,我正在尝试使用原始 JavaScript 动态/自动创建超链接到页面标题的菜单按钮。

My site loads the content of the body from an external file located at the same folder with document.onload, and I'm trying to set up a menu function, which then should load the default page's menu items.我的站点从位于与 document.onload 相同的文件夹中的外部文件加载正文的内容,我正在尝试设置一个菜单功能,然后应该加载默认页面的菜单项。 Loading the menu manually each time I change from one page to another works, as I've included loadMenues(thispage) on the end loadContents(), but it doesn't work as soon as the page is loaded, as loading the body content does.每次我从一个页面切换到另一个页面时手动加载菜单是有效的,因为我在最后的 loadContents() 中包含了 loadMenues(thispage),但是在加载页面时它不会立即工作,因为加载正文内容做。 I don't understand this behaviour.我不明白这种行为。

function setVisible(thisdiv){
    var alldivs = document.getElementsByClassName("container");
    [].forEach.call(alldivs, function(uniquediv){
        document.getElementById(uniquediv.id).style.display = "none";
        return;
    });
    document.getElementById(thisdiv).style.display = "block";
    window.scrollTo(0,0);
    loadMenues(thisdiv);
}
window.onload = function(){
    loadContent("personalinfo");
    loadContent("contactdetails");
    setVisible("personalinfo");
    loadMenues("personalinfo");
}

I'm explaining this, secondary question, in order to contextualize my main problem.我正在解释这个次要问题,以便将我的主要问题置于语境中。

loadContents(file) is a function which extracts the contents from the requested file. loadContents(file) 是一个从请求的文件中提取内容的函数。 The layout of each of these files is the same, pretty much, with each section of the file being separated by a custompadding div , where its first child is a h1 element as shown below:每个文件的布局几乎相同,文件的每个部分都由custompadding div分隔,其中第一个子元素是h1元素,如下所示:

<html>
    <div class="custompadding">
        <h1 id="headerpersonaldetails">Personal details</h1>
        <p>Lorem ipsum</p>
    </div>
    <div class="custompadding">
        <h1 id="headercontactdetails">Contact details</h1>
        <p>Lorem ipsum</p>
    </div>
</html>

I'm trying to set up a menu item for each of these headings, which scrolls to the clicked-on header.我正在尝试为这些标题中的每一个设置一个菜单项,该菜单项会滚动到单击的标题。 Setting up each menu-item manually works as expected, but I want to automatize it, so changing any file will automatically add the menu items to whichever page we change to.手动设置每个菜单项按预期工作,但我想使其自动化,因此更改任何文件都会自动将菜单项添加到我们更改的页面。 Following is my code which adds these elements to the divisor, but I'm having issues handling the onclick function.以下是我将这些元素添加到除数的代码,但我在处理 onclick 函数时遇到了问题。

function loadMenues(file) {
    var rightmenu = document.getElementById("right-menu");
    while(rightmenu.firstChild){
        rightmenu.removeChild(rightmenu.firstChild);
    }
    [].forEach.call(document.getElementById(file).children, function(custompaddingchild) {
    console.log(custompaddingchild);
    headerelement = custompaddingchild.getElementsByTagName("h1")[0]
    newbutton = document.createElement("div");
    newbutton.setAttribute("class", "menu-item");
    let movehere = function() { location.href="#"+headerelement.id; console.log(headerelement.id); }
    newbutton.onclick = movehere;
    /*rightmenu = document.getElementById("right-menu");*/
    buttonspanner = document.createElement("span");
    buttoncontent = document.createTextNode(headerelement.innerHTML);
    buttonspanner.appendChild(buttoncontent);
    newbutton.appendChild(buttonspanner);
    rightmenu.appendChild(newbutton);
    });
}

The first part of the function deletes all the nodes which already are in the menu, in order to add the new ones when changing pages.该功能的第一部分删除菜单中已有的所有节点,以便在换页时添加新节点。

Trying to define newbutton.setAttribute() with onclick results in a SyntaxError (fields are not currently supported) in Firefox.在 Firefox 中尝试使用onclick定义 newbutton.setAttribute() 会导致 SyntaxError(当前不支持字段)。 It doesn't work if I set a static string as newbutton.setAttribute("onclick", "location.href=#headerpersonalinfo");如果我将静态字符串设置为newbutton.setAttribute("onclick", "location.href=#headerpersonalinfo"); either.任何一个。

Trying to set a static anchor link with newbutton.onclick set to a function, instead, works, such that尝试将newbutton.onclick设置为函数的静态锚链接设置为一个函数,而是有效,这样

newbutton.onclick = function() {
    location.href = "#headerpersonalinfo";
}

and this is pretty much how my current code is set up, except that I have given this function a unique variable, which I then call.这几乎是我当前代码的设置方式,除了我给这个函数一个唯一的变量,然后我调用它。

The problem I have is this, as I see it: The variable is redefined each time it finds a new header, so calling the function sends the user to the last header, and not the expected one.我遇到的问题是,正如我所看到的:每次找到新标头时都会重新定义变量,因此调用该函数会将用户发送到最后一个标头,而不是预期的标头。 How can I set the function to be parsed at the moment I define onclick with it, and not call the function when the user presses the button?如何在我用它定义onclick时设置要解析的函数,而不是在用户按下按钮时调用该函数?

PS: I'm using my own internal naming convention of files, headers, and items, in order to modularize my site as much as I can. PS:我正在使用我自己的文件、标题和项目的内部命名约定,以便尽可能地模块化我的网站。 Since this is a website only intended for my Curriculum Vitae, I'm its only developer.由于这是一个仅用于我的简历的网站,因此我是其唯一的开发人员。

The issue occurs because the you are hoisting "variables" to the global scope (newbutton and headerelement).出现此问题是因为您将“变量”提升到全局范围(newbutton 和 headerelement)。

Set them to block scoped variables ( const or let ) and you will see that it works: https://codesandbox.io/s/rm4ko35vnm将它们设置为阻止作用域变量( constlet ),您将看到它的工作原理: https : //codesandbox.io/s/rm4ko35vnm

function loadMenues(file) {
  var rightmenu = document.getElementById("right-menu");
  while (rightmenu.firstChild) {
    rightmenu.removeChild(rightmenu.firstChild);
  }
  [].forEach.call(document.getElementById(file).children, function(
    custompaddingchild
  ) {
    console.log(custompaddingchild);
    const headerelement = custompaddingchild.getElementsByTagName("h1")[0];
    console.log(headerelement.innerHTML);
    const newbutton = document.createElement("div");
    newbutton.setAttribute("class", "menu-item");
    console.log(headerelement.id);
    let movehere = function() {
      location.href = "#" + headerelement.id;
      console.log(headerelement.id);
    };
    newbutton.addEventListener('click', movehere);
    const rightmenu = document.getElementById("right-menu");
    const buttonspanner = document.createElement("span");
    buttoncontent = document.createTextNode(headerelement.innerHTML);
    buttonspanner.appendChild(buttoncontent);
    newbutton.appendChild(buttonspanner);
    rightmenu.appendChild(newbutton);
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM