JavaScript元素创建差异导致jquery.ui.autocomplete元素未定义错误

如何解决JavaScript元素创建差异导致jquery.ui.autocomplete元素未定义错误

我正在尝试动态创建输入元素,并将jquery.ui自动完成控件附加到该元素,然后再将其添加到DOM。我通常创建动态元素的方式似乎正在创建Cannot read property 'element' of undefined错误,但我不知道为什么。

$(document).ready(() => {
  const content = document.getElementById('content');
  const input = document.createElement('input');
  const inputFromTemplate = createFromTemplate(`<input></input>`);

  console.log(input);
  console.log(inputFromTemplate);

  $(input).autocomplete({
    source: ['one','two','three']
  });

  $(inputFromTemplate).autocomplete({
    source: ['one','three']
  });

  content.append(input);
  content.append(inputFromTemplate);
});

function createFromTemplate(template) {
  const htmlTemplate = document.createElement('template');
  htmlTemplate.innerHTML = template;

  return htmlTemplate.content.firstElementChild.cloneNode(true);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<div id="content"></div>

在上面的代码示例中,当我使用input方法创建document.createElement('input')元素时,自动完成控件将毫无问题地附着。

当我使用自己的input方法创建createFromTemplate元素时,会引发上述错误。

两个元素在登录到控制台后看起来都一样,但是似乎在console.log触发之前附加了自动完成控件(您可以按原样运行,然后注释掉{{1} }行代码,并看到.autocomplete代码中的差异已注销到控制台。

我认为我对jquery如何将控件附加到元素的理解是有缺陷的,因为我看不出为什么两者之间会有区别。

(注意:是的,这是一个简单的复制,我想使用类似input之类的函数的原因是因为实际输入是更大的html模板的一部分,因此将createFromTemplate方法链接在一起不会发生)。

编辑: 只是为了解决当元素首先附加到DOM时它起作用的问题,不幸的是,对于我正在处理的项目,这不是一个选择。 Something akin to this issue was reported and fixed in a previous version of jquery.ui back in 2012,所以很可能是库的错误

解决方法

我建议您快速阅读:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template

DocumentFragment不是各种事件的有效目标,因此通常最好克隆或引用其中的元素。

HTML

<div id="container"></div>

<template id="template">
  <div>Click me</div>
</template>

JavaScript

const container = document.getElementById("container");
const template = document.getElementById("template");

function clickHandler(event) {
  alert("Clicked a div");
}

const firstClone = template.content.cloneNode(true);
firstClone.addEventListener("click",clickHandler);
container.appendChild(firstClone);

const secondClone = template.content.firstElementChild.cloneNode(true);
secondClone.addEventListener("click",clickHandler);
container.appendChild(secondClone);

结果

firstClone是一个DocumentFragment实例,因此,尽管按预期将其添加到了容器内,但单击它不会触发click事件secondClone是一个HTMLDivElement实例,单击它可以像预期的那样工作。

尝试初始化自动完成时,事件绑定将失败。这可能就是为什么您看到各种不同的错误以及为什么其他元素在起作用而template中的元素却没有起作用的原因。

因此,让我们根据他们的建议进行测试,尝试的方式以及其他可能的解决方案。

$(document).ready(() => {
  const content = document.getElementById('content');
  var inA = document.createElement('input');
  var inB = createTempObj("<input>");
  var inC = createFromTemplate("<input>");
  var inD = document.getElementById("template").content.firstElementChild.cloneNode(true);
  var m1 = menuFromTemp();

  console.log("Init Autocomplete 1");
  console.log("HTML",inA);

  initAutoComplete(inA);

  console.log("Init Autocomplete 2");
  console.log("HTML",inB);

  initAutoComplete(inB);

  console.log("Init Autocomplete 3");
  console.log("HTML",typeof inC,inC);
  
  initAutoComplete(inC);

  console.log("Init Autocomplete 4");
  console.log("HTML",inD);

  //initAutoComplete(inD);

  console.log("Init Menu 1");
  console.log("HTML",m1);
  var menu = $(m1).menu({
    role: null
  }).hide().menu("instance");

  content.append(inA);
  content.append(inB);
  content.append(inC);
  content.append(inD);
  content.append(m1);
});

function createFromTemplate(item) {
  var base = document.createElement('template');
  var real = document.createElement('input');
  console.log("item:",typeof item,item);
  console.log("real:",typeof real,real);
  base.innerHTML = item;
  var clone = base.content.children[0].cloneNode(true);
  console.log("clone:",typeof clone,clone);
  return clone;
};

function createTempObj(el) {
  var base = $("<template>");
  $(el).appendTo(base);
  return base.children(0).clone("true")[0];
}

function initAutoComplete(el) {
  $(el).autocomplete({
    source: ['one','two','three']
  });
}

function menuFromTemp() {
  var base = document.createElement('template');
  base.innerHTML = "<ul><li><div>Books</div></li><li><div>Clothing</div></li> <li><div>Electronics</div></li></ul>";
  var menu = base.content.children[0].cloneNode("true");
  return menu;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<div id="content"></div>
<hr />
<template id="template">
  <input>
</template>

输入C和D无法初始化。我已将其注释掉,但您可以自己进行测试。根据文档,它们应该按预期工作。如果您想进一步研究它,我敢打赌,那里有一个答案。如果您想完成工作,请不要在此部分使用template

尚不清楚为什么要尝试动态创建template,为什么不根据JavaScript的需要即时创建input元素。

,

如果您创建div元素而不是template元素,那么它将起作用。

$(document).ready(() => {
  const content = document.getElementById('content');
  const input = document.createElement('input');
  const inputFromTemplate = createFromTemplate(`<input></input>`);

  console.log(input);
  console.log(inputFromTemplate);

  $(input).autocomplete({
    source: ['one','three']
  });

  $(inputFromTemplate).autocomplete({
    source: ['one','three']
  });

  content.append(input);
  content.append(inputFromTemplate);
});

function createFromTemplate(template) {
  const htmlTemplate = document.createElement('div');
  htmlTemplate.innerHTML = template;

  return htmlTemplate.firstElementChild.cloneNode(true);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<div id="content"></div>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-