#javascript #variables #dom
#javascript #переменные #dom
Вопрос:
Приведенный ниже html-код экспортируется из orgmode, а функция Javascript предназначена для преобразования <pre class="src src-emacs-lisp">
блока в <pre><code class="lisp">
, чтобы он был синтаксически выделен с помощью highlightjs.
Из-за какой-то причуды Javascript, которую я не понимаю, функция не работает со вторым блоком. Я думал, что это синтаксис html-кода в нем, но когда я переставляю блоки, ошибка всегда возникает на втором. Должно быть что-то в правилах определения области видимости Javascript, чего я не понимаю. Код для определения местоположения блоков работает нормально, и если я распечатываю их без обработки, это работает, все они отображаются. Именно тогда, когда я применяю преобразования, все идет не так. Какую функцию Javascript я не понимаю?
Код, который просто выводит их, работает нормально. Все они обнаружены.
document.addEventListener('DOMContentLoaded', (event) => {
var lispBlocks = document.getElementsByClassName('src src-emacs-lisp');
alert(lispBlocks.length);
for (i=0;i<lispBlocks.length;i ){
var iHtml = lispBlocks[i].outerHTML;
//alert(lispBlocks[i].outerHTML);
alert(iHtml);
};
});
С кодом, который их преобразует, все идет наперекосяк
document.addEventListener('DOMContentLoaded', (event) => {
var lispBlocks = document.getElementsByClassName('src src-emacs-lisp');
alert(lispBlocks.length);
var iHtml;
var lBlockText;
for (i=0;i<lispBlocks.length;i ){
//lispBlocks[i].className = '';
iHtml = lispBlocks[i].innerHTML;
alert(lispBlocks[i].innerHTML);
alert(lispBlocks[i].outerHTML);
lBlockText = '<pre><code class="lisp">' iHtml '</code></pre>';
alert(lBlockText);
lispBlocks[i].outerHTML = lBlockText;
//alert(lispBlocks[i].outerHTML);
//hljs.highlightBlock(lispBlocks[i]);
};
});
<!-- language: lang-html -->
<div class="org-src-container">
<pre class="src src-emacs-lisp">;; after splitting a frame automatically, switch to the new window (unless we
;; were in the minibuffer)
(setq split-window-preferred-function 'my/split-window-func)
(defun my/split-window-func (amp;amp;optional window)
(let ((new-window (split-window-sensibly window)))
(if (not (active-minibuffer-window))
(select-window new-window))))
</pre>
</div>
<div class="org-src-container">
<pre class="src src-emacs-lisp"> (defun split-window--select-window (orig-func amp;amp;rest args)
"Switch to the other window after a `split-window'"
(let ((cur-window (selected-window))
(new-window (apply orig-func args)))
(when (equal (window-buffer cur-window) (window-buffer new-window))
(select-window new-window))
new-window))
(advice-add amp;#39;split-window :around #amp;#39;split-window--select-window)
</pre>
</div>
<div class="org-src-container">
<pre class="src src-emacs-lisp">;; settings for default frames
(add-to-list 'default-frame-alist '(font . FONT ))
;;or
;; set-face-atribute, ='default nil= for all existing frames and new frames
;; ='default t= for new frames only
;; function sets a number of attributes besides :font see docs
(set-face-attribute 'default nil :font FONT )
;;set frame font
(set-frame-font FONT nil t)
</pre>
</div>
Комментарии:
1.
function doesn't work
очевидно, иначе вас бы здесь не было — не могли бы вы описать, что происходит в сравнении с тем, что вы ожидаете, и любые ошибки в инструментах разработчика браузера, которые вы можете получать2. функция работает с первым и третьим блоками, но не со вторым. Обнаружение работает корректно для всех 3 блоков. Преобразование не работает со вторым.
3. Да, я понял это, как только снова посмотрел на код — пропуск каждого второго блока является классическим примером изменения элементов в «живом» списке — см. Ответ для двух возможных решений
4. Спасибо. Где я могу получить дополнительную помощь по живой категории выборок?
Ответ №1:
Проблема в том, что getElementsByClassName
возвращает текущий список
Следовательно, при изменении outerHTML вы изменяете список, потому что вы изменили класс элемента, который находится в текущем списке
В примере у вас будет список элементов, [a, b, c]
и i == 0
Вы изменяете a
таким образом, что он исчезает из списка, теперь список [b, c]
но i
увеличивается до 1, поэтому следующая итерация изменяется c
, пропуская b
использовать
var lispBlocks = document.querySelectorAll('.src.src-emacs-lisp');
вместо
В качестве альтернативы вы могли бы использовать цикл while
while(lispBlocks.length) {
iHtml = lispBlocks[0].innerHTML; // note, the hard coded `0` here
// etc
}