nth-of-type
работает в соответствии с индексом того же типа элемента, но nth-child
работает только в соответствии с индексом независимо от того, какой тип элементов сиблингов.
Например
<div class="one">...</div>
<div class="two">...</div>
<div class="three">...</div>
<div class="four">...</div>
<div class="five">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
Предположим, что в выше html мы хотим скрыть все элементы, имеющие класс отдыха.
В этом случае nth-child
и nth-of-type
будут работать точно так же, как и все элементы одного типа, <div>
, поэтому css должен быть
.rest:nth-child(6), .rest:nth-child(7), .rest:nth-child(8), .rest:nth-child(9), .rest:nth-child(10){
display:none;
}
OR
.rest:nth-of-type(6), .rest:nth-of-type(7), .rest:nth-of-type(8), .rest:nth-of-type(9), .rest:nth-of-type(10){
display:none;
}
Теперь вам должно быть интересно узнать, в чем разница между nth-child
и nth-of-type
, так что это разница
Предположим, что html is
<div class="one">...</div>
<div class="two">...</div>
<div class="three">...</div>
<div class="four">...</div>
<div class="five">...</div>
<p class="rest">...</p>
<p class="rest">...</p>
<p class="rest">...</p>
<p class="rest">...</p>
<p class="rest">...</p>
В приведенном выше html тип элемента .rest
отличается от других .rest
- это абзацы, а другие - div, поэтому в этом случае if вы используете nth-child
, вы должны писать так
.rest:nth-child(6), .rest:nth-child(7), .rest:nth-child(8), .rest:nth-child(9), .rest:nth-child(10){
display:none;
}
, но если вы используете nss-тип css, это может быть
.rest:nth-of-type(1), .rest:nth-of-type(2), .rest:nth-of-type(3), .rest:nth-of-type(4), .rest:nth-of-type(5){
display:none;
}
Как тип Элементом
blockquote >.rest
является<p>
, поэтому здесьnth-of-type
обнаруживает тип.rest
, а затем он накладывает css на 1-й, 2-й, 3-й, 4-й, 5-й элементы<p>
.
На самом деле макрос ТРАССИРОВКИ намного более гибок, чем OutputDebugString. Это берет printf (), разрабатывают строку формата и список параметров, тогда как OutputDebugString просто берет единственную строку. Для реализации полной функциональности ТРАССИРОВКИ в режиме выпуска, необходимо сделать что-то вроде этого:
void trace(const char* format, ...)
{
char buffer[1000];
va_list argptr;
va_start(argptr, format);
wvsprintf(buffer, format, argptr);
va_end(argptr);
OutputDebugString(buffer);
}
ТРАССИРОВКА является просто макросом для OutputDebugString. Таким образом, можно легко просто сделать собственный макрос ТРАССИРОВКИ (или назвать его чем-то еще), который назовет OutputDebugString.
Несколько лет назад мне понадобилась похожая функциональность, поэтому я собрал следующий код. Просто сохраните его в файл, например, rtrace.h, включите его в конец вашего stdafx.h и добавьте _RTRACE в режим выпуска, который определяет препроцессор.
Возможно, кто-то найдет для него применение: -)
Джон
#pragma once //------------------------------------------------------------------------------------------------ // // Author: John Cullen // Date: 2006/04/12 // Based On: MSDN examples for variable argument lists and ATL implementation of TRACE. // // Description: Allows the use of TRACE statements in RELEASE builds, by overriding the // TRACE macro definition and redefining in terms of the RTRACE class and overloaded // operator (). Trace output is generated by calling OutputDebugString() directly. // // // Usage: Add to the end of stdafx.h and add _RTRACE to the preprocessor defines (typically // for RELEASE builds, although the flag will be ignored for DEBUG builds. // //------------------------------------------------------------------------------------------------ #ifdef _DEBUG // NL defined as a shortcut for writing FTRACE(_T("\n")); for example, instead write FTRACE(NL); #define NL _T("\n") #define LTRACE TRACE(_T("%s(%d): "), __FILE__, __LINE__); TRACE #define FTRACE TRACE(_T("%s(%d): %s: "), __FILE__, __LINE__, __FUNCTION__); TRACE #else // _DEBUG #ifdef _RTRACE #undef TRACE #define TRACE RTRACE() #define LTRACE RTRACE(__FILE__, __LINE__) #define FTRACE RTRACE(__FILE__, __LINE__, __FUNCTION__) #define NL _T("\n") class RTRACE { public: // default constructor, no params RTRACE(void) : m_pszFileName( NULL ), m_nLineNo( 0 ), m_pszFuncName( NULL ) {}; // overloaded constructor, filename and lineno RTRACE(PCTSTR const pszFileName, int nLineNo) : m_pszFileName(pszFileName), m_nLineNo(nLineNo), m_pszFuncName(NULL) {}; // overloaded constructor, filename, lineno, and function name RTRACE(PCTSTR const pszFileName, int nLineNo, PCTSTR const pszFuncName) : m_pszFileName(pszFileName), m_nLineNo(nLineNo), m_pszFuncName(pszFuncName) {}; virtual ~RTRACE(void) {}; // no arguments passed, e.g. RTRACE()() void operator()() const { // no arguments passed, just dump the file, line and function if requested OutputFileAndLine(); OutputFunction(); } // format string and parameters passed, e.g. RTRACE()(_T("%s\n"), someStringVar) void operator()(const PTCHAR pszFmt, ...) const { // dump the file, line and function if requested, followed by the TRACE arguments OutputFileAndLine(); OutputFunction(); // perform the standard TRACE output processing va_list ptr; va_start( ptr, pszFmt ); INT len = _vsctprintf( pszFmt, ptr ) + 1; TCHAR* buffer = (PTCHAR) malloc( len * sizeof(TCHAR) ); _vstprintf( buffer, pszFmt, ptr ); OutputDebugString(buffer); free( buffer ); } private: // output the current file and line inline void OutputFileAndLine() const { if (m_pszFileName && _tcslen(m_pszFileName) > 0) { INT len = _sctprintf( _T("%s(%d): "), m_pszFileName, m_nLineNo ) + 1; PTCHAR buffer = (PTCHAR) malloc( len * sizeof(TCHAR) ); _stprintf( buffer, _T("%s(%d): "), m_pszFileName, m_nLineNo ); OutputDebugString( buffer ); free( buffer ); } } // output the current function name inline void OutputFunction() const { if (m_pszFuncName && _tcslen(m_pszFuncName) > 0) { INT len = _sctprintf( _T("%s: "), m_pszFuncName ) + 1; PTCHAR buffer = (PTCHAR) malloc( len * sizeof(TCHAR) ); _stprintf( buffer, _T("%s: "), m_pszFuncName ); OutputDebugString( buffer ); free( buffer ); } } private: PCTSTR const m_pszFuncName; PCTSTR const m_pszFileName; const int m_nLineNo; }; #endif // _RTRACE #endif // NDEBUG
В MFC ТРАССИРОВКА определяется как ATLTRACE. И в режиме выпуска, который определяется как:
#define ATLTRACE __noop
Так, использование-поля ПРОСЛЕЖИВАЕТ от MFC, Вы на самом деле не сможете прочитать любой текст ТРАССИРОВКИ, потому что это не будет даже выписано. Вы могли записать свою собственную функцию ТРАССИРОВКИ вместо этого, затем переопределить макрос ТРАССИРОВКИ. Вы могли сделать что-то вроде этого:
void MyTrace(const CString& text)
{
::OutputDebugString(text); // Outputs to console, same as regular TRACE
// TODO: Do whatever output you need here. Write to event log / write to text file / write to pipe etc.
}