避免对每个元素重复 javascript
Avoid repeating javascript for each element
我在我的网站上使用 Google dialog-polyfill 作为模式。我需要在一个页面上有多个可以独立启动的模式。现在,我唯一可以开始工作的方法是重复所有 javascript,这似乎完全没有效率:
<dialog id="dialog" name="modal">
<p>This is the login modal dialog.</p>
<input type="text"></input>
<p><button id="close-dialog">Close dialog</button></p>
</dialog>
<p><button id="open-dialog">Open login dialog</button></p>
<dialog id="dialog2" name="modal">
<p>This is the registration modal dialog.</p>
<input type="text"></input>
<p><button id="close-dialog2">Close dialog</button></p>
</dialog>
<p><button id="open-dialog2">Open registration dialog</button></p>
<script>
var dialog = document.getElementById('dialog');
var dialog2 = document.getElementById('dialog2');
dialogPolyfill.registerDialog(dialog);
dialogPolyfill.registerDialog(dialog2);
document.getElementById('open-dialog').addEventListener('click', function () {
dialog.showModal(); });
document.getElementById('close-dialog').addEventListener('click', function () {
dialog.close(); });
document.getElementById('open-dialog2').addEventListener('click', function () {
dialog2.showModal(); });
document.getElementById('close-dialog2').addEventListener('click', function () {
dialog2.close(); });
dialog.addEventListener('click', function (event) {
var rect = dialog.getBoundingClientRect();
var isInDialog = (rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width);
if (!isInDialog) {
dialog.close();
}
});
dialog2.addEventListener('click', function (event) {
var rect = dialog2.getBoundingClientRect();
var isInDialog = (rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width);
if (!isInDialog) {
dialog2.close();
}
});
</script>
我试过这个并添加 name
属性无济于事:
var names = document.getElementsByName("modal");
for (var i = 0; i < names.length; i++) {
names[i].onchange = function () {
document.getElementById('open-dialog').addEventListener('click', function () {
dialog.showModal();
});
document.getElementById('close-dialog').addEventListener('click', function () {
dialog.close();
});
}
}
我不知道 类 会如何解决这个问题。有没有一种方法可以压缩代码,这样我就不需要为每个模态对话框重复它?
我编辑了你的fiddle:
http://jsfiddle.net/178f81qc/2/
你是这个意思吗?
HTML
<div class="dialog-container">
<dialog>This is dialog one <button class="close">close</button></dialog>
<button class="open">open dialog one</button>
</div>
<br>
<div class="dialog-container">
<dialog>This is dialog two <button class="close">close</button></dialog>
<button class="open">open dialog two</button>
</div>
Javascript
var dialogContainers = document.querySelectorAll('.dialog-container'), i;
for (i=0; i<dialogContainers.length; i++) {
var dialog = dialogContainers[i].querySelector('dialog'), // the <dialog> element
btnOpen = dialogContainers[i].querySelector('.open'), // the open button
btnClose = dialogContainers[i].querySelector('.close'); // the close button
// for old browsers
dialogPolyfill.registerDialog(dialogContainers[i]);
btnOpen.addEventListener('click', function () {
this.showModal();
}.bind(dialog));
// because you bind 'dialog' to the function, 'this' will be the dialog.
// (if you don't use bind, 'this' will be btnOpen instead)
btnClose.addEventListener('click', function () {
this.close();
}.bind(dialog));
}
我明白了。我在对话框中添加了一个 class ,这样我就可以得到所有的对话框;我可能只是通过标签名称进行选择,但这只会将我锁定在模态对话框中。然后我修改了我的脚本:
<script>
var els = document.getElementsByClassName("modal");
Array.prototype.forEach.call(els, function(el) {
var dialogid = el.id;
var dialog = document.getElementById(dialogid);
dialogPolyfill.registerDialog(dialog);
document.getElementById('open-'+dialogid).addEventListener('click', function () {
dialog.showModal();
});
document.getElementById('close-'+dialogid).addEventListener('click', function () {
dialog.close();
});
dialog.addEventListener('click', function (event) {
var rect = dialog.getBoundingClientRect();
var isInDialog = (rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width);
if (!isInDialog) {
dialog.close();
}
});
});
</script>
我真的不喜欢自己回答问题,但这很管用。如果有人能想出更有效的方法,我会很乐意给他信任。
我在我的网站上使用 Google dialog-polyfill 作为模式。我需要在一个页面上有多个可以独立启动的模式。现在,我唯一可以开始工作的方法是重复所有 javascript,这似乎完全没有效率:
<dialog id="dialog" name="modal">
<p>This is the login modal dialog.</p>
<input type="text"></input>
<p><button id="close-dialog">Close dialog</button></p>
</dialog>
<p><button id="open-dialog">Open login dialog</button></p>
<dialog id="dialog2" name="modal">
<p>This is the registration modal dialog.</p>
<input type="text"></input>
<p><button id="close-dialog2">Close dialog</button></p>
</dialog>
<p><button id="open-dialog2">Open registration dialog</button></p>
<script>
var dialog = document.getElementById('dialog');
var dialog2 = document.getElementById('dialog2');
dialogPolyfill.registerDialog(dialog);
dialogPolyfill.registerDialog(dialog2);
document.getElementById('open-dialog').addEventListener('click', function () {
dialog.showModal(); });
document.getElementById('close-dialog').addEventListener('click', function () {
dialog.close(); });
document.getElementById('open-dialog2').addEventListener('click', function () {
dialog2.showModal(); });
document.getElementById('close-dialog2').addEventListener('click', function () {
dialog2.close(); });
dialog.addEventListener('click', function (event) {
var rect = dialog.getBoundingClientRect();
var isInDialog = (rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width);
if (!isInDialog) {
dialog.close();
}
});
dialog2.addEventListener('click', function (event) {
var rect = dialog2.getBoundingClientRect();
var isInDialog = (rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width);
if (!isInDialog) {
dialog2.close();
}
});
</script>
我试过这个并添加 name
属性无济于事:
var names = document.getElementsByName("modal");
for (var i = 0; i < names.length; i++) {
names[i].onchange = function () {
document.getElementById('open-dialog').addEventListener('click', function () {
dialog.showModal();
});
document.getElementById('close-dialog').addEventListener('click', function () {
dialog.close();
});
}
}
我不知道 类 会如何解决这个问题。有没有一种方法可以压缩代码,这样我就不需要为每个模态对话框重复它?
我编辑了你的fiddle:
http://jsfiddle.net/178f81qc/2/
你是这个意思吗?
HTML
<div class="dialog-container">
<dialog>This is dialog one <button class="close">close</button></dialog>
<button class="open">open dialog one</button>
</div>
<br>
<div class="dialog-container">
<dialog>This is dialog two <button class="close">close</button></dialog>
<button class="open">open dialog two</button>
</div>
Javascript
var dialogContainers = document.querySelectorAll('.dialog-container'), i;
for (i=0; i<dialogContainers.length; i++) {
var dialog = dialogContainers[i].querySelector('dialog'), // the <dialog> element
btnOpen = dialogContainers[i].querySelector('.open'), // the open button
btnClose = dialogContainers[i].querySelector('.close'); // the close button
// for old browsers
dialogPolyfill.registerDialog(dialogContainers[i]);
btnOpen.addEventListener('click', function () {
this.showModal();
}.bind(dialog));
// because you bind 'dialog' to the function, 'this' will be the dialog.
// (if you don't use bind, 'this' will be btnOpen instead)
btnClose.addEventListener('click', function () {
this.close();
}.bind(dialog));
}
我明白了。我在对话框中添加了一个 class ,这样我就可以得到所有的对话框;我可能只是通过标签名称进行选择,但这只会将我锁定在模态对话框中。然后我修改了我的脚本:
<script>
var els = document.getElementsByClassName("modal");
Array.prototype.forEach.call(els, function(el) {
var dialogid = el.id;
var dialog = document.getElementById(dialogid);
dialogPolyfill.registerDialog(dialog);
document.getElementById('open-'+dialogid).addEventListener('click', function () {
dialog.showModal();
});
document.getElementById('close-'+dialogid).addEventListener('click', function () {
dialog.close();
});
dialog.addEventListener('click', function (event) {
var rect = dialog.getBoundingClientRect();
var isInDialog = (rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width);
if (!isInDialog) {
dialog.close();
}
});
});
</script>
我真的不喜欢自己回答问题,但这很管用。如果有人能想出更有效的方法,我会很乐意给他信任。