使用自定义 html 属性标签时出错
Posted
技术标签:
【中文标题】使用自定义 html 属性标签时出错【英文标题】:error while using custom html property tags 【发布时间】:2022-01-15 14:46:09 【问题描述】:我正在尝试使我的项目中的每个 html 元素都可点击。当它被点击时,它应该带我到另一个网页(other.html) 我的 JS:
let objs = document.querySelectorAll( 'body *' );
console.log(objs)
Array.from(objs).map(x =>
if (x.hasAttribute('loc') && x.hasAttribute('trig'))
let loc = x.getAttribute('loc')
let trig = x.getAttribute('trig')
let functionAtLast = function() location.href = loc
x.addEventListener(trig, functionAtLast)
)
我的 HTML:
<b loc = 'other.html' act = 'click'>hi</b>
当我点击粗体文本时,什么也没有发生。
我在这里做错了什么?
【问题讨论】:
“我试图让我的项目中的每个 HTML 元素都可以点击” - 为什么?这听起来是个坏主意,因为并非每个 HTML 元素都是可交互的(例如<script>
和 <noscript>
、<style>
等)
自定义属性应该写成data-
。见Using data attributes。什么都没有发生或您收到错误消息?如果是后者,错误是什么?
map
是一个返回新数组的 FP 风格的函数,它不等同于 forEach
。
属性是trig
还是act
?
您应该将选择器更改为body *[log][trig]
。
【参考方案1】:
map
不应用于变异 数组元素 - 也不打算 用于迭代数组。为此,您应该使用for( of )
(也不要使用.forEach
方法)。
data-*
属性来存储自定义数据,而不是定义您自己的标准外观属性。
我假设trig
是“触发器”的缩写,它是运行时定义的事件名称。
我已将其更改为 data-event-name
。
您可以通过HTMLElement.dataset['eventName']
获取值。
dataset
automatically converts -
in HTML attribute names to camelCase
,所以您不需要需要执行 `getAttribute("data-event-name")。
我假设loc
是“位置”的缩写,基本上是href
URI。我已将其更改为 data-href
。
像这样:
function setupClickableEverything()
const allBodyElementsWithAttribs = document.querySelectorAll( 'body *[data-event-name][data-href]' );
for( const el of allBodyElementsWithAttribs )
const eventName = el.dataset['eventName'];
el.addEventListener( eventName, setWindowLocationToDataSetHref );
window.addEventListener( 'DOMContentLoaded', setupClickableEverything );
function setWindowLocationToDataSetHref( e )
const el = e.currentTarget;
const href = el.dataset['href'];
window.location = href;
示例 HTML:
<b data-href="https://***.com/questions/51390971/im-lost-what-happened-to-asp-net-mvc-5/51391202#51391202" data-event-name="click">Navigate on click</b>
<br />
<b data-href="https://***.com/questions/15305278/how-to-check-if-a-string-contains-a-specific-text/15305313#15305313" data-event-name="mousedown">Navigate on mousedown</b>
<br />
<b data-href="https://***.com/questions/70011022/is-there-a-difference-between-and-is-not-in-c/70011062#70011062" data-event-name="contextmenu">Navigate on right-click</b>
这是一个使用 *** sn-p 稍作修改的演示。 由于 SO 对 Snippets 施加的 CSP,下面的演示无法导航、打开弹出窗口或将内容加载到 <iframe>
,但它仍然展示了它的工作原理原则:
function setupClickableEverything()
const allBodyElementsWithAttribs = document.querySelectorAll( 'body *[data-event-name][data-href]' );
for( const el of allBodyElementsWithAttribs )
const eventName = el.dataset['eventName'];
// const href = el.dataset['href'];
el.addEventListener( eventName, setWindowLocationToDataSetHref );
window.addEventListener( 'DOMContentLoaded', setupClickableEverything );
function setWindowLocationToDataSetHref( e )
const el = e.currentTarget;
const href = el.dataset['href'];
//window.location = href;
// To avoid breaking this demo, links are opened in the <iframe>.
// *** snippets cannot use `window.open`.
// document.getElementById('demoIFrame').src = href;
document.getElementById('demoOutput').textContent = href;
<b data-href="https://***.com/questions/51390971/im-lost-what-happened-to-asp-net-mvc-5/51391202#51391202" data-event-name="click">Navigate on click</b>
<br />
<b data-href="https://***.com/questions/15305278/how-to-check-if-a-string-contains-a-specific-text/15305313#15305313" data-event-name="mousedown">Navigate on mousedown</b>
<br />
<b data-href="https://***.com/questions/70011022/is-there-a-difference-between-and-is-not-in-c/70011062#70011062" data-event-name="contextmenu">Navigate on right-click</b>
<hr />
<!-- To avoid breaking this demo, links are NOT actually opened, just shown in the <output> element below. I tried to make it work using an <iframe> but the CSP on SO prevents that. Note that SO snippets are blocked from using `window.open` too. -->
<!--<iframe id="demoIFrame" border="1"></iframe>-->
<output id="demoOutput"></output>
【讨论】:
次要吹毛求疵:“事件名称”不是更常用的称为事件type吗? @SebastianSimon 您在技术上是正确的 (the best kind of correct) 但是在 MDN 的准权威文档中,他们交替使用术语“名称”和“类型”,并且考虑到 OP 对 JS 和 DOM 我来说似乎是新的想要使用更容易理解的术语。 我正在尝试这个,但它不起作用。没有错误,但是当我点击文本时,什么也没有发生。 @JSst67 你用过你的调试器吗?您是否确保脚本仅在DOMContentLoaded
DOMContentLoaded
之后运行?
@JSst67 我已经更新了我的答案以包含一个工作示例(尽管由于 SO sn-ps 的安全限制,实际上没有导航到任何地方)。以上是关于使用自定义 html 属性标签时出错的主要内容,如果未能解决你的问题,请参考以下文章