我目前正在尝试为我的一位客户开发更智能的用户界面。但是,我可以用来开发此“功能”的唯一代码是纯 JS。我无法访问源 HTML 或 CSS 文件,我唯一的访问权限是能够通过外部 .js 文件注入(inject) JavaScript。 我不太熟悉 JS,但我可以使用一两个基本脚本。
场景
我们正在做的是允许用户使用名为 Core Create 的软件在线编辑 PDF 模板。通过浏览器访问的 UI 非常困惑,我想提供一个选项来隐藏和显示 UI 元素 <textareas>/<inputs>
通过使用复选框。
Here is a very basic JS Fiddle that I have built with the intention of hiding and displaying UI.
有问题的页面
上面是我正在使用的页面的屏幕截图,在左侧您可以在“检查元素”工具中看到 UI 及其在右侧的组成。
我得出的结论是,我需要遍历突出显示的选择并将它们与七个复选框相应地链接起来。结果将是选择的复选框,这些复选框将隐藏/显示正确的 UI 元素。
注意事项
在意识到我无法编辑或引入新的 HTML 时,我注意到缺少点击属性。所以我对如何调用我最终将构建的 JavaScript 有点迷茫。
My Question
With my limited knowledge of JS I don't know how I would iterate though div elements
editoraccvar - editoraccvar6
picking out the ones I need to manipulate.Due to the lack of ID's / Names (I assume it would have to be done using Parent/Child rules somehow, as the classes are widley used by the rest of the UI. I would appreciate a small example demonstrating how I could achieve this, so I can learn from it.
我应该澄清一下,我已经将复选框添加到页面,我只需要在复选框和我尝试定位的 UI 元素之间构建 JS 链接。您可以在 JS Fiddle 中找到链接到这些复选框的所有属性.
EDIT//一个有效的简化示例;
由于一些困惑,我将一些代码“科学怪人”放在一起以显示我所追求的最终结果。各种工作示例。实际结果需要针对7个Checkboxes和7个Division。我将在下面列出它们的常用属性。
// This script is already in place and constructed by the system.
// Written inside script tags and located straight after 'editopt1'.
// $(document).ready(function() {
// $('#checkboxopt1').click(function() {
// if ($('#checkboxopt1').val() == 'true') {
// $('#opt1').val('false');
// $('#checkboxopt1').val('false');
// $('#checkboxopt1').prop('checked', false);
// $('#previewrefresh').trigger('click');
// } else {
// $('#opt1').val('true');
// $('#checkboxopt1').val('true');
// $('#checkboxopt1').prop('checked', true);
// $('#previewrefresh').trigger('click');
// };
// });
// });
function exFunction() {
// Check the function is called
console.log("200 : OK");
// grab all elements with the class, .field-summernote
var uiblocks = document.querySelectorAll('.field-summernote');
for (var i = 0; i < uiblocks.length; i++) {
var current = uiblocks[i];
if (current.className.indexOf('editoraccvar') < 0) //not found: -1
return;
// check elements in the array
console.log(current);
// control the elemets in the array.
if (document.getElementById('checkboxopt1').checked) {
uiblocks[0].style.display = 'block'; // display the element
} else {
uiblocks[0].style.display = 'none'; // hide the element
}
}
};
// Trigger the collection the check, and the control.
var x = document.getElementById("checkboxopt1");
x.addEventListener("click", function() {
console.log("Opt");
exFunction();
});
.editoraccvar1 {
width: 300px;
background: #0ff;
padding: .5em;
}
.editoropt1 {
width: 300px;
background: #ff0;
padding: .5em;
}
textarea {
display: block;
width: 95%;
resize: none;
padding: .5em;
}
<!-- I'm trying to hide & show this entire division... -->
<div class="seq-box-form-field field-summernote editoraccvar1 ">
<label for="accvar1">Ground Floor Info</label>
<div class="clearfix"></div>
<textarea id="richaccvar1" name="richaccvar1" class="summernote"></textarea>
<input type="hidden" name="accvar1" id="accvar1" value="" />
</div>
<!-- Using only what the system has supplied. -->
<div class="seq-box-form-field editoropt1 ">
<label for="opt1"><span style="padding-right: 10px; vertical-align: 1px;">Ground Floor </span>
<input type="checkbox" name="checkboxopt1" id="checkboxopt1" value="true" checked="true" />
<input type="hidden" name="opt1" id="opt1" value="true" />
</label>
</div>
Divisions
<div class=""></div>
* editoraccvar, editoraccvar1, editoraccvar2, editoraccvar3, editoraccvar4, editoraccvar5, editoraccvar6*Checkboxes
<input id=""></input>
* checkboxopt, checkboxopt1, checkboxopt2, checkboxopt3, checkboxopt4, checkboxopt5, checkboxopt6,*
最佳答案
据我所知,您的问题归结为将复选框(似乎是以某种方式生成的)链接到您要隐藏的 html 的“划分”部分。另外,您必须在页面中注入(inject) javascript 代码(所以我想代码越少越好)。
一种方法如下:
// Wrap the code in an anonymus function, to avoid clustering the global space.
(function (domElements) {
// This is the callback that will fire when a checkbox is clicked.
function clickCallback() {
// the context of this callback is the DOM element thus we can access its attributes through this.
// extract the checkNumber of the class of the element. This number is the link to the division that we want to hide/show.
var checkNumber = ((/ editoropt(\d*) /).exec(this.className))[1],
checkBox = document.getElementById('checkboxopt' + checkNumber),
division = document.querySelectorAll('.editoraccvar' + checkNumber)[0];
// Hide/show division, update checkBox state.
toggleElements(division, checkBox, window.getComputedStyle(division).display === 'none');
}
function toggleElements(division, checkBox, isShown) {
// Toggle the division (show/hide) accordingly.
division.style.display = isShown ? 'block' : 'none';
// Due to the fact that the event listener is attached to the parent of the checkBox, we need to maintain consistency manually.
checkBox.checked = isShown;
}
// Remove from the array of DOMElements those that aren't checkboxes and add a click event listener to each of them.
domElements
.filter(function (el) {
return el.className.indexOf('editoropt') !== -1;
})
.forEach(function (el) {
el.addEventListener('click', clickCallback, false);
});
// Call the function passing the dom elements with class '.seq-box-form-field' as argument. Checkboxes are contained within them. Also, transform the nodelist
// into a proper array so that methods defined in Array.prototype can be used.
})([].slice.call(document.querySelectorAll('.seq-box-form-field')));
代码已被注释并且(我认为)非常不言自明。但是,如果您有任何疑问或希望我进一步阐述任何观点,请告诉我。
最后,这是工作 fiddle .
更新
相同的功能(或多或少),但现在它接受一个值数组,这些值将对应于复选框的初始状态:
(function (domElements, cbState) {
function clickCallback() {
toggleElements(this.className);
}
function toggleElements(className, initialShow) {
var checkNumber = ((/ editoropt(\d*) /).exec(className))[1],
checkBox = document.getElementById('checkboxopt' + checkNumber),
division = document.querySelectorAll('.editoraccvar' + checkNumber)[0],
isShown = initialShow === undefined ? window.getComputedStyle(division).display === 'none' : initialShow;
division.style.display = isShown ? 'block' : 'none';
checkBox.checked = isShown;
}
domElements
.filter(function (el) {
return el.className.indexOf('editoropt') !== -1;
})
.forEach(function (el, index) {
el.addEventListener('click', clickCallback, false);
toggleElements(el.className, cbState[index]);
});
// Initial state of the checkboxes goes in the second parameter. The index in the array correspond to the checkbox position in the page.
})([].slice.call(document.querySelectorAll('.seq-box-form-field')), [false, false]);
这是 Fiddle和玩。希望对您有所帮助。
关于javascript - 使用复选框实时更新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39792899/