javascript - 使用复选框实时更新 UI

标签 javascript checkbox

我目前正在尝试为我的一位客户开发更智能的用户界面。但是,我可以用来开发此“功能”的唯一代码是纯 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.

有问题的页面

enter image description here

上面是我正在使用的页面的屏幕截图,在左侧您可以在“检查元素”工具中看到 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/

相关文章:

javascript - 设置变量以保存值始终为真

javascript - 如何在 Firefox 扩展中更改状态栏面板的背景颜色

html - Pardot 表格 : Two Column Layout for Radio/Checkboxes

android - 在自定义 ListView 中隐藏数字键盘后复选框的状态发生变化

javascript - 将鼠标悬停在 wordpress 菜单中单击

python - Tkinter IntVar 返回 PY_VAR0 而不是值

android - PreferencesActivity - 自定义复选框、单选按钮等的样式

javascript - 如何避免 Angular 指令 Controller 中的绑定(bind)(this)

Javascript 电话号码验证 : no regex evaluation

javascript - 使用 Javascript 按月将 JSON 解析为表格